From 1b27ea69408e4e26aae6d7138ffd00c1fc949dd2 Mon Sep 17 00:00:00 2001 From: Eiren Rain Date: Tue, 22 Nov 2022 17:30:08 +0300 Subject: [PATCH 1/5] Delete old gui, cleanup after new gui merge, bump version to 0.3.1 --- gui/package.json | 2 +- package.json | 2 +- server/java/com/jme3/math/ColorRGBA.java | 665 ----- server/java/com/jme3/math/FastMath.java | 1072 -------- server/java/com/jme3/math/Matrix3f.java | 1362 ---------- server/java/com/jme3/math/Matrix4f.java | 2277 ----------------- server/java/com/jme3/math/Quaternion.java | 1721 ------------- server/java/com/jme3/math/Transform.java | 399 --- server/java/com/jme3/math/Vector2f.java | 718 ------ server/java/com/jme3/math/Vector3f.java | 1101 -------- server/java/com/jme3/math/Vector4f.java | 971 ------- server/java/com/jme3/system/NanoTimer.java | 105 - server/java/com/jme3/system/Timer.java | 93 - server/java/com/jme3/util/TempVars.java | 178 -- server/java/io/eiren/math/FloatMath.java | 672 ----- server/java/io/eiren/math/Vector3d.java | 257 -- server/java/io/eiren/util/BufferedTimer.java | 130 - server/java/io/eiren/util/MacOSX.java | 41 - .../java/io/eiren/util/OperatingSystem.java | 47 - server/java/io/eiren/util/StringUtils.java | 35 - server/java/io/eiren/util/Util.java | 176 -- server/java/io/eiren/util/ann/AWTThread.java | 10 - .../java/io/eiren/util/ann/DebugSwitch.java | 9 - .../java/io/eiren/util/ann/NativeUnsafe.java | 19 - .../java/io/eiren/util/ann/Synchronize.java | 30 - server/java/io/eiren/util/ann/ThreadSafe.java | 27 - .../io/eiren/util/ann/ThreadSafeSingle.java | 17 - .../java/io/eiren/util/ann/ThreadSecure.java | 22 - server/java/io/eiren/util/ann/Transient.java | 39 - .../io/eiren/util/collections/FastList.java | 547 ---- .../collections/RemoveAtSwapFastList.java | 41 - .../util/collections/RemoveAtSwapList.java | 11 - .../util/collections/ResettableIterator.java | 17 - .../eiren/util/collections/SkipIterator.java | 16 - .../io/eiren/util/logging/DefaultGLog.java | 137 - .../eiren/util/logging/FileLogFormatter.java | 58 - server/java/io/eiren/util/logging/IGLog.java | 48 - .../io/eiren/util/logging/LogManager.java | 136 - .../util/logging/LoggerOutputStream.java | 52 - .../io/eiren/util/logging/LoggerRecorder.java | 23 - .../logging/PreciseConsoleLogFormatter.java | 32 - .../logging/ShortConsoleLogFormatter.java | 58 - server/java/io/eiren/yaml/YamlException.java | 23 - server/java/io/eiren/yaml/YamlFile.java | 149 -- server/java/io/eiren/yaml/YamlNode.java | 642 ----- server/java/org/json/JSONArray.java | 880 ------- server/java/org/json/JSONException.java | 26 - server/java/org/json/JSONObject.java | 1590 ------------ server/java/org/json/JSONString.java | 19 - server/java/org/json/JSONTokener.java | 434 ---- server/java/org/json/JSONUtil.java | 57 - .../dev/slimevr/{gui => }/Keybinding.java | 150 +- server/src/main/java/dev/slimevr/Main.java | 14 +- .../gui/AbstractComponentListener.java | 24 - .../slimevr/gui/AbstractWindowListener.java | 36 - .../java/dev/slimevr/gui/AutoBoneWindow.java | 220 -- .../dev/slimevr/gui/CalibrationWindow.java | 89 - .../java/dev/slimevr/gui/ScalableFont.java | 89 - .../dev/slimevr/gui/SkeletonConfigGUI.java | 200 -- .../java/dev/slimevr/gui/SkeletonList.java | 108 - .../dev/slimevr/gui/TrackersFiltersGUI.java | 104 - .../java/dev/slimevr/gui/TrackersList.java | 568 ---- .../java/dev/slimevr/gui/VRServerGUI.java | 589 ----- .../main/java/dev/slimevr/gui/WiFiWindow.java | 194 -- .../dev/slimevr/gui/swing/ButtonTimer.java | 51 - .../java/dev/slimevr/gui/swing/EJBag.java | 11 - .../dev/slimevr/gui/swing/EJBagNoStretch.java | 32 - .../java/dev/slimevr/gui/swing/EJBox.java | 12 - .../dev/slimevr/gui/swing/EJBoxNoStretch.java | 40 - .../java/dev/slimevr/gui/swing/EJPanel.java | 105 - .../java/dev/slimevr/gui/swing/EJlabel.java | 8 - server/src/main/java/org/json/JSONArray.java | 878 ------- .../src/main/java/org/json/JSONException.java | 26 - server/src/main/java/org/json/JSONObject.java | 1586 ------------ server/src/main/java/org/json/JSONString.java | 19 - .../src/main/java/org/json/JSONTokener.java | 414 --- server/src/main/java/org/json/JSONUtil.java | 56 - 77 files changed, 79 insertions(+), 22737 deletions(-) delete mode 100644 server/java/com/jme3/math/ColorRGBA.java delete mode 100644 server/java/com/jme3/math/FastMath.java delete mode 100644 server/java/com/jme3/math/Matrix3f.java delete mode 100644 server/java/com/jme3/math/Matrix4f.java delete mode 100644 server/java/com/jme3/math/Quaternion.java delete mode 100644 server/java/com/jme3/math/Transform.java delete mode 100644 server/java/com/jme3/math/Vector2f.java delete mode 100644 server/java/com/jme3/math/Vector3f.java delete mode 100644 server/java/com/jme3/math/Vector4f.java delete mode 100644 server/java/com/jme3/system/NanoTimer.java delete mode 100644 server/java/com/jme3/system/Timer.java delete mode 100644 server/java/com/jme3/util/TempVars.java delete mode 100644 server/java/io/eiren/math/FloatMath.java delete mode 100644 server/java/io/eiren/math/Vector3d.java delete mode 100644 server/java/io/eiren/util/BufferedTimer.java delete mode 100644 server/java/io/eiren/util/MacOSX.java delete mode 100644 server/java/io/eiren/util/OperatingSystem.java delete mode 100644 server/java/io/eiren/util/StringUtils.java delete mode 100644 server/java/io/eiren/util/Util.java delete mode 100644 server/java/io/eiren/util/ann/AWTThread.java delete mode 100644 server/java/io/eiren/util/ann/DebugSwitch.java delete mode 100644 server/java/io/eiren/util/ann/NativeUnsafe.java delete mode 100644 server/java/io/eiren/util/ann/Synchronize.java delete mode 100644 server/java/io/eiren/util/ann/ThreadSafe.java delete mode 100644 server/java/io/eiren/util/ann/ThreadSafeSingle.java delete mode 100644 server/java/io/eiren/util/ann/ThreadSecure.java delete mode 100644 server/java/io/eiren/util/ann/Transient.java delete mode 100644 server/java/io/eiren/util/collections/FastList.java delete mode 100644 server/java/io/eiren/util/collections/RemoveAtSwapFastList.java delete mode 100644 server/java/io/eiren/util/collections/RemoveAtSwapList.java delete mode 100644 server/java/io/eiren/util/collections/ResettableIterator.java delete mode 100644 server/java/io/eiren/util/collections/SkipIterator.java delete mode 100644 server/java/io/eiren/util/logging/DefaultGLog.java delete mode 100644 server/java/io/eiren/util/logging/FileLogFormatter.java delete mode 100644 server/java/io/eiren/util/logging/IGLog.java delete mode 100644 server/java/io/eiren/util/logging/LogManager.java delete mode 100644 server/java/io/eiren/util/logging/LoggerOutputStream.java delete mode 100644 server/java/io/eiren/util/logging/LoggerRecorder.java delete mode 100644 server/java/io/eiren/util/logging/PreciseConsoleLogFormatter.java delete mode 100644 server/java/io/eiren/util/logging/ShortConsoleLogFormatter.java delete mode 100644 server/java/io/eiren/yaml/YamlException.java delete mode 100644 server/java/io/eiren/yaml/YamlFile.java delete mode 100644 server/java/io/eiren/yaml/YamlNode.java delete mode 100644 server/java/org/json/JSONArray.java delete mode 100644 server/java/org/json/JSONException.java delete mode 100644 server/java/org/json/JSONObject.java delete mode 100644 server/java/org/json/JSONString.java delete mode 100644 server/java/org/json/JSONTokener.java delete mode 100644 server/java/org/json/JSONUtil.java rename server/src/main/java/dev/slimevr/{gui => }/Keybinding.java (97%) delete mode 100644 server/src/main/java/dev/slimevr/gui/AbstractComponentListener.java delete mode 100644 server/src/main/java/dev/slimevr/gui/AbstractWindowListener.java delete mode 100644 server/src/main/java/dev/slimevr/gui/AutoBoneWindow.java delete mode 100644 server/src/main/java/dev/slimevr/gui/CalibrationWindow.java delete mode 100644 server/src/main/java/dev/slimevr/gui/ScalableFont.java delete mode 100644 server/src/main/java/dev/slimevr/gui/SkeletonConfigGUI.java delete mode 100644 server/src/main/java/dev/slimevr/gui/SkeletonList.java delete mode 100644 server/src/main/java/dev/slimevr/gui/TrackersFiltersGUI.java delete mode 100644 server/src/main/java/dev/slimevr/gui/TrackersList.java delete mode 100644 server/src/main/java/dev/slimevr/gui/VRServerGUI.java delete mode 100644 server/src/main/java/dev/slimevr/gui/WiFiWindow.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/ButtonTimer.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/EJBag.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/EJBagNoStretch.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/EJBox.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/EJBoxNoStretch.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/EJPanel.java delete mode 100644 server/src/main/java/dev/slimevr/gui/swing/EJlabel.java delete mode 100644 server/src/main/java/org/json/JSONArray.java delete mode 100644 server/src/main/java/org/json/JSONException.java delete mode 100644 server/src/main/java/org/json/JSONObject.java delete mode 100644 server/src/main/java/org/json/JSONString.java delete mode 100644 server/src/main/java/org/json/JSONTokener.java delete mode 100644 server/src/main/java/org/json/JSONUtil.java diff --git a/gui/package.json b/gui/package.json index 0c2e7849d9..1c82b64daf 100644 --- a/gui/package.json +++ b/gui/package.json @@ -1,6 +1,6 @@ { "name": "slimevr-ui", - "version": "0.2.0", + "version": "0.3.1", "private": true, "dependencies": { "@babel/core": "^7.16.0", diff --git a/package.json b/package.json index 7994425600..ef9d48209a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "slimevr-ui", - "version": "0.2.0", + "version": "0.3.1", "private": true, "workspaces": [ "solarxr-protocol", diff --git a/server/java/com/jme3/math/ColorRGBA.java b/server/java/com/jme3/math/ColorRGBA.java deleted file mode 100644 index a6b8a62f2e..0000000000 --- a/server/java/com/jme3/math/ColorRGBA.java +++ /dev/null @@ -1,665 +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 com.jme3.math; - -import io.eiren.math.FloatMath; - - -/** - * ColorRGBA defines a color made from a collection of red, green - * and blue values. An alpha value determines is transparency. All values must - * be between 0 and 1. If any value is set higher or lower than these - * constraints they are clamped to the min or max. That is, if a value smaller - * than zero is set the value clamps to zero. If a value higher than 1 is - * passed, that value is clamped to 1. However, because the attributes r, g, b, - * a are public for efficiency reasons, they can be directly modified with - * invalid values. The client should take care when directly addressing the - * values. A call to clamp will assure that the values are within the - * constraints. - * - * @author Mark Powell - * @version $Id: ColorRGBA.java,v 1.29 2007/09/09 18:25:14 irrisor Exp $ - */ -public final class ColorRGBA implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - /** - * The color black (0,0,0). - */ - public static final ColorRGBA Black = new ColorRGBA(0f, 0f, 0f, 1f); - /** - * The color white (1,1,1). - */ - public static final ColorRGBA White = new ColorRGBA(1f, 1f, 1f, 1f); - /** - * The color gray (.2,.2,.2). - */ - public static final ColorRGBA DarkGray = new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f); - /** - * The color gray (.5,.5,.5). - */ - public static final ColorRGBA Gray = new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f); - /** - * The color gray (.8,.8,.8). - */ - public static final ColorRGBA LightGray = new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f); - /** - * The color red (1,0,0). - */ - public static final ColorRGBA Red = new ColorRGBA(1f, 0f, 0f, 1f); - /** - * The color green (0,1,0). - */ - public static final ColorRGBA Green = new ColorRGBA(0f, 1f, 0f, 1f); - /** - * The color blue (0,0,1). - */ - public static final ColorRGBA Blue = new ColorRGBA(0f, 0f, 1f, 1f); - /** - * The color yellow (1,1,0). - */ - public static final ColorRGBA Yellow = new ColorRGBA(1f, 1f, 0f, 1f); - /** - * The color magenta (1,0,1). - */ - public static final ColorRGBA Magenta = new ColorRGBA(1f, 0f, 1f, 1f); - /** - * The color cyan (0,1,1). - */ - public static final ColorRGBA Cyan = new ColorRGBA(0f, 1f, 1f, 1f); - /** - * The color orange (251/255, 130/255,0). - */ - public static final ColorRGBA Orange = new ColorRGBA(251f / 255f, 130f / 255f, 0f, 1f); - /** - * The color brown (65/255, 40/255, 25/255). - */ - public static final ColorRGBA Brown = new ColorRGBA(65f / 255f, 40f / 255f, 25f / 255f, 1f); - /** - * The color pink (1, 0.68, 0.68). - */ - public static final ColorRGBA Pink = new ColorRGBA(1f, 0.68f, 0.68f, 1f); - /** - * The black color with no alpha (0, 0, 0, 0). - */ - public static final ColorRGBA BlackNoAlpha = new ColorRGBA(0f, 0f, 0f, 0f); - /** - * The red component of the color. 0 is none and 1 is maximum red. - */ - public float r; - /** - * The green component of the color. 0 is none and 1 is maximum green. - */ - public float g; - /** - * The blue component of the color. 0 is none and 1 is maximum blue. - */ - public float b; - /** - * The alpha component of the color. 0 is transparent and 1 is opaque. - */ - public float a; - - /** - * Constructor instantiates a new ColorRGBA object. This color - * is the default "white" with all values 1. - */ - public ColorRGBA() { - r = g = b = a = 1.0f; - } - - /** - * Constructor instantiates a new ColorRGBA object. The values - * are defined as passed parameters. These values are then clamped to insure - * that they are between 0 and 1. - * - * @param r The red component of this color. - * @param g The green component of this ColorRGBA. - * @param b The blue component of this ColorRGBA. - * @param a The alpha component of this ColorRGBA. - */ - public ColorRGBA(float r, float g, float b, float a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - - /** - * Copy constructor creates a new ColorRGBA object, based on a - * provided color. - * - * @param rgba The ColorRGBA object to copy. - */ - public ColorRGBA(ColorRGBA rgba) { - this.a = rgba.a; - this.r = rgba.r; - this.g = rgba.g; - this.b = rgba.b; - } - - /** - * set sets the RGBA values of this ColorRGBA. The - * values are then clamped to insure that they are between 0 and 1. - * - * @param r The red component of this color. - * @param g The green component of this color. - * @param b The blue component of this color. - * @param a The alpha component of this color. - * @return this - */ - public ColorRGBA set(float r, float g, float b, float a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - return this; - } - - /** - * set sets the values of this ColorRGBA to those - * set by a parameter color. - * - * @param rgba The color to set this ColorRGBA to. - * @return this - */ - public ColorRGBA set(ColorRGBA rgba) { - if (rgba == null) { - r = 0; - g = 0; - b = 0; - a = 0; - } else { - r = rgba.r; - g = rgba.g; - b = rgba.b; - a = rgba.a; - } - return this; - } - - public ColorRGBA setR(float r) { - this.r = r; - return this; - } - - public ColorRGBA setG(float g) { - this.g = g; - return this; - } - - public ColorRGBA setB(float b) { - this.b = b; - return this; - } - - public ColorRGBA setA(float a) { - this.a = a; - return this; - } - - /** - * clamp insures that all values are between 0 and 1. If any - * are less than 0 they are set to zero. If any are more than 1 they are set - * to one. - */ - public void clamp() { - if (r < 0) { - r = 0; - } else if (r > 1) { - r = 1; - } - - if (g < 0) { - g = 0; - } else if (g > 1) { - g = 1; - } - - if (b < 0) { - b = 0; - } else if (b > 1) { - b = 1; - } - - if (a < 0) { - a = 0; - } else if (a > 1) { - a = 1; - } - } - - /** - * getColorArray retrieves the color values of this - * ColorRGBA as a four element float array in the - * order: r,g,b,a. - * - * @return The float array that contains the color components. - */ - public float[] getColorArray() { - return new float[] { r, g, b, a }; - } - - /** - * Stores the current r,g,b,a values into the given array. The given array - * must have a length of 4 or greater, or an array index out of bounds - * exception will be thrown. - * - * @param store The float array to store the values into. - * @return The float array after storage. - */ - public float[] getColorArray(float[] store) { - store[0] = r; - store[1] = g; - store[2] = b; - store[3] = a; - return store; - } - - /** - * Retrieves the alpha component value of this ColorRGBA. - * - * @return The alpha component value. - */ - public float getAlpha() { - return a; - } - - /** - * Retrieves the red component value of this ColorRGBA. - * - * @return The red component value. - */ - public float getRed() { - return r; - } - - /** - * Retrieves the blue component value of this ColorRGBA. - * - * @return The blue component value. - */ - public float getBlue() { - return b; - } - - /** - * Retrieves the green component value of this ColorRGBA. - * - * @return The green component value. - */ - public float getGreen() { - return g; - } - - /** - * Sets this ColorRGBA to the interpolation by changeAmnt from - * this to the finalColor: this=(1-changeAmnt)*this + changeAmnt * - * finalColor - * - * @param finalColor The final color to interpolate towards. - * @param changeAmnt An amount between 0.0 - 1.0 representing a percentage - * change from this towards finalColor. - */ - public void interpolate(ColorRGBA finalColor, float changeAmnt) { - this.r = (1 - changeAmnt) * this.r + changeAmnt * finalColor.r; - this.g = (1 - changeAmnt) * this.g + changeAmnt * finalColor.g; - this.b = (1 - changeAmnt) * this.b + changeAmnt * finalColor.b; - this.a = (1 - changeAmnt) * this.a + changeAmnt * finalColor.a; - } - - /** - * Sets this ColorRGBA to the interpolation by changeAmnt from - * beginColor to finalColor: this=(1-changeAmnt)*beginColor + changeAmnt * - * finalColor - * - * @param beginColor The begining color (changeAmnt=0). - * @param finalColor The final color to interpolate towards (changeAmnt=1). - * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage - * change from beginColor towards finalColor. - */ - public void interpolate(ColorRGBA beginColor, ColorRGBA finalColor, float changeAmnt) { - this.r = (1 - changeAmnt) * beginColor.r + changeAmnt * finalColor.r; - this.g = (1 - changeAmnt) * beginColor.g + changeAmnt * finalColor.g; - this.b = (1 - changeAmnt) * beginColor.b + changeAmnt * finalColor.b; - this.a = (1 - changeAmnt) * beginColor.a + changeAmnt * finalColor.a; - } - - /** - * randomColor is a utility method that generates a random - * opaque color. - * - * @return a random ColorRGBA with an alpha set to 1. - */ - public static ColorRGBA randomColor() { - ColorRGBA rVal = new ColorRGBA(0, 0, 0, 1); - rVal.r = FastMath.nextRandomFloat(); - rVal.g = FastMath.nextRandomFloat(); - rVal.b = FastMath.nextRandomFloat(); - return rVal; - } - - /** - * Multiplies each r,g,b,a of this ColorRGBA by the - * corresponding r,g,b,a of the given color and returns the result as a new - * ColorRGBA. Used as a way of combining colors and lights. - * - * @param c The color to multiply by. - * @return The new ColorRGBA. this*c - */ - public ColorRGBA mult(ColorRGBA c) { - return new ColorRGBA(c.r * r, c.g * g, c.b * b, c.a * a); - } - - /** - * Multiplies each r,g,b,a of this ColorRGBA by the given - * scalar and returns the result as a new ColorRGBA. Used as a - * way of making colors dimmer or brighter. - * - * @param scalar The scalar to multiply by. - * @return The new ColorRGBA. this*scalar - */ - public ColorRGBA mult(float scalar) { - return new ColorRGBA(scalar * r, scalar * g, scalar * b, scalar * a); - } - - /** - * Multiplies each r,g,b,a of this ColorRGBA by the given - * scalar and returns the result (this). Used as a way of making colors - * dimmer or brighter. - * - * @param scalar The scalar to multiply by. - * @return this*c - */ - public ColorRGBA multLocal(float scalar) { - this.r *= scalar; - this.g *= scalar; - this.b *= scalar; - this.a *= scalar; - return this; - } - - /** - * Adds each r,g,b,a of this ColorRGBA by the corresponding - * r,g,b,a of the given color and returns the result as a new - * ColorRGBA. Used as a way of combining colors and lights. - * - * @param c The color to add. - * @return The new ColorRGBA. this+c - */ - public ColorRGBA add(ColorRGBA c) { - return new ColorRGBA(c.r + r, c.g + g, c.b + b, c.a + a); - } - - /** - * Adds each r,g,b,a of this ColorRGBA by the r,g,b,a the given - * color and returns the result (this). Used as a way of combining colors - * and lights. - * - * @param c The color to add. - * @return this+c - */ - public ColorRGBA addLocal(ColorRGBA c) { - set(c.r + r, c.g + g, c.b + b, c.a + a); - return this; - } - - /** - * Multiplies alpha component by the given scalar and returns the result as - * a new color. - */ - public ColorRGBA dilute(float scalarA) { - return new ColorRGBA(r, g, b, a * scalarA); - } - - /** - * Multiplies alpha component by the given scalar and returns the result - * (this). - */ - public ColorRGBA diluteLocal(float scalarA) { - this.a *= scalarA; - return this; - } - - /** - * toString returns the string representation of this - * ColorRGBA. The format of the string is:
- * : [R=RR.RRRR, G=GG.GGGG, B=BB.BBBB, A=AA.AAAA] - * - * @return The string representation of this ColorRGBA. - */ - @Override - public String toString() { - return "Color[" + r + ", " + g + ", " + b + ", " + a + "]"; - } - - @Override - public ColorRGBA clone() { - try { - return (ColorRGBA) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } - - /** - * Saves this ColorRGBA into the given float - * array. - * - * @param floats The float array to take this - * ColorRGBA. If null, a new float[4] is created. - * @return The array, with r,g,b,a float values in that order. - */ - public float[] toArray(float[] floats) { - if (floats == null) { - floats = new float[4]; - } - floats[0] = r; - floats[1] = g; - floats[2] = b; - floats[3] = a; - return floats; - } - - public ColorRGBA fromArray(float[] floats) { - r = floats[0]; - g = floats[1]; - b = floats[2]; - a = floats[3]; - return this; - } - - /** - * equals returns true if this ColorRGBA is - * logically equivalent to a given color. That is, if all the components of - * the two colors are the same. False is returned otherwise. - * - * @param o The object to compare against. - * @return true if the colors are equal, false otherwise. - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof ColorRGBA)) { - return false; - } - - if (this == o) { - return true; - } - - ColorRGBA comp = (ColorRGBA) o; - if (!FloatMath.equalsWithEpsilon(r, comp.r, FastMath.ZERO_TOLERANCE)) { - return false; - } - if (!FloatMath.equalsWithEpsilon(g, comp.g, FastMath.ZERO_TOLERANCE)) { - return false; - } - if (!FloatMath.equalsWithEpsilon(b, comp.b, FastMath.ZERO_TOLERANCE)) { - return false; - } - if (!FloatMath.equalsWithEpsilon(a, comp.a, FastMath.ZERO_TOLERANCE)) { - return false; - } - return true; - } - - /** - * hashCode returns a unique code for this - * ColorRGBA based on its values. If two colors are logically - * equivalent, they will return the same hash code value. - * - * @return The hash code value of this ColorRGBA. - */ - @Override - public int hashCode() { - int hash = 37; - hash += 37 * hash + Float.floatToIntBits(r); - hash += 37 * hash + Float.floatToIntBits(g); - hash += 37 * hash + Float.floatToIntBits(b); - hash += 37 * hash + Float.floatToIntBits(a); - return hash; - } - - /** - * Retrieves the component values of this ColorRGBA as a four - * element byte array in the order: r,g,b,a. - * - * @return the byte array that contains the color components. - */ - public byte[] asBytesRGBA() { - byte[] store = new byte[4]; - store[0] = (byte) ((int) (r * 255) & 0xFF); - store[1] = (byte) ((int) (g * 255) & 0xFF); - store[2] = (byte) ((int) (b * 255) & 0xFF); - store[3] = (byte) ((int) (a * 255) & 0xFF); - return store; - } - - /** - * Retrieves the component values of this ColorRGBA as an - * int in a,r,g,b order. Bits 24-31 are alpha, 16-23 are red, - * 8-15 are green, 0-7 are blue. - * - * @return The integer representation of this ColorRGBA in - * a,r,g,b order. - */ - public int asIntARGB() { - int argb = (((int) (a * 255) & 0xFF) << 24) - | (((int) (r * 255) & 0xFF) << 16) - | (((int) (g * 255) & 0xFF) << 8) - | (((int) (b * 255) & 0xFF)); - return argb; - } - - /** - * Retrieves the component values of this ColorRGBA as an - * int in r,g,b,a order. Bits 24-31 are red, 16-23 are green, - * 8-15 are blue, 0-7 are alpha. - * - * @return The integer representation of this ColorRGBA in - * r,g,b,a order. - */ - public int asIntRGBA() { - int rgba = (((int) (r * 255) & 0xFF) << 24) - | (((int) (g * 255) & 0xFF) << 16) - | (((int) (b * 255) & 0xFF) << 8) - | (((int) (a * 255) & 0xFF)); - return rgba; - } - - /** - * Retrieves the component values of this ColorRGBA as an - * int in a,b,g,r order. Bits 24-31 are alpha, 16-23 are blue, - * 8-15 are green, 0-7 are red. - * - * @return The integer representation of this ColorRGBA in - * a,b,g,r order. - */ - public int asIntABGR() { - int abgr = (((int) (a * 255) & 0xFF) << 24) - | (((int) (b * 255) & 0xFF) << 16) - | (((int) (g * 255) & 0xFF) << 8) - | (((int) (r * 255) & 0xFF)); - return abgr; - } - - /** - * Sets the component values of this ColorRGBA with the given - * combined ARGB int. Bits 24-31 are alpha, bits 16-23 are red, - * bits 8-15 are green, bits 0-7 are blue. - * - * @param color The integer ARGB value used to set this - * ColorRGBA. - */ - public void fromIntARGB(int color) { - a = ((byte) (color >> 24) & 0xFF) / 255f; - r = ((byte) (color >> 16) & 0xFF) / 255f; - g = ((byte) (color >> 8) & 0xFF) / 255f; - b = ((byte) (color) & 0xFF) / 255f; - } - - /** - * Sets the RGBA values of this ColorRGBA with the given - * combined RGBA value Bits 24-31 are red, bits 16-23 are green, bits 8-15 - * are blue, bits 0-7 are alpha. - * - * @param color The integer RGBA value used to set this object. - */ - public void fromIntRGBA(int color) { - r = ((byte) (color >> 24) & 0xFF) / 255f; - g = ((byte) (color >> 16) & 0xFF) / 255f; - b = ((byte) (color >> 8) & 0xFF) / 255f; - a = ((byte) (color) & 0xFF) / 255f; - } - - /** - * Transform this ColorRGBA to a Vector3f using x - * = r, y = g, z = b. The Alpha value is not used. This method is useful to - * use for shaders assignment. - * - * @return A Vector3f containing the RGB value of this - * ColorRGBA. - */ - public Vector3f toVector3f() { - return new Vector3f(r, g, b); - } - - /** - * Transform this ColorRGBA to a Vector4f using x - * = r, y = g, z = b, w = a. This method is useful to use for shaders - * assignment. - * - * @return A Vector4f containing the RGBA value of this - * ColorRGBA. - */ - public Vector4f toVector4f() { - return new Vector4f(r, g, b, a); - } -} diff --git a/server/java/com/jme3/math/FastMath.java b/server/java/com/jme3/math/FastMath.java deleted file mode 100644 index ed0917d146..0000000000 --- a/server/java/com/jme3/math/FastMath.java +++ /dev/null @@ -1,1072 +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 com.jme3.math; - -import java.util.Random; - - -/** - * FastMath provides 'fast' math approximations and float - * equivalents of Math functions. These are all used as static values and - * functions. - * - * @author Various - * @version $Id: FastMath.java,v 1.45 2007/08/26 08:44:20 irrisor Exp $ - */ -final public class FastMath { - - private FastMath() { - } - - /** A "close to zero" double epsilon value for use */ - public static final double DBL_EPSILON = 2.220446049250313E-16d; - /** A "close to zero" float epsilon value for use */ - public static final float FLT_EPSILON = 1.1920928955078125E-7f; - /** A "close to zero" float epsilon value for use */ - public static final float ZERO_TOLERANCE = 0.0001f; - public static final float ONE_THIRD = 1f / 3f; - /** The value PI as a float. (180 degrees) */ - public static final float PI = (float) Math.PI; - /** The value 2PI as a float. (360 degrees) */ - public static final float TWO_PI = 2.0f * PI; - /** The value PI/2 as a float. (90 degrees) */ - public static final float HALF_PI = 0.5f * PI; - /** The value PI/4 as a float. (45 degrees) */ - public static final float QUARTER_PI = 0.25f * PI; - /** The value 1/PI as a float. */ - public static final float INV_PI = 1.0f / PI; - /** The value 1/(2PI) as a float. */ - public static final float INV_TWO_PI = 1.0f / TWO_PI; - /** A value to multiply a degree value by, to convert it to radians. */ - public static final float DEG_TO_RAD = PI / 180.0f; - /** A value to multiply a radian value by, to convert it to degrees. */ - public static final float RAD_TO_DEG = 180.0f / PI; - /** A precreated random object for random numbers. */ - public static final Random rand = new Random(System.currentTimeMillis()); - - /** - * Returns true if the number is a power of 2 (2,4,8,16...) - * - * A good implementation found on the Java boards. note: a number is a power - * of two if and only if it is the smallest number with that number of - * significant bits. Therefore, if you subtract 1, you know that the new - * number will have fewer bits, so ANDing the original number with anything - * less than it will give 0. - * - * @param number The number to test. - * @return True if it is a power of two. - */ - public static boolean isPowerOfTwo(int number) { - return (number > 0) && (number & (number - 1)) == 0; - } - - public static int nearestPowerOfTwo(int number) { - return (int) Math.pow(2, Math.ceil(Math.log(number) / Math.log(2))); - } - - /** - * Linear interpolation from startValue to endValue by the given percent. - * Basically: ((1 - percent) * startValue) + (percent * endValue) - * - * @param scale scale value to use. if 1, use endValue, if 0, use - * startValue. - * @param startValue Begining value. 0% of f - * @param endValue ending value. 100% of f - * @return The interpolated value between startValue and endValue. - */ - public static float interpolateLinear(float scale, float startValue, float endValue) { - if (startValue == endValue) { - return startValue; - } - if (scale <= 0f) { - return startValue; - } - if (scale >= 1f) { - return endValue; - } - return ((1f - scale) * startValue) + (scale * endValue); - } - - /** - * Linear interpolation from startValue to endValue by the given percent. - * Basically: ((1 - percent) * startValue) + (percent * endValue) - * - * @param scale scale value to use. if 1, use endValue, if 0, use - * startValue. - * @param startValue Begining value. 0% of f - * @param endValue ending value. 100% of f - * @param store a vector3f to store the result - * @return The interpolated value between startValue and endValue. - */ - public static Vector3f interpolateLinear( - float scale, - Vector3f startValue, - Vector3f endValue, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - store.x = interpolateLinear(scale, startValue.x, endValue.x); - store.y = interpolateLinear(scale, startValue.y, endValue.y); - store.z = interpolateLinear(scale, startValue.z, endValue.z); - return store; - } - - /** - * Linear interpolation from startValue to endValue by the given percent. - * Basically: ((1 - percent) * startValue) + (percent * endValue) - * - * @param scale scale value to use. if 1, use endValue, if 0, use - * startValue. - * @param startValue Begining value. 0% of f - * @param endValue ending value. 100% of f - * @return The interpolated value between startValue and endValue. - */ - public static Vector3f interpolateLinear(float scale, Vector3f startValue, Vector3f endValue) { - return interpolateLinear(scale, startValue, endValue, null); - } - - /** - * Linear extrapolation from startValue to endValue by the given scale. if - * scale is between 0 and 1 this method returns the same result as - * interpolateLinear if the scale is over 1 the value is linearly - * extrapolated. Note that the end value is the value for a scale of 1. - * - * @param scale the scale for extrapolation - * @param startValue the starting value (scale = 0) - * @param endValue the end value (scale = 1) - * @return an extrapolation for the given parameters - */ - public static float extrapolateLinear(float scale, float startValue, float endValue) { -// if (scale <= 0f) { -// return startValue; -// } - return ((1f - scale) * startValue) + (scale * endValue); - } - - /** - * Linear extrapolation from startValue to endValue by the given scale. if - * scale is between 0 and 1 this method returns the same result as - * interpolateLinear if the scale is over 1 the value is linearly - * extrapolated. Note that the end value is the value for a scale of 1. - * - * @param scale the scale for extrapolation - * @param startValue the starting value (scale = 0) - * @param endValue the end value (scale = 1) - * @param store an initialized vector to store the return value - * @return an extrapolation for the given parameters - */ - public static Vector3f extrapolateLinear( - float scale, - Vector3f startValue, - Vector3f endValue, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } -// if (scale <= 1f) { -// return interpolateLinear(scale, startValue, endValue, store); -// } - store.x = extrapolateLinear(scale, startValue.x, endValue.x); - store.y = extrapolateLinear(scale, startValue.y, endValue.y); - store.z = extrapolateLinear(scale, startValue.z, endValue.z); - return store; - } - - /** - * Linear extrapolation from startValue to endValue by the given scale. if - * scale is between 0 and 1 this method returns the same result as - * interpolateLinear if the scale is over 1 the value is linearly - * extrapolated. Note that the end value is the value for a scale of 1. - * - * @param scale the scale for extrapolation - * @param startValue the starting value (scale = 0) - * @param endValue the end value (scale = 1) - * @return an extrapolation for the given parameters - */ - public static Vector3f extrapolateLinear(float scale, Vector3f startValue, Vector3f endValue) { - return extrapolateLinear(scale, startValue, endValue, null); - } - - /** - * Interpolate a spline between at least 4 control points following the - * Catmull-Rom equation. here is the interpolation matrix m = [ 0.0 1.0 0.0 - * 0.0 ] [-T 0.0 T 0.0 ] [ 2T T-3 3-2T -T ] [-T 2-T T-2 T ] where T is the - * curve tension the result is a value between p1 and p2, t=0 for p1, t=1 - * for p2 - * - * @param u value from 0 to 1 - * @param T The tension of the curve - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @return catmull-Rom interpolation - */ - public static float interpolateCatmullRom( - float u, - float T, - float p0, - float p1, - float p2, - float p3 - ) { - float c1, c2, c3, c4; - c1 = p1; - c2 = -1.0f * T * p0 + T * p2; - c3 = 2 * T * p0 + (T - 3) * p1 + (3 - 2 * T) * p2 + -T * p3; - c4 = -T * p0 + (2 - T) * p1 + (T - 2) * p2 + T * p3; - - return (float) (((c4 * u + c3) * u + c2) * u + c1); - } - - /** - * Interpolate a spline between at least 4 control points following the - * Catmull-Rom equation. here is the interpolation matrix m = [ 0.0 1.0 0.0 - * 0.0 ] [-T 0.0 T 0.0 ] [ 2T T-3 3-2T -T ] [-T 2-T T-2 T ] where T is the - * tension of the curve the result is a value between p1 and p2, t=0 for p1, - * t=1 for p2 - * - * @param u value from 0 to 1 - * @param T The tension of the curve - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @param store a Vector3f to store the result - * @return catmull-Rom interpolation - */ - public static Vector3f interpolateCatmullRom( - float u, - float T, - Vector3f p0, - Vector3f p1, - Vector3f p2, - Vector3f p3, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - store.x = interpolateCatmullRom(u, T, p0.x, p1.x, p2.x, p3.x); - store.y = interpolateCatmullRom(u, T, p0.y, p1.y, p2.y, p3.y); - store.z = interpolateCatmullRom(u, T, p0.z, p1.z, p2.z, p3.z); - return store; - } - - /** - * Interpolate a spline between at least 4 control points following the - * Catmull-Rom equation. here is the interpolation matrix m = [ 0.0 1.0 0.0 - * 0.0 ] [-T 0.0 T 0.0 ] [ 2T T-3 3-2T -T ] [-T 2-T T-2 T ] where T is the - * tension of the curve the result is a value between p1 and p2, t=0 for p1, - * t=1 for p2 - * - * @param u value from 0 to 1 - * @param T The tension of the curve - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @return catmull-Rom interpolation - */ - public static Vector3f interpolateCatmullRom( - float u, - float T, - Vector3f p0, - Vector3f p1, - Vector3f p2, - Vector3f p3 - ) { - return interpolateCatmullRom(u, T, p0, p1, p2, p3, null); - } - - /** - * Interpolate a spline between at least 4 control points following the - * Bezier equation. here is the interpolation matrix m = [ -1.0 3.0 -3.0 1.0 - * ] [ 3.0 -6.0 3.0 0.0 ] [ -3.0 3.0 0.0 0.0 ] [ 1.0 0.0 0.0 0.0 ] where T - * is the curve tension the result is a value between p1 and p3, t=0 for p1, - * t=1 for p3 - * - * @param u value from 0 to 1 - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @return Bezier interpolation - */ - public static float interpolateBezier(float u, float p0, float p1, float p2, float p3) { - float oneMinusU = 1.0f - u; - float oneMinusU2 = oneMinusU * oneMinusU; - float u2 = u * u; - return p0 * oneMinusU2 * oneMinusU - + 3.0f * p1 * u * oneMinusU2 - + 3.0f * p2 * u2 * oneMinusU - + p3 * u2 * u; - } - - /** - * Interpolate a spline between at least 4 control points following the - * Bezier equation. here is the interpolation matrix m = [ -1.0 3.0 -3.0 1.0 - * ] [ 3.0 -6.0 3.0 0.0 ] [ -3.0 3.0 0.0 0.0 ] [ 1.0 0.0 0.0 0.0 ] where T - * is the tension of the curve the result is a value between p1 and p3, t=0 - * for p1, t=1 for p3 - * - * @param u value from 0 to 1 - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @param store a Vector3f to store the result - * @return Bezier interpolation - */ - public static Vector3f interpolateBezier( - float u, - Vector3f p0, - Vector3f p1, - Vector3f p2, - Vector3f p3, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - store.x = interpolateBezier(u, p0.x, p1.x, p2.x, p3.x); - store.y = interpolateBezier(u, p0.y, p1.y, p2.y, p3.y); - store.z = interpolateBezier(u, p0.z, p1.z, p2.z, p3.z); - return store; - } - - /** - * Interpolate a spline between at least 4 control points following the - * Bezier equation. here is the interpolation matrix m = [ -1.0 3.0 -3.0 1.0 - * ] [ 3.0 -6.0 3.0 0.0 ] [ -3.0 3.0 0.0 0.0 ] [ 1.0 0.0 0.0 0.0 ] where T - * is the tension of the curve the result is a value between p1 and p3, t=0 - * for p1, t=1 for p3 - * - * @param u value from 0 to 1 - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @return Bezier interpolation - */ - public static Vector3f interpolateBezier( - float u, - Vector3f p0, - Vector3f p1, - Vector3f p2, - Vector3f p3 - ) { - return interpolateBezier(u, p0, p1, p2, p3, null); - } - - /** - * Compute the lenght on a catmull rom spline between control point 1 and 2 - * - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @param startRange the starting range on the segment (use 0) - * @param endRange the end range on the segment (use 1) - * @param curveTension the curve tension - * @return the length of the segment - */ - public static float getCatmullRomP1toP2Length( - Vector3f p0, - Vector3f p1, - Vector3f p2, - Vector3f p3, - float startRange, - float endRange, - float curveTension - ) { - - float epsilon = 0.001f; - float middleValue = (startRange + endRange) * 0.5f; - Vector3f start = p1.clone(); - if (startRange != 0) { - FastMath.interpolateCatmullRom(startRange, curveTension, p0, p1, p2, p3, start); - } - Vector3f end = p2.clone(); - if (endRange != 1) { - FastMath.interpolateCatmullRom(endRange, curveTension, p0, p1, p2, p3, end); - } - Vector3f middle = FastMath.interpolateCatmullRom(middleValue, curveTension, p0, p1, p2, p3); - float l = end.subtract(start).length(); - float l1 = middle.subtract(start).length(); - float l2 = end.subtract(middle).length(); - float len = l1 + l2; - if (l + epsilon < len) { - l1 = getCatmullRomP1toP2Length(p0, p1, p2, p3, startRange, middleValue, curveTension); - l2 = getCatmullRomP1toP2Length(p0, p1, p2, p3, middleValue, endRange, curveTension); - } - l = l1 + l2; - return l; - } - - /** - * Compute the lenght on a bezier spline between control point 1 and 2 - * - * @param p0 control point 0 - * @param p1 control point 1 - * @param p2 control point 2 - * @param p3 control point 3 - * @return the length of the segment - */ - public static float getBezierP1toP2Length(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) { - float delta = 0.02f, t = 0.0f, result = 0.0f; - Vector3f v1 = p0.clone(), v2 = new Vector3f(); - while (t <= 1.0f) { - FastMath.interpolateBezier(t, p0, p1, p2, p3, v2); - result += v1.subtractLocal(v2).length(); - v1.set(v2); - t += delta; - } - return result; - } - - /** - * Returns the arc cosine of a value.
- * Special cases: - * - * - * @param fValue The value to arc cosine. - * @return The angle, in radians. - * @see java.lang.Math#acos(double) - */ - public static float acos(float fValue) { - if (-1.0f < fValue) { - if (fValue < 1.0f) { - return (float) Math.acos(fValue); - } - - return 0.0f; - } - - return PI; - } - - /** - * Returns the arc sine of a value.
- * Special cases: - * - * - * @param fValue The value to arc sine. - * @return the angle in radians. - * @see java.lang.Math#asin(double) - */ - public static float asin(float fValue) { - if (-1.0f < fValue) { - if (fValue < 1.0f) { - return (float) Math.asin(fValue); - } - - return HALF_PI; - } - - return -HALF_PI; - } - - /** - * Returns the arc tangent of an angle given in radians.
- * - * @param fValue The angle, in radians. - * @return fValue's atan - * @see java.lang.Math#atan(double) - */ - public static float atan(float fValue) { - return (float) Math.atan(fValue); - } - - /** - * A direct call to Math.atan2. - * - * @param fY - * @param fX - * @return Math.atan2(fY,fX) - * @see java.lang.Math#atan2(double, double) - */ - public static float atan2(float fY, float fX) { - return (float) Math.atan2(fY, fX); - } - - /** - * Rounds a fValue up. A call to Math.ceil - * - * @param fValue The value. - * @return The fValue rounded up - * @see java.lang.Math#ceil(double) - */ - public static float ceil(float fValue) { - return (float) Math.ceil(fValue); - } - - /** - * Returns cosine of an angle. Direct call to java.lang.Math - * - * @see Math#cos(double) - * @param v The angle to cosine. - * @return the cosine of the angle. - */ - public static float cos(float v) { - return (float) Math.cos(v); - } - - /** - * Returns the sine of an angle. Direct call to java.lang.Math - * - * @see Math#sin(double) - * @param v The angle to sine. - * @return the sine of the angle. - */ - public static float sin(float v) { - return (float) Math.sin(v); - } - - /** - * Returns E^fValue - * - * @param fValue Value to raise to a power. - * @return The value E^fValue - * @see java.lang.Math#exp(double) - */ - public static float exp(float fValue) { - return (float) Math.exp(fValue); - } - - /** - * Returns Absolute value of a float. - * - * @param fValue The value to abs. - * @return The abs of the value. - * @see java.lang.Math#abs(float) - */ - public static float abs(float fValue) { - if (fValue < 0) { - return -fValue; - } - return fValue; - } - - /** - * Returns a number rounded down. - * - * @param fValue The value to round - * @return The given number rounded down - * @see java.lang.Math#floor(double) - */ - public static float floor(float fValue) { - return (float) Math.floor(fValue); - } - - /** - * Returns 1/sqrt(fValue) - * - * @param fValue The value to process. - * @return 1/sqrt(fValue) - * @see java.lang.Math#sqrt(double) - */ - public static float invSqrt(float fValue) { - return (float) (1.0f / Math.sqrt(fValue)); - } - - public static float fastInvSqrt(float x) { - float xhalf = 0.5f * x; - int i = Float.floatToIntBits(x); // get bits for floating value - i = 0x5f375a86 - (i >> 1); // gives initial guess y0 - x = Float.intBitsToFloat(i); // convert bits back to float - x = x * (1.5f - xhalf * x * x); // Newton step, repeating increases - // accuracy - return x; - } - - /** - * Returns the log base E of a value. - * - * @param fValue The value to log. - * @return The log of fValue base E - * @see java.lang.Math#log(double) - */ - public static float log(float fValue) { - return (float) Math.log(fValue); - } - - /** - * Returns the logarithm of value with given base, calculated as - * log(value)/log(base), so that pow(base, return)==value (contributed by - * vear) - * - * @param value The value to log. - * @param base Base of logarithm. - * @return The logarithm of value with given base - */ - public static float log(float value, float base) { - return (float) (Math.log(value) / Math.log(base)); - } - - /** - * Returns a number raised to an exponent power. fBase^fExponent - * - * @param fBase The base value (IE 2) - * @param fExponent The exponent value (IE 3) - * @return base raised to exponent (IE 8) - * @see java.lang.Math#pow(double, double) - */ - public static float pow(float fBase, float fExponent) { - return (float) Math.pow(fBase, fExponent); - } - - /** - * Returns the value squared. fValue ^ 2 - * - * @param fValue The vaule to square. - * @return The square of the given value. - */ - public static float sqr(float fValue) { - return fValue * fValue; - } - - /** - * Returns the square root of a given value. - * - * @param fValue The value to sqrt. - * @return The square root of the given value. - * @see java.lang.Math#sqrt(double) - */ - public static float sqrt(float fValue) { - return (float) Math.sqrt(fValue); - } - - /** - * Returns the tangent of a value. If USE_FAST_TRIG is enabled, an - * approximate value is returned. Otherwise, a direct value is used. - * - * @param fValue The value to tangent, in radians. - * @return The tangent of fValue. - * @see java.lang.Math#tan(double) - */ - public static float tan(float fValue) { - return (float) Math.tan(fValue); - } - - /** - * Returns 1 if the number is positive, -1 if the number is negative, and 0 - * otherwise - * - * @param iValue The integer to examine. - * @return The integer's sign. - */ - public static int sign(int iValue) { - if (iValue > 0) { - return 1; - } - if (iValue < 0) { - return -1; - } - return 0; - } - - /** - * Returns 1 if the number is positive, -1 if the number is negative, and 0 - * otherwise - * - * @param fValue The float to examine. - * @return The float's sign. - */ - public static float sign(float fValue) { - return Math.signum(fValue); - } - - /** - * Given 3 points in a 2d plane, this function computes if the points going - * from A-B-C are moving counter clock wise. - * - * @param p0 Point 0. - * @param p1 Point 1. - * @param p2 Point 2. - * @return 1 If they are CCW, -1 if they are not CCW, 0 if p2 is between p0 - * and p1. - */ - public static int counterClockwise(Vector2f p0, Vector2f p1, Vector2f p2) { - float dx1, dx2, dy1, dy2; - dx1 = p1.x - p0.x; - dy1 = p1.y - p0.y; - dx2 = p2.x - p0.x; - dy2 = p2.y - p0.y; - if (dx1 * dy2 > dy1 * dx2) { - return 1; - } - if (dx1 * dy2 < dy1 * dx2) { - return -1; - } - if ((dx1 * dx2 < 0) || (dy1 * dy2 < 0)) { - return -1; - } - if ((dx1 * dx1 + dy1 * dy1) < (dx2 * dx2 + dy2 * dy2)) { - return 1; - } - return 0; - } - - /** - * Test if a point is inside a triangle. 1 if the point is on the ccw side, - * -1 if the point is on the cw side, and 0 if it is on neither. - * - * @param t0 First point of the triangle. - * @param t1 Second point of the triangle. - * @param t2 Third point of the triangle. - * @param p The point to test. - * @return Value 1 or -1 if inside triangle, 0 otherwise. - */ - public static int pointInsideTriangle(Vector2f t0, Vector2f t1, Vector2f t2, Vector2f p) { - int val1 = counterClockwise(t0, t1, p); - if (val1 == 0) { - return 1; - } - int val2 = counterClockwise(t1, t2, p); - if (val2 == 0) { - return 1; - } - if (val2 != val1) { - return 0; - } - int val3 = counterClockwise(t2, t0, p); - if (val3 == 0) { - return 1; - } - if (val3 != val1) { - return 0; - } - return val3; - } - - /** - * A method that computes normal for a triangle defined by three vertices. - * - * @param v1 first vertex - * @param v2 second vertex - * @param v3 third vertex - * @return a normal for the face - */ - public static Vector3f computeNormal(Vector3f v1, Vector3f v2, Vector3f v3) { - Vector3f a1 = v1.subtract(v2); - Vector3f a2 = v3.subtract(v2); - return a2.crossLocal(a1).normalizeLocal(); - } - - /** - * Returns the determinant of a 4x4 matrix. - */ - public static float determinant( - double m00, - double m01, - double m02, - double m03, - double m10, - double m11, - double m12, - double m13, - double m20, - double m21, - double m22, - double m23, - double m30, - double m31, - double m32, - double m33 - ) { - - double det01 = m20 * m31 - m21 * m30; - double det02 = m20 * m32 - m22 * m30; - double det03 = m20 * m33 - m23 * m30; - double det12 = m21 * m32 - m22 * m31; - double det13 = m21 * m33 - m23 * m31; - double det23 = m22 * m33 - m23 * m32; - return (float) (m00 * (m11 * det23 - m12 * det13 + m13 * det12) - - m01 - * (m10 * det23 - m12 * det03 + m13 * det02) - + m02 - * (m10 * det13 - m11 * det03 + m13 * det01) - - m03 - * (m10 * det12 - m11 * det02 + m12 * det01)); - } - - /** - * Returns a random float between 0 and 1. - * - * @return A random float between 0.0f (inclusive) to 1.0f - * (exclusive). - */ - public static float nextRandomFloat() { - return rand.nextFloat(); - } - - /** - * Returns a random integer between min and max. - * - * @return A random int between min (inclusive) to max - * (inclusive). - */ - public static int nextRandomInt(int min, int max) { - return (int) (nextRandomFloat() * (max - min + 1)) + min; - } - - public static int nextRandomInt() { - return rand.nextInt(); - } - - /** - * Converts a point from Spherical coordinates to Cartesian (using positive - * Y as up) and stores the results in the store var. - */ - public static Vector3f sphericalToCartesian( - Vector3f sphereCoords, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - store.y = sphereCoords.x * FastMath.sin(sphereCoords.z); - float a = sphereCoords.x * FastMath.cos(sphereCoords.z); - store.x = a * FastMath.cos(sphereCoords.y); - store.z = a * FastMath.sin(sphereCoords.y); - - return store; - } - - /** - * Converts a point from Cartesian coordinates (using positive Y as up) to - * Spherical and stores the results in the store var. (Radius, Azimuth, - * Polar) - */ - public static Vector3f cartesianToSpherical( - Vector3f cartCoords, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - float x = cartCoords.x; - if (x == 0) { - x = FastMath.FLT_EPSILON; - } - store.x = FastMath - .sqrt( - (x * x) - + (cartCoords.y * cartCoords.y) - + (cartCoords.z * cartCoords.z) - ); - store.y = FastMath.atan(cartCoords.z / x); - if (x < 0) { - store.y += FastMath.PI; - } - store.z = FastMath.asin(cartCoords.y / store.x); - return store; - } - - /** - * Converts a point from Spherical coordinates to Cartesian (using positive - * Z as up) and stores the results in the store var. - */ - public static Vector3f sphericalToCartesianZ( - Vector3f sphereCoords, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - store.z = sphereCoords.x * FastMath.sin(sphereCoords.z); - float a = sphereCoords.x * FastMath.cos(sphereCoords.z); - store.x = a * FastMath.cos(sphereCoords.y); - store.y = a * FastMath.sin(sphereCoords.y); - - return store; - } - - /** - * Converts a point from Cartesian coordinates (using positive Z as up) to - * Spherical and stores the results in the store var. (Radius, Azimuth, - * Polar) - */ - public static Vector3f cartesianZToSpherical( - Vector3f cartCoords, - Vector3f store - ) { - if (store == null) { - store = new Vector3f(); - } - float x = cartCoords.x; - if (x == 0) { - x = FastMath.FLT_EPSILON; - } - store.x = FastMath - .sqrt( - (x * x) - + (cartCoords.y * cartCoords.y) - + (cartCoords.z * cartCoords.z) - ); - store.z = FastMath.atan(cartCoords.z / x); - if (x < 0) { - store.z += FastMath.PI; - } - store.y = FastMath.asin(cartCoords.y / store.x); - return store; - } - - /** - * Takes an value and expresses it in terms of min to max. - * - * @param val - the angle to normalize (in radians) - * @return the normalized angle (also in radians) - */ - public static float normalize(float val, float min, float max) { - if (Float.isInfinite(val) || Float.isNaN(val)) { - return 0f; - } - float range = max - min; - while (val > max) { - val -= range; - } - while (val < min) { - val += range; - } - return val; - } - - /** - * @param x the value whose sign is to be adjusted. - * @param y the value whose sign is to be used. - * @return x with its sign changed to match the sign of y. - */ - public static float copysign(float x, float y) { - if (y >= 0 && x <= -0) { - return -x; - } else if (y < 0 && x >= 0) { - return -x; - } else { - return x; - } - } - - /** - * Take a float input and clamp it between min and max. - * - * @param input - * @param min - * @param max - * @return clamped input - */ - public static float clamp(float input, float min, float max) { - return (input < min) ? min : (input > max) ? max : input; - } - - /** - * Clamps the given float to be between 0 and 1. - * - * @param input - * @return input clamped between 0 and 1. - */ - public static float saturate(float input) { - return clamp(input, 0f, 1f); - } - - /** - * Converts a single precision (32 bit) floating point value into half - * precision (16 bit). - * - *

- * Source: - * - * http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
- * broken link - * - * @param half The half floating point value as a short. - * @return floating point value of the half. - */ - public static float convertHalfToFloat(short half) { - switch ((int) half) { - case 0x0000: - return 0f; - case 0x8000: - return -0f; - case 0x7c00: - return Float.POSITIVE_INFINITY; - case 0xfc00: - return Float.NEGATIVE_INFINITY; - // TODO: Support for NaN? - default: - return Float - .intBitsToFloat( - ((half & 0x8000) << 16) - | (((half & 0x7c00) + 0x1C000) << 13) - | ((half & 0x03FF) << 13) - ); - } - } - - public static short convertFloatToHalf(float flt) { - if (Float.isNaN(flt)) { - throw new UnsupportedOperationException("NaN to half conversion not supported!"); - } else if (flt == Float.POSITIVE_INFINITY) { - return (short) 0x7c00; - } else if (flt == Float.NEGATIVE_INFINITY) { - return (short) 0xfc00; - } else if (flt == 0f) { - return (short) 0x0000; - } else if (flt == -0f) { - return (short) 0x8000; - } else if (flt > 65504f) { - // max value supported by half float - return 0x7bff; - } else if (flt < -65504f) { - return (short) (0x7bff | 0x8000); - } else if (flt > 0f && flt < 5.96046E-8f) { - return 0x0001; - } else if (flt < 0f && flt > -5.96046E-8f) { - return (short) 0x8001; - } - - int f = Float.floatToIntBits(flt); - return (short) (((f >> 16) & 0x8000) - | ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) - | ((f >> 13) & 0x03ff)); - } -} diff --git a/server/java/com/jme3/math/Matrix3f.java b/server/java/com/jme3/math/Matrix3f.java deleted file mode 100644 index 76e745c27c..0000000000 --- a/server/java/com/jme3/math/Matrix3f.java +++ /dev/null @@ -1,1362 +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 com.jme3.math; - -import java.nio.FloatBuffer; -import java.util.logging.Logger; - -import com.jme3.util.TempVars; - - -/** - * Matrix3f defines a 3x3 matrix. Matrix data is maintained - * internally and is accessible via the get and set methods. Convenience methods - * are used for matrix operations as well as generating a matrix from a given - * set of values. - * - * @author Mark Powell - * @author Joshua Slack - */ -public final class Matrix3f implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - - private static final Logger logger = Logger.getLogger(Matrix3f.class.getName()); - protected float m00, m01, m02; - protected float m10, m11, m12; - protected float m20, m21, m22; - public static final Matrix3f ZERO = new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0); - public static final Matrix3f IDENTITY = new Matrix3f(); - - /** - * Constructor instantiates a new Matrix3f object. The initial - * values for the matrix is that of the identity matrix. - * - */ - public Matrix3f() { - loadIdentity(); - } - - /** - * constructs a matrix with the given values. - * - * @param m00 0x0 in the matrix. - * @param m01 0x1 in the matrix. - * @param m02 0x2 in the matrix. - * @param m10 1x0 in the matrix. - * @param m11 1x1 in the matrix. - * @param m12 1x2 in the matrix. - * @param m20 2x0 in the matrix. - * @param m21 2x1 in the matrix. - * @param m22 2x2 in the matrix. - */ - public Matrix3f( - float m00, - float m01, - float m02, - float m10, - float m11, - float m12, - float m20, - float m21, - float m22 - ) { - - this.m00 = m00; - this.m01 = m01; - this.m02 = m02; - this.m10 = m10; - this.m11 = m11; - this.m12 = m12; - this.m20 = m20; - this.m21 = m21; - this.m22 = m22; - } - - /** - * Copy constructor that creates a new Matrix3f object that is - * the same as the provided matrix. - * - * @param mat the matrix to copy. - */ - public Matrix3f(Matrix3f mat) { - set(mat); - } - - /** - * Takes the absolute value of all matrix fields locally. - */ - public void absoluteLocal() { - m00 = FastMath.abs(m00); - m01 = FastMath.abs(m01); - m02 = FastMath.abs(m02); - m10 = FastMath.abs(m10); - m11 = FastMath.abs(m11); - m12 = FastMath.abs(m12); - m20 = FastMath.abs(m20); - m21 = FastMath.abs(m21); - m22 = FastMath.abs(m22); - } - - /** - * copy transfers the contents of a given matrix to this - * matrix. If a null matrix is supplied, this matrix is set to the identity - * matrix. - * - * @param matrix the matrix to copy. - * @return this - */ - public Matrix3f set(Matrix3f matrix) { - if (null == matrix) { - loadIdentity(); - } else { - m00 = matrix.m00; - m01 = matrix.m01; - m02 = matrix.m02; - m10 = matrix.m10; - m11 = matrix.m11; - m12 = matrix.m12; - m20 = matrix.m20; - m21 = matrix.m21; - m22 = matrix.m22; - } - return this; - } - - /** - * get retrieves a value from the matrix at the given position. - * If the position is invalid a JmeException is thrown. - * - * @param i the row index. - * @param j the colum index. - * @return the value at (i, j). - */ - @SuppressWarnings("fallthrough") - public float get(int i, int j) { - switch (i) { - case 0: - switch (j) { - case 0: - return m00; - case 1: - return m01; - case 2: - return m02; - } - case 1: - switch (j) { - case 0: - return m10; - case 1: - return m11; - case 2: - return m12; - } - case 2: - switch (j) { - case 0: - return m20; - case 1: - return m21; - case 2: - return m22; - } - } - - logger.warning("Invalid matrix index."); - throw new IllegalArgumentException("Invalid indices into matrix."); - } - - /** - * get(float[]) returns the matrix in row-major or column-major - * order. - * - * @param data The array to return the data into. This array can be 9 or 16 - * floats in size. Only the upper 3x3 are assigned to in the case of a 16 - * element array. - * @param rowMajor True for row major storage in the array (translation in - * elements 3, 7, 11 for a 4x4), false for column major (translation in - * elements 12, 13, 14 for a 4x4). - */ - public void get(float[] data, boolean rowMajor) { - if (data.length == 9) { - if (rowMajor) { - data[0] = m00; - data[1] = m01; - data[2] = m02; - data[3] = m10; - data[4] = m11; - data[5] = m12; - data[6] = m20; - data[7] = m21; - data[8] = m22; - } else { - data[0] = m00; - data[1] = m10; - data[2] = m20; - data[3] = m01; - data[4] = m11; - data[5] = m21; - data[6] = m02; - data[7] = m12; - data[8] = m22; - } - } else if (data.length == 16) { - if (rowMajor) { - data[0] = m00; - data[1] = m01; - data[2] = m02; - data[4] = m10; - data[5] = m11; - data[6] = m12; - data[8] = m20; - data[9] = m21; - data[10] = m22; - } else { - data[0] = m00; - data[1] = m10; - data[2] = m20; - data[4] = m01; - data[5] = m11; - data[6] = m21; - data[8] = m02; - data[9] = m12; - data[10] = m22; - } - } else { - throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get()."); - } - } - - /** - * Normalize this matrix and store the result in the store parameter that is - * returned. - * - * Note that the original matrix is not altered. - * - * @param store the matrix to store the result of the normalization. If this - * parameter is null a new one is created - * @return the normalized matrix - */ - public Matrix3f normalize(Matrix3f store) { - if (store == null) { - store = new Matrix3f(); - } - - float mag = 1.0f - / FastMath - .sqrt( - m00 * m00 - + m10 * m10 - + m20 * m20 - ); - - store.m00 = m00 * mag; - store.m10 = m10 * mag; - store.m20 = m20 * mag; - - mag = 1.0f - / FastMath - .sqrt( - m01 * m01 - + m11 * m11 - + m21 * m21 - ); - - store.m01 = m01 * mag; - store.m11 = m11 * mag; - store.m21 = m21 * mag; - - store.m02 = store.m10 * store.m21 - store.m11 * store.m20; - store.m12 = store.m01 * store.m20 - store.m00 * store.m21; - store.m22 = store.m00 * store.m11 - store.m01 * store.m10; - return store; - } - - /** - * Normalize this matrix - * - * @return this matrix once normalized. - */ - public Matrix3f normalizeLocal() { - return normalize(this); - } - - /** - * getColumn returns one of three columns specified by the - * parameter. This column is returned as a Vector3f object. - * - * @param i the column to retrieve. Must be between 0 and 2. - * @return the column specified by the index. - */ - public Vector3f getColumn(int i) { - return getColumn(i, null); - } - - /** - * getColumn returns one of three columns specified by the - * parameter. This column is returned as a Vector3f object. - * - * @param i the column to retrieve. Must be between 0 and 2. - * @param store the vector object to store the result in. if null, a new one - * is created. - * @return the column specified by the index. - */ - public Vector3f getColumn(int i, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - switch (i) { - case 0: - store.x = m00; - store.y = m10; - store.z = m20; - break; - case 1: - store.x = m01; - store.y = m11; - store.z = m21; - break; - case 2: - store.x = m02; - store.y = m12; - store.z = m22; - break; - default: - logger.warning("Invalid column index."); - throw new IllegalArgumentException("Invalid column index. " + i); - } - return store; - } - - /** - * getColumn returns one of three rows as specified by the - * parameter. This row is returned as a Vector3f object. - * - * @param i the row to retrieve. Must be between 0 and 2. - * @return the row specified by the index. - */ - public Vector3f getRow(int i) { - return getRow(i, null); - } - - /** - * getRow returns one of three rows as specified by the - * parameter. This row is returned as a Vector3f object. - * - * @param i the row to retrieve. Must be between 0 and 2. - * @param store the vector object to store the result in. if null, a new one - * is created. - * @return the row specified by the index. - */ - public Vector3f getRow(int i, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - switch (i) { - case 0: - store.x = m00; - store.y = m01; - store.z = m02; - break; - case 1: - store.x = m10; - store.y = m11; - store.z = m12; - break; - case 2: - store.x = m20; - store.y = m21; - store.z = m22; - break; - default: - logger.warning("Invalid row index."); - throw new IllegalArgumentException("Invalid row index. " + i); - } - return store; - } - - /** - * fillFloatBuffer fills a FloatBuffer object with the matrix - * data. - * - * @param fb the buffer to fill, starting at current position. Must have - * room for 9 more floats. - * @return matrix data as a FloatBuffer. (position is advanced by 9 and any - * limit set is not changed). - */ - public FloatBuffer fillFloatBuffer(FloatBuffer fb, boolean columnMajor) { -// if (columnMajor){ -// fb.put(m00).put(m10).put(m20); -// fb.put(m01).put(m11).put(m21); -// fb.put(m02).put(m12).put(m22); -// }else{ -// fb.put(m00).put(m01).put(m02); -// fb.put(m10).put(m11).put(m12); -// fb.put(m20).put(m21).put(m22); -// } - - TempVars vars = TempVars.get(); - - - fillFloatArray(vars.matrixWrite, columnMajor); - fb.put(vars.matrixWrite, 0, 9); - - vars.release(); - - return fb; - } - - public void fillFloatArray(float[] f, boolean columnMajor) { - if (columnMajor) { - f[0] = m00; - f[1] = m10; - f[2] = m20; - f[3] = m01; - f[4] = m11; - f[5] = m21; - f[6] = m02; - f[7] = m12; - f[8] = m22; - } else { - f[0] = m00; - f[1] = m01; - f[2] = m02; - f[3] = m10; - f[4] = m11; - f[5] = m12; - f[6] = m20; - f[7] = m21; - f[8] = m22; - } - } - - /** - * - * setColumn sets a particular column of this matrix to that - * represented by the provided vector. - * - * @param i the column to set. - * @param column the data to set. - * @return this - */ - public Matrix3f setColumn(int i, Vector3f column) { - - if (column == null) { - logger.warning("Column is null. Ignoring."); - return this; - } - switch (i) { - case 0: - m00 = column.x; - m10 = column.y; - m20 = column.z; - break; - case 1: - m01 = column.x; - m11 = column.y; - m21 = column.z; - break; - case 2: - m02 = column.x; - m12 = column.y; - m22 = column.z; - break; - default: - logger.warning("Invalid column index."); - throw new IllegalArgumentException("Invalid column index. " + i); - } - return this; - } - - /** - * - * setRow sets a particular row of this matrix to that - * represented by the provided vector. - * - * @param i the row to set. - * @param row the data to set. - * @return this - */ - public Matrix3f setRow(int i, Vector3f row) { - - if (row == null) { - logger.warning("Row is null. Ignoring."); - return this; - } - switch (i) { - case 0: - m00 = row.x; - m01 = row.y; - m02 = row.z; - break; - case 1: - m10 = row.x; - m11 = row.y; - m12 = row.z; - break; - case 2: - m20 = row.x; - m21 = row.y; - m22 = row.z; - break; - default: - logger.warning("Invalid row index."); - throw new IllegalArgumentException("Invalid row index. " + i); - } - return this; - } - - /** - * set places a given value into the matrix at the given - * position. If the position is invalid a JmeException is - * thrown. - * - * @param i the row index. - * @param j the colum index. - * @param value the value for (i, j). - * @return this - */ - @SuppressWarnings("fallthrough") - public Matrix3f set(int i, int j, float value) { - switch (i) { - case 0: - switch (j) { - case 0: - m00 = value; - return this; - case 1: - m01 = value; - return this; - case 2: - m02 = value; - return this; - } - case 1: - switch (j) { - case 0: - m10 = value; - return this; - case 1: - m11 = value; - return this; - case 2: - m12 = value; - return this; - } - case 2: - switch (j) { - case 0: - m20 = value; - return this; - case 1: - m21 = value; - return this; - case 2: - m22 = value; - return this; - } - } - - logger.warning("Invalid matrix index."); - throw new IllegalArgumentException("Invalid indices into matrix."); - } - - /** - * - * set sets the values of the matrix to those supplied by the - * 3x3 two dimenion array. - * - * @param matrix the new values of the matrix. - * @throws JmeException if the array is not of size 9. - * @return this - */ - public Matrix3f set(float[][] matrix) { - if (matrix.length != 3 || matrix[0].length != 3) { - throw new IllegalArgumentException( - "Array must be of size 9." - ); - } - - m00 = matrix[0][0]; - m01 = matrix[0][1]; - m02 = matrix[0][2]; - m10 = matrix[1][0]; - m11 = matrix[1][1]; - m12 = matrix[1][2]; - m20 = matrix[2][0]; - m21 = matrix[2][1]; - m22 = matrix[2][2]; - - return this; - } - - /** - * Recreate Matrix using the provided axis. - * - * @param uAxis Vector3f - * @param vAxis Vector3f - * @param wAxis Vector3f - */ - public void fromAxes(Vector3f uAxis, Vector3f vAxis, Vector3f wAxis) { - m00 = uAxis.x; - m10 = uAxis.y; - m20 = uAxis.z; - - m01 = vAxis.x; - m11 = vAxis.y; - m21 = vAxis.z; - - m02 = wAxis.x; - m12 = wAxis.y; - m22 = wAxis.z; - } - - /** - * set sets the values of this matrix from an array of values - * assuming that the data is rowMajor order; - * - * @param matrix the matrix to set the value to. - * @return this - */ - public Matrix3f set(float[] matrix) { - return set(matrix, true); - } - - /** - * set sets the values of this matrix from an array of values; - * - * @param matrix the matrix to set the value to. - * @param rowMajor whether the incoming data is in row or column major - * order. - * @return this - */ - public Matrix3f set(float[] matrix, boolean rowMajor) { - if (matrix.length != 9) { - throw new IllegalArgumentException( - "Array must be of size 9." - ); - } - - if (rowMajor) { - m00 = matrix[0]; - m01 = matrix[1]; - m02 = matrix[2]; - m10 = matrix[3]; - m11 = matrix[4]; - m12 = matrix[5]; - m20 = matrix[6]; - m21 = matrix[7]; - m22 = matrix[8]; - } else { - m00 = matrix[0]; - m01 = matrix[3]; - m02 = matrix[6]; - m10 = matrix[1]; - m11 = matrix[4]; - m12 = matrix[7]; - m20 = matrix[2]; - m21 = matrix[5]; - m22 = matrix[8]; - } - return this; - } - - /** - * - * set defines the values of the matrix based on a supplied - * Quaternion. It should be noted that all previous values will - * be overridden. - * - * @param quaternion the quaternion to create a rotational matrix from. - * @return this - */ - public Matrix3f set(Quaternion quaternion) { - return quaternion.toRotationMatrix(this); - } - - /** - * loadIdentity sets this matrix to the identity matrix. Where - * all values are zero except those along the diagonal which are one. - * - */ - public void loadIdentity() { - m01 = m02 = m10 = m12 = m20 = m21 = 0; - m00 = m11 = m22 = 1; - } - - /** - * @return true if this matrix is identity - */ - public boolean isIdentity() { - return (m00 == 1 && m01 == 0 && m02 == 0) - && (m10 == 0 && m11 == 1 && m12 == 0) - && (m20 == 0 && m21 == 0 && m22 == 1); - } - - /** - * fromAngleAxis sets this matrix4f to the values specified by - * an angle and an axis of rotation. This method creates an object, so use - * fromAngleNormalAxis if your axis is already normalized. - * - * @param angle the angle to rotate (in radians). - * @param axis the axis of rotation. - */ - public void fromAngleAxis(float angle, Vector3f axis) { - Vector3f normAxis = axis.normalize(); - fromAngleNormalAxis(angle, normAxis); - } - - /** - * fromAngleNormalAxis sets this matrix4f to the values - * specified by an angle and a normalized axis of rotation. - * - * @param angle the angle to rotate (in radians). - * @param axis the axis of rotation (already normalized). - */ - public void fromAngleNormalAxis(float angle, Vector3f axis) { - float fCos = FastMath.cos(angle); - float fSin = FastMath.sin(angle); - float fOneMinusCos = ((float) 1.0) - fCos; - float fX2 = axis.x * axis.x; - float fY2 = axis.y * axis.y; - float fZ2 = axis.z * axis.z; - float fXYM = axis.x * axis.y * fOneMinusCos; - float fXZM = axis.x * axis.z * fOneMinusCos; - float fYZM = axis.y * axis.z * fOneMinusCos; - float fXSin = axis.x * fSin; - float fYSin = axis.y * fSin; - float fZSin = axis.z * fSin; - - m00 = fX2 * fOneMinusCos + fCos; - m01 = fXYM - fZSin; - m02 = fXZM + fYSin; - m10 = fXYM + fZSin; - m11 = fY2 * fOneMinusCos + fCos; - m12 = fYZM - fXSin; - m20 = fXZM - fYSin; - m21 = fYZM + fXSin; - m22 = fZ2 * fOneMinusCos + fCos; - } - - /** - * mult multiplies this matrix by a given matrix. The result - * matrix is returned as a new object. If the given matrix is null, a null - * matrix is returned. - * - * @param mat the matrix to multiply this matrix by. - * @return the result matrix. - */ - public Matrix3f mult(Matrix3f mat) { - return mult(mat, null); - } - - /** - * mult multiplies this matrix by a given matrix. The result - * matrix is returned as a new object. - * - * @param mat the matrix to multiply this matrix by. - * @param product the matrix to store the result in. if null, a new matrix3f - * is created. It is safe for mat and product to be the same object. - * @return a matrix3f object containing the result of this operation - */ - public Matrix3f mult(Matrix3f mat, Matrix3f product) { - - float temp00, temp01, temp02; - float temp10, temp11, temp12; - float temp20, temp21, temp22; - - if (product == null) { - product = new Matrix3f(); - } - temp00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20; - temp01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21; - temp02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22; - temp10 = m10 * mat.m00 + m11 * mat.m10 + m12 * mat.m20; - temp11 = m10 * mat.m01 + m11 * mat.m11 + m12 * mat.m21; - temp12 = m10 * mat.m02 + m11 * mat.m12 + m12 * mat.m22; - temp20 = m20 * mat.m00 + m21 * mat.m10 + m22 * mat.m20; - temp21 = m20 * mat.m01 + m21 * mat.m11 + m22 * mat.m21; - temp22 = m20 * mat.m02 + m21 * mat.m12 + m22 * mat.m22; - - product.m00 = temp00; - product.m01 = temp01; - product.m02 = temp02; - product.m10 = temp10; - product.m11 = temp11; - product.m12 = temp12; - product.m20 = temp20; - product.m21 = temp21; - product.m22 = temp22; - - return product; - } - - /** - * mult multiplies this matrix by a given Vector3f - * object. The result vector is returned. If the given vector is null, null - * will be returned. - * - * @param vec the vector to multiply this matrix by. - * @return the result vector. - */ - public Vector3f mult(Vector3f vec) { - return mult(vec, null); - } - - /** - * Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in - * product. - * - * @param vec The Vector3f to multiply. - * @param product The Vector3f to store the result, it is safe for this to - * be the same as vec. - * @return The given product vector. - */ - public Vector3f mult(Vector3f vec, Vector3f product) { - - if (null == product) { - product = new Vector3f(); - } - - float x = vec.x; - float y = vec.y; - float z = vec.z; - - product.x = m00 * x + m01 * y + m02 * z; - product.y = m10 * x + m11 * y + m12 * z; - product.z = m20 * x + m21 * y + m22 * z; - return product; - } - - /** - * multLocal multiplies this matrix internally by a given float - * scale factor. - * - * @param scale the value to scale by. - * @return this Matrix3f - */ - public Matrix3f multLocal(float scale) { - m00 *= scale; - m01 *= scale; - m02 *= scale; - m10 *= scale; - m11 *= scale; - m12 *= scale; - m20 *= scale; - m21 *= scale; - m22 *= scale; - return this; - } - - /** - * multLocal multiplies this matrix by a given - * Vector3f object. The result vector is stored inside the - * passed vector, then returned . If the given vector is null, null will be - * returned. - * - * @param vec the vector to multiply this matrix by. - * @return The passed vector after multiplication - */ - public Vector3f multLocal(Vector3f vec) { - if (vec == null) { - return null; - } - float x = vec.x; - float y = vec.y; - vec.x = m00 * x + m01 * y + m02 * vec.z; - vec.y = m10 * x + m11 * y + m12 * vec.z; - vec.z = m20 * x + m21 * y + m22 * vec.z; - return vec; - } - - /** - * mult multiplies this matrix by a given matrix. The result - * matrix is saved in the current matrix. If the given matrix is null, - * nothing happens. The current matrix is returned. This is equivalent to - * this*=mat - * - * @param mat the matrix to multiply this matrix by. - * @return This matrix, after the multiplication - */ - public Matrix3f multLocal(Matrix3f mat) { - return mult(mat, this); - } - - /** - * Transposes this matrix in place. Returns this matrix for chaining - * - * @return This matrix after transpose - */ - public Matrix3f transposeLocal() { -// float[] tmp = new float[9]; -// get(tmp, false); -// set(tmp, true); - - float tmp = m01; - m01 = m10; - m10 = tmp; - - tmp = m02; - m02 = m20; - m20 = tmp; - - tmp = m12; - m12 = m21; - m21 = tmp; - - return this; - } - - /** - * Inverts this matrix as a new Matrix3f. - * - * @return The new inverse matrix - */ - public Matrix3f invert() { - return invert(null); - } - - /** - * Inverts this matrix and stores it in the given store. - * - * @return The store - */ - public Matrix3f invert(Matrix3f store) { - if (store == null) { - store = new Matrix3f(); - } - - float det = determinant(); - if (FastMath.abs(det) <= FastMath.FLT_EPSILON) { - return store.zero(); - } - - store.m00 = m11 * m22 - m12 * m21; - store.m01 = m02 * m21 - m01 * m22; - store.m02 = m01 * m12 - m02 * m11; - store.m10 = m12 * m20 - m10 * m22; - store.m11 = m00 * m22 - m02 * m20; - store.m12 = m02 * m10 - m00 * m12; - store.m20 = m10 * m21 - m11 * m20; - store.m21 = m01 * m20 - m00 * m21; - store.m22 = m00 * m11 - m01 * m10; - - store.multLocal(1f / det); - return store; - } - - /** - * Inverts this matrix locally. - * - * @return this - */ - public Matrix3f invertLocal() { - float det = determinant(); - if (FastMath.abs(det) <= 0f) { - return zero(); - } - - float f00 = m11 * m22 - m12 * m21; - float f01 = m02 * m21 - m01 * m22; - float f02 = m01 * m12 - m02 * m11; - float f10 = m12 * m20 - m10 * m22; - float f11 = m00 * m22 - m02 * m20; - float f12 = m02 * m10 - m00 * m12; - float f20 = m10 * m21 - m11 * m20; - float f21 = m01 * m20 - m00 * m21; - float f22 = m00 * m11 - m01 * m10; - - m00 = f00; - m01 = f01; - m02 = f02; - m10 = f10; - m11 = f11; - m12 = f12; - m20 = f20; - m21 = f21; - m22 = f22; - - multLocal(1f / det); - return this; - } - - /** - * Returns a new matrix representing the adjoint of this matrix. - * - * @return The adjoint matrix - */ - public Matrix3f adjoint() { - return adjoint(null); - } - - /** - * Places the adjoint of this matrix in store (creates store if null.) - * - * @param store The matrix to store the result in. If null, a new matrix is - * created. - * @return store - */ - public Matrix3f adjoint(Matrix3f store) { - if (store == null) { - store = new Matrix3f(); - } - - store.m00 = m11 * m22 - m12 * m21; - store.m01 = m02 * m21 - m01 * m22; - store.m02 = m01 * m12 - m02 * m11; - store.m10 = m12 * m20 - m10 * m22; - store.m11 = m00 * m22 - m02 * m20; - store.m12 = m02 * m10 - m00 * m12; - store.m20 = m10 * m21 - m11 * m20; - store.m21 = m01 * m20 - m00 * m21; - store.m22 = m00 * m11 - m01 * m10; - - return store; - } - - /** - * determinant generates the determinant of this matrix. - * - * @return the determinant - */ - public float determinant() { - float fCo00 = m11 * m22 - m12 * m21; - float fCo10 = m12 * m20 - m10 * m22; - float fCo20 = m10 * m21 - m11 * m20; - float fDet = m00 * fCo00 + m01 * fCo10 + m02 * fCo20; - return fDet; - } - - /** - * Sets all of the values in this matrix to zero. - * - * @return this matrix - */ - public Matrix3f zero() { - m00 = m01 = m02 = m10 = m11 = m12 = m20 = m21 = m22 = 0.0f; - return this; - } - - /** - * transpose locally transposes this Matrix. This is - * inconsistent with general value vs local semantics, but is preserved for - * backwards compatibility. Use transposeNew() to transpose to a new object - * (value). - * - * @return this object for chaining. - */ - public Matrix3f transpose() { - return transposeLocal(); - } - - /** - * transposeNew returns a transposed version of this matrix. - * - * @return The new Matrix3f object. - */ - public Matrix3f transposeNew() { - Matrix3f ret = new Matrix3f(m00, m10, m20, m01, m11, m21, m02, m12, m22); - return ret; - } - - /** - * toString returns the string representation of this object. - * It is in a format of a 3x3 matrix. For example, an identity matrix would - * be represented by the following string. com.jme.math.Matrix3f
- * [
- * 1.0 0.0 0.0
- * 0.0 1.0 0.0
- * 0.0 0.0 1.0
- * ]
- * - * @return the string representation of this object. - */ - @Override - public String toString() { - StringBuilder result = new StringBuilder("Matrix3f\n[\n"); - result.append(" "); - result.append(m00); - result.append(" "); - result.append(m01); - result.append(" "); - result.append(m02); - result.append(" \n"); - result.append(" "); - result.append(m10); - result.append(" "); - result.append(m11); - result.append(" "); - result.append(m12); - result.append(" \n"); - result.append(" "); - result.append(m20); - result.append(" "); - result.append(m21); - result.append(" "); - result.append(m22); - result.append(" \n]"); - return result.toString(); - } - - /** - * - * hashCode returns the hash code value as an integer and is - * supported for the benefit of hashing based collection classes such as - * Hashtable, HashMap, HashSet etc. - * - * @return the hashcode for this instance of Matrix4f. - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - int hash = 37; - hash = 37 * hash + Float.floatToIntBits(m00); - hash = 37 * hash + Float.floatToIntBits(m01); - hash = 37 * hash + Float.floatToIntBits(m02); - - hash = 37 * hash + Float.floatToIntBits(m10); - hash = 37 * hash + Float.floatToIntBits(m11); - hash = 37 * hash + Float.floatToIntBits(m12); - - hash = 37 * hash + Float.floatToIntBits(m20); - hash = 37 * hash + Float.floatToIntBits(m21); - hash = 37 * hash + Float.floatToIntBits(m22); - - return hash; - } - - /** - * are these two matrices the same? they are is they both have the same mXX - * values. - * - * @param o the object to compare for equality - * @return true if they are equal - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Matrix3f) || o == null) { - return false; - } - - if (this == o) { - return true; - } - - Matrix3f comp = (Matrix3f) o; - if (Float.compare(m00, comp.m00) != 0) { - return false; - } - if (Float.compare(m01, comp.m01) != 0) { - return false; - } - if (Float.compare(m02, comp.m02) != 0) { - return false; - } - - if (Float.compare(m10, comp.m10) != 0) { - return false; - } - if (Float.compare(m11, comp.m11) != 0) { - return false; - } - if (Float.compare(m12, comp.m12) != 0) { - return false; - } - - if (Float.compare(m20, comp.m20) != 0) { - return false; - } - if (Float.compare(m21, comp.m21) != 0) { - return false; - } - if (Float.compare(m22, comp.m22) != 0) { - return false; - } - - return true; - } - - /** - * A function for creating a rotation matrix that rotates a vector called - * "start" into another vector called "end". - * - * @param start normalized non-zero starting vector - * @param end normalized non-zero ending vector - * @see "Tomas M�ller, John Hughes \"Efficiently Building a Matrix to Rotate - * \ One Vector to Another\" Journal of Graphics Tools, 4(4):1-4, 1999" - */ - public void fromStartEndVectors(Vector3f start, Vector3f end) { - Vector3f v = new Vector3f(); - float e, h, f; - - start.cross(end, v); - e = start.dot(end); - f = (e < 0) ? -e : e; - - // if "from" and "to" vectors are nearly parallel - if (f > 1.0f - FastMath.ZERO_TOLERANCE) { - Vector3f u = new Vector3f(); - Vector3f x = new Vector3f(); - float c1, c2, c3; /* coefficients for later use */ - int i, j; - - x.x = (start.x > 0.0) ? start.x : -start.x; - x.y = (start.y > 0.0) ? start.y : -start.y; - x.z = (start.z > 0.0) ? start.z : -start.z; - - if (x.x < x.y) { - if (x.x < x.z) { - x.x = 1.0f; - x.y = x.z = 0.0f; - } else { - x.z = 1.0f; - x.x = x.y = 0.0f; - } - } else { - if (x.y < x.z) { - x.y = 1.0f; - x.x = x.z = 0.0f; - } else { - x.z = 1.0f; - x.x = x.y = 0.0f; - } - } - - u.x = x.x - start.x; - u.y = x.y - start.y; - u.z = x.z - start.z; - v.x = x.x - end.x; - v.y = x.y - end.y; - v.z = x.z - end.z; - - c1 = 2.0f / u.dot(u); - c2 = 2.0f / v.dot(v); - c3 = c1 * c2 * u.dot(v); - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - float val = -c1 * u.get(i) * u.get(j) - - c2 - * v.get(i) - * v.get(j) - + c3 * v.get(i) * u.get(j); - set(i, j, val); - } - float val = get(i, i); - set(i, i, val + 1.0f); - } - } else { - // the most common case, unless "start"="end", or "start"=-"end" - float hvx, hvz, hvxy, hvxz, hvyz; - h = 1.0f / (1.0f + e); - hvx = h * v.x; - hvz = h * v.z; - hvxy = hvx * v.y; - hvxz = hvx * v.z; - hvyz = hvz * v.y; - set(0, 0, e + hvx * v.x); - set(0, 1, hvxy - v.z); - set(0, 2, hvxz + v.y); - - set(1, 0, hvxy + v.z); - set(1, 1, e + h * v.y * v.y); - set(1, 2, hvyz - v.x); - - set(2, 0, hvxz - v.y); - set(2, 1, hvyz + v.x); - set(2, 2, e + hvz * v.z); - } - } - - /** - * scale scales the operation performed by this matrix on a - * per-component basis. - * - * @param scale The scale applied to each of the X, Y and Z output values. - */ - public void scale(Vector3f scale) { - m00 *= scale.x; - m10 *= scale.x; - m20 *= scale.x; - m01 *= scale.y; - m11 *= scale.y; - m21 *= scale.y; - m02 *= scale.z; - m12 *= scale.z; - m22 *= scale.z; - } - - static boolean equalIdentity(Matrix3f mat) { - if (Math.abs(mat.m00 - 1) > 1e-4) { - return false; - } - if (Math.abs(mat.m11 - 1) > 1e-4) { - return false; - } - if (Math.abs(mat.m22 - 1) > 1e-4) { - return false; - } - - if (Math.abs(mat.m01) > 1e-4) { - return false; - } - if (Math.abs(mat.m02) > 1e-4) { - return false; - } - - if (Math.abs(mat.m10) > 1e-4) { - return false; - } - if (Math.abs(mat.m12) > 1e-4) { - return false; - } - - if (Math.abs(mat.m20) > 1e-4) { - return false; - } - if (Math.abs(mat.m21) > 1e-4) { - return false; - } - - return true; - } - - @Override - public Matrix3f clone() { - try { - return (Matrix3f) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } -} diff --git a/server/java/com/jme3/math/Matrix4f.java b/server/java/com/jme3/math/Matrix4f.java deleted file mode 100644 index b490b70673..0000000000 --- a/server/java/com/jme3/math/Matrix4f.java +++ /dev/null @@ -1,2277 +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 com.jme3.math; - -import java.nio.FloatBuffer; -import java.util.logging.Logger; - -import com.jme3.util.TempVars; - - -/** - * Matrix4f defines and maintains a 4x4 matrix in row major order. - * This matrix is intended for use in a translation and rotational capacity. It - * provides convenience methods for creating the matrix from a multitude of - * sources. - * - * Matrices are stored assuming column vectors on the right, with the - * translation in the rightmost column. Element numbering is row,column, so m03 - * is the zeroth row, third column, which is the "x" translation part. This - * means that the implicit storage order is column major. However, the get() and - * set() functions on float arrays default to row major order! - * - * @author Mark Powell - * @author Joshua Slack - */ -public final class Matrix4f implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - - private static final Logger logger = Logger.getLogger(Matrix4f.class.getName()); - public float m00, m01, m02, m03; - public float m10, m11, m12, m13; - public float m20, m21, m22, m23; - public float m30, m31, m32, m33; - public static final Matrix4f ZERO = new Matrix4f( - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ); - public static final Matrix4f IDENTITY = new Matrix4f(); - - /** - * Constructor instantiates a new Matrix that is set to the - * identity matrix. - * - */ - public Matrix4f() { - loadIdentity(); - } - - /** - * constructs a matrix with the given values. - */ - public Matrix4f( - float m00, - float m01, - float m02, - float m03, - float m10, - float m11, - float m12, - float m13, - float m20, - float m21, - float m22, - float m23, - float m30, - float m31, - float m32, - float m33 - ) { - - this.m00 = m00; - this.m01 = m01; - this.m02 = m02; - this.m03 = m03; - this.m10 = m10; - this.m11 = m11; - this.m12 = m12; - this.m13 = m13; - this.m20 = m20; - this.m21 = m21; - this.m22 = m22; - this.m23 = m23; - this.m30 = m30; - this.m31 = m31; - this.m32 = m32; - this.m33 = m33; - } - - /** - * Create a new Matrix4f, given data in column-major format. - * - * @param array An array of 16 floats in column-major format (translation in - * elements 12, 13 and 14). - */ - public Matrix4f(float[] array) { - set(array, false); - } - - /** - * Constructor instantiates a new Matrix that is set to the - * provided matrix. This constructor copies a given Matrix. If the provided - * matrix is null, the constructor sets the matrix to the identity. - * - * @param mat the matrix to copy. - */ - public Matrix4f(Matrix4f mat) { - copy(mat); - } - - /** - * copy transfers the contents of a given matrix to this - * matrix. If a null matrix is supplied, this matrix is set to the identity - * matrix. - * - * @param matrix the matrix to copy. - */ - public void copy(Matrix4f matrix) { - if (null == matrix) { - loadIdentity(); - } else { - m00 = matrix.m00; - m01 = matrix.m01; - m02 = matrix.m02; - m03 = matrix.m03; - m10 = matrix.m10; - m11 = matrix.m11; - m12 = matrix.m12; - m13 = matrix.m13; - m20 = matrix.m20; - m21 = matrix.m21; - m22 = matrix.m22; - m23 = matrix.m23; - m30 = matrix.m30; - m31 = matrix.m31; - m32 = matrix.m32; - m33 = matrix.m33; - } - } - - public void fromFrame(Vector3f location, Vector3f direction, Vector3f up, Vector3f left) { - loadIdentity(); - - TempVars vars = TempVars.get(); - - Vector3f f = vars.vect1.set(direction); - Vector3f s = vars.vect2.set(f).crossLocal(up); - Vector3f u = vars.vect3.set(s).crossLocal(f); -// s.normalizeLocal(); -// u.normalizeLocal(); - - m00 = s.x; - m01 = s.y; - m02 = s.z; - - m10 = u.x; - m11 = u.y; - m12 = u.z; - - m20 = -f.x; - m21 = -f.y; - m22 = -f.z; - -// m00 = -left.x; -// m10 = -left.y; -// m20 = -left.z; -// -// m01 = up.x; -// m11 = up.y; -// m21 = up.z; -// -// m02 = -direction.x; -// m12 = -direction.y; -// m22 = -direction.z; -// - - Matrix4f transMatrix = vars.tempMat4; - transMatrix.loadIdentity(); - transMatrix.m03 = -location.x; - transMatrix.m13 = -location.y; - transMatrix.m23 = -location.z; - this.multLocal(transMatrix); - - vars.release(); - -// transMatrix.multLocal(this); - -// set(transMatrix); - } - - /** - * get retrieves the values of this object into a float array - * in row-major order. - * - * @param matrix the matrix to set the values into. - */ - public void get(float[] matrix) { - get(matrix, true); - } - - /** - * set retrieves the values of this object into a float array. - * - * @param matrix the matrix to set the values into. - * @param rowMajor whether the outgoing data is in row or column major - * order. - */ - public void get(float[] matrix, boolean rowMajor) { - if (matrix.length != 16) { - throw new IllegalArgumentException( - "Array must be of size 16." - ); - } - - if (rowMajor) { - matrix[0] = m00; - matrix[1] = m01; - matrix[2] = m02; - matrix[3] = m03; - matrix[4] = m10; - matrix[5] = m11; - matrix[6] = m12; - matrix[7] = m13; - matrix[8] = m20; - matrix[9] = m21; - matrix[10] = m22; - matrix[11] = m23; - matrix[12] = m30; - matrix[13] = m31; - matrix[14] = m32; - matrix[15] = m33; - } else { - matrix[0] = m00; - matrix[4] = m01; - matrix[8] = m02; - matrix[12] = m03; - matrix[1] = m10; - matrix[5] = m11; - matrix[9] = m12; - matrix[13] = m13; - matrix[2] = m20; - matrix[6] = m21; - matrix[10] = m22; - matrix[14] = m23; - matrix[3] = m30; - matrix[7] = m31; - matrix[11] = m32; - matrix[15] = m33; - } - } - - /** - * get retrieves a value from the matrix at the given position. - * If the position is invalid a JmeException is thrown. - * - * @param i the row index. - * @param j the colum index. - * @return the value at (i, j). - */ - @SuppressWarnings("fallthrough") - public float get(int i, int j) { - switch (i) { - case 0: - switch (j) { - case 0: - return m00; - case 1: - return m01; - case 2: - return m02; - case 3: - return m03; - } - case 1: - switch (j) { - case 0: - return m10; - case 1: - return m11; - case 2: - return m12; - case 3: - return m13; - } - case 2: - switch (j) { - case 0: - return m20; - case 1: - return m21; - case 2: - return m22; - case 3: - return m23; - } - case 3: - switch (j) { - case 0: - return m30; - case 1: - return m31; - case 2: - return m32; - case 3: - return m33; - } - } - - logger.warning("Invalid matrix index."); - throw new IllegalArgumentException("Invalid indices into matrix."); - } - - /** - * getColumn returns one of three columns specified by the - * parameter. This column is returned as a float array of length 4. - * - * @param i the column to retrieve. Must be between 0 and 3. - * @return the column specified by the index. - */ - public float[] getColumn(int i) { - return getColumn(i, null); - } - - /** - * getColumn returns one of three columns specified by the - * parameter. This column is returned as a float[4]. - * - * @param i the column to retrieve. Must be between 0 and 3. - * @param store the float array to store the result in. if null, a new one - * is created. - * @return the column specified by the index. - */ - public float[] getColumn(int i, float[] store) { - if (store == null) { - store = new float[4]; - } - switch (i) { - case 0: - store[0] = m00; - store[1] = m10; - store[2] = m20; - store[3] = m30; - break; - case 1: - store[0] = m01; - store[1] = m11; - store[2] = m21; - store[3] = m31; - break; - case 2: - store[0] = m02; - store[1] = m12; - store[2] = m22; - store[3] = m32; - break; - case 3: - store[0] = m03; - store[1] = m13; - store[2] = m23; - store[3] = m33; - break; - default: - logger.warning("Invalid column index."); - throw new IllegalArgumentException("Invalid column index. " + i); - } - return store; - } - - /** - * - * setColumn sets a particular column of this matrix to that - * represented by the provided vector. - * - * @param i the column to set. - * @param column the data to set. - */ - public void setColumn(int i, float[] column) { - - if (column == null) { - logger.warning("Column is null. Ignoring."); - return; - } - switch (i) { - case 0: - m00 = column[0]; - m10 = column[1]; - m20 = column[2]; - m30 = column[3]; - break; - case 1: - m01 = column[0]; - m11 = column[1]; - m21 = column[2]; - m31 = column[3]; - break; - case 2: - m02 = column[0]; - m12 = column[1]; - m22 = column[2]; - m32 = column[3]; - break; - case 3: - m03 = column[0]; - m13 = column[1]; - m23 = column[2]; - m33 = column[3]; - break; - default: - logger.warning("Invalid column index."); - throw new IllegalArgumentException("Invalid column index. " + i); - } - } - - /** - * set places a given value into the matrix at the given - * position. If the position is invalid a JmeException is - * thrown. - * - * @param i the row index. - * @param j the colum index. - * @param value the value for (i, j). - */ - @SuppressWarnings("fallthrough") - public void set(int i, int j, float value) { - switch (i) { - case 0: - switch (j) { - case 0: - m00 = value; - return; - case 1: - m01 = value; - return; - case 2: - m02 = value; - return; - case 3: - m03 = value; - return; - } - case 1: - switch (j) { - case 0: - m10 = value; - return; - case 1: - m11 = value; - return; - case 2: - m12 = value; - return; - case 3: - m13 = value; - return; - } - case 2: - switch (j) { - case 0: - m20 = value; - return; - case 1: - m21 = value; - return; - case 2: - m22 = value; - return; - case 3: - m23 = value; - return; - } - case 3: - switch (j) { - case 0: - m30 = value; - return; - case 1: - m31 = value; - return; - case 2: - m32 = value; - return; - case 3: - m33 = value; - return; - } - } - - logger.warning("Invalid matrix index."); - throw new IllegalArgumentException("Invalid indices into matrix."); - } - - /** - * set sets the values of this matrix from an array of values. - * - * @param matrix the matrix to set the value to. - * @throws JmeException if the array is not of size 16. - */ - public void set(float[][] matrix) { - if (matrix.length != 4 || matrix[0].length != 4) { - throw new IllegalArgumentException( - "Array must be of size 16." - ); - } - - m00 = matrix[0][0]; - m01 = matrix[0][1]; - m02 = matrix[0][2]; - m03 = matrix[0][3]; - m10 = matrix[1][0]; - m11 = matrix[1][1]; - m12 = matrix[1][2]; - m13 = matrix[1][3]; - m20 = matrix[2][0]; - m21 = matrix[2][1]; - m22 = matrix[2][2]; - m23 = matrix[2][3]; - m30 = matrix[3][0]; - m31 = matrix[3][1]; - m32 = matrix[3][2]; - m33 = matrix[3][3]; - } - - - /** - * Sets the values of this matrix - */ - public void set( - float m00, - float m01, - float m02, - float m03, - float m10, - float m11, - float m12, - float m13, - float m20, - float m21, - float m22, - float m23, - float m30, - float m31, - float m32, - float m33 - ) { - - this.m00 = m00; - this.m01 = m01; - this.m02 = m02; - this.m03 = m03; - this.m10 = m10; - this.m11 = m11; - this.m12 = m12; - this.m13 = m13; - this.m20 = m20; - this.m21 = m21; - this.m22 = m22; - this.m23 = m23; - this.m30 = m30; - this.m31 = m31; - this.m32 = m32; - this.m33 = m33; - } - - /** - * set sets the values of this matrix from another matrix. - * - * @param matrix the matrix to read the value from. - */ - public Matrix4f set(Matrix4f matrix) { - m00 = matrix.m00; - m01 = matrix.m01; - m02 = matrix.m02; - m03 = matrix.m03; - m10 = matrix.m10; - m11 = matrix.m11; - m12 = matrix.m12; - m13 = matrix.m13; - m20 = matrix.m20; - m21 = matrix.m21; - m22 = matrix.m22; - m23 = matrix.m23; - m30 = matrix.m30; - m31 = matrix.m31; - m32 = matrix.m32; - m33 = matrix.m33; - return this; - } - - /** - * set sets the values of this matrix from an array of values - * assuming that the data is rowMajor order; - * - * @param matrix the matrix to set the value to. - */ - public void set(float[] matrix) { - set(matrix, true); - } - - /** - * set sets the values of this matrix from an array of values; - * - * @param matrix the matrix to set the value to. - * @param rowMajor whether the incoming data is in row or column major - * order. - */ - public void set(float[] matrix, boolean rowMajor) { - if (matrix.length != 16) { - throw new IllegalArgumentException( - "Array must be of size 16." - ); - } - - if (rowMajor) { - m00 = matrix[0]; - m01 = matrix[1]; - m02 = matrix[2]; - m03 = matrix[3]; - m10 = matrix[4]; - m11 = matrix[5]; - m12 = matrix[6]; - m13 = matrix[7]; - m20 = matrix[8]; - m21 = matrix[9]; - m22 = matrix[10]; - m23 = matrix[11]; - m30 = matrix[12]; - m31 = matrix[13]; - m32 = matrix[14]; - m33 = matrix[15]; - } else { - m00 = matrix[0]; - m01 = matrix[4]; - m02 = matrix[8]; - m03 = matrix[12]; - m10 = matrix[1]; - m11 = matrix[5]; - m12 = matrix[9]; - m13 = matrix[13]; - m20 = matrix[2]; - m21 = matrix[6]; - m22 = matrix[10]; - m23 = matrix[14]; - m30 = matrix[3]; - m31 = matrix[7]; - m32 = matrix[11]; - m33 = matrix[15]; - } - } - - public Matrix4f transpose() { - float[] tmp = new float[16]; - get(tmp, true); - Matrix4f mat = new Matrix4f(tmp); - return mat; - } - - /** - * transpose locally transposes this Matrix. - * - * @return this object for chaining. - */ - public Matrix4f transposeLocal() { - float tmp = m01; - m01 = m10; - m10 = tmp; - - tmp = m02; - m02 = m20; - m20 = tmp; - - tmp = m03; - m03 = m30; - m30 = tmp; - - tmp = m12; - m12 = m21; - m21 = tmp; - - tmp = m13; - m13 = m31; - m31 = tmp; - - tmp = m23; - m23 = m32; - m32 = tmp; - - return this; - } - - /** - * fillFloatBuffer fills a FloatBuffer object with the matrix - * data. - * - * @param fb the buffer to fill, must be correct size - * @return matrix data as a FloatBuffer. - */ - public FloatBuffer fillFloatBuffer(FloatBuffer fb) { - return fillFloatBuffer(fb, false); - } - - /** - * fillFloatBuffer fills a FloatBuffer object with the matrix - * data. - * - * @param fb the buffer to fill, starting at current position. Must have - * room for 16 more floats. - * @param columnMajor if true, this buffer should be filled with column - * major data, otherwise it will be filled row major. - * @return matrix data as a FloatBuffer. (position is advanced by 16 and any - * limit set is not changed). - */ - public FloatBuffer fillFloatBuffer(FloatBuffer fb, boolean columnMajor) { -// if (columnMajor) { -// fb.put(m00).put(m10).put(m20).put(m30); -// fb.put(m01).put(m11).put(m21).put(m31); -// fb.put(m02).put(m12).put(m22).put(m32); -// fb.put(m03).put(m13).put(m23).put(m33); -// } else { -// fb.put(m00).put(m01).put(m02).put(m03); -// fb.put(m10).put(m11).put(m12).put(m13); -// fb.put(m20).put(m21).put(m22).put(m23); -// fb.put(m30).put(m31).put(m32).put(m33); -// } - - TempVars vars = TempVars.get(); - - - fillFloatArray(vars.matrixWrite, columnMajor); - fb.put(vars.matrixWrite, 0, 16); - - vars.release(); - - return fb; - } - - public void fillFloatArray(float[] f, boolean columnMajor) { - if (columnMajor) { - f[0] = m00; - f[1] = m10; - f[2] = m20; - f[3] = m30; - f[4] = m01; - f[5] = m11; - f[6] = m21; - f[7] = m31; - f[8] = m02; - f[9] = m12; - f[10] = m22; - f[11] = m32; - f[12] = m03; - f[13] = m13; - f[14] = m23; - f[15] = m33; - } else { - f[0] = m00; - f[1] = m01; - f[2] = m02; - f[3] = m03; - f[4] = m10; - f[5] = m11; - f[6] = m12; - f[7] = m13; - f[8] = m20; - f[9] = m21; - f[10] = m22; - f[11] = m23; - f[12] = m30; - f[13] = m31; - f[14] = m32; - f[15] = m33; - } - } - - /** - * readFloatBuffer reads value for this matrix from a - * FloatBuffer. - * - * @param fb the buffer to read from, must be correct size - * @return this data as a FloatBuffer. - */ - public Matrix4f readFloatBuffer(FloatBuffer fb) { - return readFloatBuffer(fb, false); - } - - /** - * readFloatBuffer reads value for this matrix from a - * FloatBuffer. - * - * @param fb the buffer to read from, must be correct size - * @param columnMajor if true, this buffer should be filled with column - * major data, otherwise it will be filled row major. - * @return this data as a FloatBuffer. - */ - public Matrix4f readFloatBuffer(FloatBuffer fb, boolean columnMajor) { - - if (columnMajor) { - m00 = fb.get(); - m10 = fb.get(); - m20 = fb.get(); - m30 = fb.get(); - m01 = fb.get(); - m11 = fb.get(); - m21 = fb.get(); - m31 = fb.get(); - m02 = fb.get(); - m12 = fb.get(); - m22 = fb.get(); - m32 = fb.get(); - m03 = fb.get(); - m13 = fb.get(); - m23 = fb.get(); - m33 = fb.get(); - } else { - m00 = fb.get(); - m01 = fb.get(); - m02 = fb.get(); - m03 = fb.get(); - m10 = fb.get(); - m11 = fb.get(); - m12 = fb.get(); - m13 = fb.get(); - m20 = fb.get(); - m21 = fb.get(); - m22 = fb.get(); - m23 = fb.get(); - m30 = fb.get(); - m31 = fb.get(); - m32 = fb.get(); - m33 = fb.get(); - } - return this; - } - - /** - * loadIdentity sets this matrix to the identity matrix, namely - * all zeros with ones along the diagonal. - * - */ - public void loadIdentity() { - m01 = m02 = m03 = 0.0f; - m10 = m12 = m13 = 0.0f; - m20 = m21 = m23 = 0.0f; - m30 = m31 = m32 = 0.0f; - m00 = m11 = m22 = m33 = 1.0f; - } - - public void fromFrustum( - float near, - float far, - float left, - float right, - float top, - float bottom, - boolean parallel - ) { - loadIdentity(); - if (parallel) { - // scale - m00 = 2.0f / (right - left); - // m11 = 2.0f / (bottom - top); - m11 = 2.0f / (top - bottom); - m22 = -2.0f / (far - near); - m33 = 1f; - - // translation - m03 = -(right + left) / (right - left); - // m31 = -(bottom + top) / (bottom - top); - m13 = -(top + bottom) / (top - bottom); - m23 = -(far + near) / (far - near); - } else { - m00 = (2.0f * near) / (right - left); - m11 = (2.0f * near) / (top - bottom); - m32 = -1.0f; - m33 = -0.0f; - - // A - m02 = (right + left) / (right - left); - - // B - m12 = (top + bottom) / (top - bottom); - - // C - m22 = -(far + near) / (far - near); - - // D - m23 = -(2.0f * far * near) / (far - near); - } - } - - /** - * fromAngleAxis sets this matrix4f to the values specified by - * an angle and an axis of rotation. This method creates an object, so use - * fromAngleNormalAxis if your axis is already normalized. - * - * @param angle the angle to rotate (in radians). - * @param axis the axis of rotation. - */ - public void fromAngleAxis(float angle, Vector3f axis) { - Vector3f normAxis = axis.normalize(); - fromAngleNormalAxis(angle, normAxis); - } - - /** - * fromAngleNormalAxis sets this matrix4f to the values - * specified by an angle and a normalized axis of rotation. - * - * @param angle the angle to rotate (in radians). - * @param axis the axis of rotation (already normalized). - */ - public void fromAngleNormalAxis(float angle, Vector3f axis) { - zero(); - m33 = 1; - - float fCos = FastMath.cos(angle); - float fSin = FastMath.sin(angle); - float fOneMinusCos = ((float) 1.0) - fCos; - float fX2 = axis.x * axis.x; - float fY2 = axis.y * axis.y; - float fZ2 = axis.z * axis.z; - float fXYM = axis.x * axis.y * fOneMinusCos; - float fXZM = axis.x * axis.z * fOneMinusCos; - float fYZM = axis.y * axis.z * fOneMinusCos; - float fXSin = axis.x * fSin; - float fYSin = axis.y * fSin; - float fZSin = axis.z * fSin; - - m00 = fX2 * fOneMinusCos + fCos; - m01 = fXYM - fZSin; - m02 = fXZM + fYSin; - m10 = fXYM + fZSin; - m11 = fY2 * fOneMinusCos + fCos; - m12 = fYZM - fXSin; - m20 = fXZM - fYSin; - m21 = fYZM + fXSin; - m22 = fZ2 * fOneMinusCos + fCos; - } - - /** - * mult multiplies this matrix by a scalar. - * - * @param scalar the scalar to multiply this matrix by. - */ - public void multLocal(float scalar) { - m00 *= scalar; - m01 *= scalar; - m02 *= scalar; - m03 *= scalar; - m10 *= scalar; - m11 *= scalar; - m12 *= scalar; - m13 *= scalar; - m20 *= scalar; - m21 *= scalar; - m22 *= scalar; - m23 *= scalar; - m30 *= scalar; - m31 *= scalar; - m32 *= scalar; - m33 *= scalar; - } - - public Matrix4f mult(float scalar) { - Matrix4f out = new Matrix4f(); - out.set(this); - out.multLocal(scalar); - return out; - } - - public Matrix4f mult(float scalar, Matrix4f store) { - store.set(this); - store.multLocal(scalar); - return store; - } - - /** - * mult multiplies this matrix with another matrix. The result - * matrix will then be returned. This matrix will be on the left hand side, - * while the parameter matrix will be on the right. - * - * @param in2 the matrix to multiply this matrix by. - * @return the resultant matrix - */ - public Matrix4f mult(Matrix4f in2) { - return mult(in2, null); - } - - /** - * mult multiplies this matrix with another matrix. The result - * matrix will then be returned. This matrix will be on the left hand side, - * while the parameter matrix will be on the right. - * - * @param in2 the matrix to multiply this matrix by. - * @param store where to store the result. It is safe for in2 and store to - * be the same object. - * @return the resultant matrix - */ - public Matrix4f mult(Matrix4f in2, Matrix4f store) { - if (store == null) { - store = new Matrix4f(); - } - - float temp00, temp01, temp02, temp03; - float temp10, temp11, temp12, temp13; - float temp20, temp21, temp22, temp23; - float temp30, temp31, temp32, temp33; - - temp00 = m00 * in2.m00 - + m01 * in2.m10 - + m02 * in2.m20 - + m03 * in2.m30; - temp01 = m00 * in2.m01 - + m01 * in2.m11 - + m02 * in2.m21 - + m03 * in2.m31; - temp02 = m00 * in2.m02 - + m01 * in2.m12 - + m02 * in2.m22 - + m03 * in2.m32; - temp03 = m00 * in2.m03 - + m01 * in2.m13 - + m02 * in2.m23 - + m03 * in2.m33; - - temp10 = m10 * in2.m00 - + m11 * in2.m10 - + m12 * in2.m20 - + m13 * in2.m30; - temp11 = m10 * in2.m01 - + m11 * in2.m11 - + m12 * in2.m21 - + m13 * in2.m31; - temp12 = m10 * in2.m02 - + m11 * in2.m12 - + m12 * in2.m22 - + m13 * in2.m32; - temp13 = m10 * in2.m03 - + m11 * in2.m13 - + m12 * in2.m23 - + m13 * in2.m33; - - temp20 = m20 * in2.m00 - + m21 * in2.m10 - + m22 * in2.m20 - + m23 * in2.m30; - temp21 = m20 * in2.m01 - + m21 * in2.m11 - + m22 * in2.m21 - + m23 * in2.m31; - temp22 = m20 * in2.m02 - + m21 * in2.m12 - + m22 * in2.m22 - + m23 * in2.m32; - temp23 = m20 * in2.m03 - + m21 * in2.m13 - + m22 * in2.m23 - + m23 * in2.m33; - - temp30 = m30 * in2.m00 - + m31 * in2.m10 - + m32 * in2.m20 - + m33 * in2.m30; - temp31 = m30 * in2.m01 - + m31 * in2.m11 - + m32 * in2.m21 - + m33 * in2.m31; - temp32 = m30 * in2.m02 - + m31 * in2.m12 - + m32 * in2.m22 - + m33 * in2.m32; - temp33 = m30 * in2.m03 - + m31 * in2.m13 - + m32 * in2.m23 - + m33 * in2.m33; - - store.m00 = temp00; - store.m01 = temp01; - store.m02 = temp02; - store.m03 = temp03; - store.m10 = temp10; - store.m11 = temp11; - store.m12 = temp12; - store.m13 = temp13; - store.m20 = temp20; - store.m21 = temp21; - store.m22 = temp22; - store.m23 = temp23; - store.m30 = temp30; - store.m31 = temp31; - store.m32 = temp32; - store.m33 = temp33; - - return store; - } - - /** - * mult multiplies this matrix with another matrix. The results - * are stored internally and a handle to this matrix will then be returned. - * This matrix will be on the left hand side, while the parameter matrix - * will be on the right. - * - * @param in2 the matrix to multiply this matrix by. - * @return the resultant matrix - */ - public Matrix4f multLocal(Matrix4f in2) { - return mult(in2, this); - } - - /** - * mult multiplies a vector about a rotation matrix. The - * resulting vector is returned as a new Vector3f. - * - * @param vec vec to multiply against. - * @return the rotated vector. - */ - public Vector3f mult(Vector3f vec) { - return mult(vec, null); - } - - /** - * mult multiplies a vector about a rotation matrix and adds - * translation. The resulting vector is returned. - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. Created if null is passed. - * @return the rotated vector. - */ - public Vector3f mult(Vector3f vec, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - - float vx = vec.x, vy = vec.y, vz = vec.z; - store.x = m00 * vx + m01 * vy + m02 * vz + m03; - store.y = m10 * vx + m11 * vy + m12 * vz + m13; - store.z = m20 * vx + m21 * vy + m22 * vz + m23; - - return store; - } - - /** - * mult multiplies a Vector4f about a rotation - * matrix. The resulting vector is returned as a new Vector4f. - * - * @param vec vec to multiply against. - * @return the rotated vector. - */ - public Vector4f mult(Vector4f vec) { - return mult(vec, null); - } - - /** - * mult multiplies a Vector4f about a rotation - * matrix. The resulting vector is returned. - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. Created if null is passed. - * @return the rotated vector. - */ - public Vector4f mult(Vector4f vec, Vector4f store) { - if (null == vec) { - logger.warning("Source vector is null, null result returned."); - return null; - } - if (store == null) { - store = new Vector4f(); - } - - float vx = vec.x, vy = vec.y, vz = vec.z, vw = vec.w; - store.x = m00 * vx + m01 * vy + m02 * vz + m03 * vw; - store.y = m10 * vx + m11 * vy + m12 * vz + m13 * vw; - store.z = m20 * vx + m21 * vy + m22 * vz + m23 * vw; - store.w = m30 * vx + m31 * vy + m32 * vz + m33 * vw; - - return store; - } - - /** - * mult multiplies a vector about a rotation matrix. The - * resulting vector is returned. - * - * @param vec vec to multiply against. - * - * @return the rotated vector. - */ - public Vector4f multAcross(Vector4f vec) { - return multAcross(vec, null); - } - - /** - * mult multiplies a vector about a rotation matrix. The - * resulting vector is returned. - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. created if null is passed. - * @return the rotated vector. - */ - public Vector4f multAcross(Vector4f vec, Vector4f store) { - if (null == vec) { - logger.warning("Source vector is null, null result returned."); - return null; - } - if (store == null) { - store = new Vector4f(); - } - - float vx = vec.x, vy = vec.y, vz = vec.z, vw = vec.w; - store.x = m00 * vx + m10 * vy + m20 * vz + m30 * vw; - store.y = m01 * vx + m11 * vy + m21 * vz + m31 * vw; - store.z = m02 * vx + m12 * vy + m22 * vz + m32 * vw; - store.w = m03 * vx + m13 * vy + m23 * vz + m33 * vw; - - return store; - } - - /** - * multNormal multiplies a vector about a rotation matrix, but - * does not add translation. The resulting vector is returned. - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. Created if null is passed. - * @return the rotated vector. - */ - public Vector3f multNormal(Vector3f vec, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - - float vx = vec.x, vy = vec.y, vz = vec.z; - store.x = m00 * vx + m01 * vy + m02 * vz; - store.y = m10 * vx + m11 * vy + m12 * vz; - store.z = m20 * vx + m21 * vy + m22 * vz; - - return store; - } - - /** - * multNormal multiplies a vector about a rotation matrix, but - * does not add translation. The resulting vector is returned. - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. Created if null is passed. - * @return the rotated vector. - */ - public Vector3f multNormalAcross(Vector3f vec, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - - float vx = vec.x, vy = vec.y, vz = vec.z; - store.x = m00 * vx + m10 * vy + m20 * vz; - store.y = m01 * vx + m11 * vy + m21 * vz; - store.z = m02 * vx + m12 * vy + m22 * vz; - - return store; - } - - /** - * mult multiplies a vector about a rotation matrix and adds - * translation. The w value is returned as a result of multiplying the last - * column of the matrix by 1.0 - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. - * @return the W value - */ - public float multProj(Vector3f vec, Vector3f store) { - float vx = vec.x, vy = vec.y, vz = vec.z; - store.x = m00 * vx + m01 * vy + m02 * vz + m03; - store.y = m10 * vx + m11 * vy + m12 * vz + m13; - store.z = m20 * vx + m21 * vy + m22 * vz + m23; - return m30 * vx + m31 * vy + m32 * vz + m33; - } - - /** - * mult multiplies a vector about a rotation matrix. The - * resulting vector is returned. - * - * @param vec vec to multiply against. - * @param store a vector to store the result in. created if null is passed. - * @return the rotated vector. - */ - public Vector3f multAcross(Vector3f vec, Vector3f store) { - if (null == vec) { - logger.warning("Source vector is null, null result returned."); - return null; - } - if (store == null) { - store = new Vector3f(); - } - - float vx = vec.x, vy = vec.y, vz = vec.z; - store.x = m00 * vx + m10 * vy + m20 * vz + m30 * 1; - store.y = m01 * vx + m11 * vy + m21 * vz + m31 * 1; - store.z = m02 * vx + m12 * vy + m22 * vz + m32 * 1; - - return store; - } - - /** - * mult multiplies a quaternion about a matrix. The resulting - * vector is returned. - * - * @param vec vec to multiply against. - * @param store a quaternion to store the result in. created if null is - * passed. - * @return store = this * vec - */ - public Quaternion mult(Quaternion vec, Quaternion store) { - - if (null == vec) { - logger.warning("Source vector is null, null result returned."); - return null; - } - if (store == null) { - store = new Quaternion(); - } - - float x = m00 * vec.x + m10 * vec.y + m20 * vec.z + m30 * vec.w; - float y = m01 * vec.x + m11 * vec.y + m21 * vec.z + m31 * vec.w; - float z = m02 * vec.x + m12 * vec.y + m22 * vec.z + m32 * vec.w; - float w = m03 * vec.x + m13 * vec.y + m23 * vec.z + m33 * vec.w; - store.x = x; - store.y = y; - store.z = z; - store.w = w; - - return store; - } - - /** - * mult multiplies an array of 4 floats against this rotation - * matrix. The results are stored directly in the array. (vec4f x mat4f) - * - * @param vec4f float array (size 4) to multiply against the matrix. - * @return the vec4f for chaining. - */ - public float[] mult(float[] vec4f) { - if (null == vec4f || vec4f.length != 4) { - logger.warning("invalid array given, must be nonnull and length 4"); - return null; - } - - float x = vec4f[0], y = vec4f[1], z = vec4f[2], w = vec4f[3]; - - vec4f[0] = m00 * x + m01 * y + m02 * z + m03 * w; - vec4f[1] = m10 * x + m11 * y + m12 * z + m13 * w; - vec4f[2] = m20 * x + m21 * y + m22 * z + m23 * w; - vec4f[3] = m30 * x + m31 * y + m32 * z + m33 * w; - - return vec4f; - } - - /** - * mult multiplies an array of 4 floats against this rotation - * matrix. The results are stored directly in the array. (vec4f x mat4f) - * - * @param vec4f float array (size 4) to multiply against the matrix. - * @return the vec4f for chaining. - */ - public float[] multAcross(float[] vec4f) { - if (null == vec4f || vec4f.length != 4) { - logger.warning("invalid array given, must be nonnull and length 4"); - return null; - } - - float x = vec4f[0], y = vec4f[1], z = vec4f[2], w = vec4f[3]; - - vec4f[0] = m00 * x + m10 * y + m20 * z + m30 * w; - vec4f[1] = m01 * x + m11 * y + m21 * z + m31 * w; - vec4f[2] = m02 * x + m12 * y + m22 * z + m32 * w; - vec4f[3] = m03 * x + m13 * y + m23 * z + m33 * w; - - return vec4f; - } - - /** - * Inverts this matrix as a new Matrix4f. - * - * @return The new inverse matrix - */ - public Matrix4f invert() { - return invert(null); - } - - /** - * Inverts this matrix and stores it in the given store. - * - * @return The store - */ - public Matrix4f invert(Matrix4f store) { - if (store == null) { - store = new Matrix4f(); - } - - float fA0 = m00 * m11 - m01 * m10; - float fA1 = m00 * m12 - m02 * m10; - float fA2 = m00 * m13 - m03 * m10; - float fA3 = m01 * m12 - m02 * m11; - float fA4 = m01 * m13 - m03 * m11; - float fA5 = m02 * m13 - m03 * m12; - float fB0 = m20 * m31 - m21 * m30; - float fB1 = m20 * m32 - m22 * m30; - float fB2 = m20 * m33 - m23 * m30; - float fB3 = m21 * m32 - m22 * m31; - float fB4 = m21 * m33 - m23 * m31; - float fB5 = m22 * m33 - m23 * m32; - float fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - - if (FastMath.abs(fDet) <= 0f) { - throw new ArithmeticException("This matrix cannot be inverted"); - } - - store.m00 = +m11 * fB5 - m12 * fB4 + m13 * fB3; - store.m10 = -m10 * fB5 + m12 * fB2 - m13 * fB1; - store.m20 = +m10 * fB4 - m11 * fB2 + m13 * fB0; - store.m30 = -m10 * fB3 + m11 * fB1 - m12 * fB0; - store.m01 = -m01 * fB5 + m02 * fB4 - m03 * fB3; - store.m11 = +m00 * fB5 - m02 * fB2 + m03 * fB1; - store.m21 = -m00 * fB4 + m01 * fB2 - m03 * fB0; - store.m31 = +m00 * fB3 - m01 * fB1 + m02 * fB0; - store.m02 = +m31 * fA5 - m32 * fA4 + m33 * fA3; - store.m12 = -m30 * fA5 + m32 * fA2 - m33 * fA1; - store.m22 = +m30 * fA4 - m31 * fA2 + m33 * fA0; - store.m32 = -m30 * fA3 + m31 * fA1 - m32 * fA0; - store.m03 = -m21 * fA5 + m22 * fA4 - m23 * fA3; - store.m13 = +m20 * fA5 - m22 * fA2 + m23 * fA1; - store.m23 = -m20 * fA4 + m21 * fA2 - m23 * fA0; - store.m33 = +m20 * fA3 - m21 * fA1 + m22 * fA0; - - float fInvDet = 1.0f / fDet; - store.multLocal(fInvDet); - - return store; - } - - /** - * Inverts this matrix locally. - * - * @return this - */ - public Matrix4f invertLocal() { - - float fA0 = m00 * m11 - m01 * m10; - float fA1 = m00 * m12 - m02 * m10; - float fA2 = m00 * m13 - m03 * m10; - float fA3 = m01 * m12 - m02 * m11; - float fA4 = m01 * m13 - m03 * m11; - float fA5 = m02 * m13 - m03 * m12; - float fB0 = m20 * m31 - m21 * m30; - float fB1 = m20 * m32 - m22 * m30; - float fB2 = m20 * m33 - m23 * m30; - float fB3 = m21 * m32 - m22 * m31; - float fB4 = m21 * m33 - m23 * m31; - float fB5 = m22 * m33 - m23 * m32; - float fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - - if (FastMath.abs(fDet) <= 0f) { - return zero(); - } - - float f00 = +m11 * fB5 - m12 * fB4 + m13 * fB3; - float f10 = -m10 * fB5 + m12 * fB2 - m13 * fB1; - float f20 = +m10 * fB4 - m11 * fB2 + m13 * fB0; - float f30 = -m10 * fB3 + m11 * fB1 - m12 * fB0; - float f01 = -m01 * fB5 + m02 * fB4 - m03 * fB3; - float f11 = +m00 * fB5 - m02 * fB2 + m03 * fB1; - float f21 = -m00 * fB4 + m01 * fB2 - m03 * fB0; - float f31 = +m00 * fB3 - m01 * fB1 + m02 * fB0; - float f02 = +m31 * fA5 - m32 * fA4 + m33 * fA3; - float f12 = -m30 * fA5 + m32 * fA2 - m33 * fA1; - float f22 = +m30 * fA4 - m31 * fA2 + m33 * fA0; - float f32 = -m30 * fA3 + m31 * fA1 - m32 * fA0; - float f03 = -m21 * fA5 + m22 * fA4 - m23 * fA3; - float f13 = +m20 * fA5 - m22 * fA2 + m23 * fA1; - float f23 = -m20 * fA4 + m21 * fA2 - m23 * fA0; - float f33 = +m20 * fA3 - m21 * fA1 + m22 * fA0; - - m00 = f00; - m01 = f01; - m02 = f02; - m03 = f03; - m10 = f10; - m11 = f11; - m12 = f12; - m13 = f13; - m20 = f20; - m21 = f21; - m22 = f22; - m23 = f23; - m30 = f30; - m31 = f31; - m32 = f32; - m33 = f33; - - float fInvDet = 1.0f / fDet; - multLocal(fInvDet); - - return this; - } - - /** - * Returns a new matrix representing the adjoint of this matrix. - * - * @return The adjoint matrix - */ - public Matrix4f adjoint() { - return adjoint(null); - } - - public void setTransform(Vector3f position, Vector3f scale, Matrix3f rotMat) { - // Ordering: - // 1. Scale - // 2. Rotate - // 3. Translate - - // Set up final matrix with scale, rotation and translation - m00 = scale.x * rotMat.m00; - m01 = scale.y * rotMat.m01; - m02 = scale.z * rotMat.m02; - m03 = position.x; - m10 = scale.x * rotMat.m10; - m11 = scale.y * rotMat.m11; - m12 = scale.z * rotMat.m12; - m13 = position.y; - m20 = scale.x * rotMat.m20; - m21 = scale.y * rotMat.m21; - m22 = scale.z * rotMat.m22; - m23 = position.z; - - // No projection term - m30 = 0; - m31 = 0; - m32 = 0; - m33 = 1; - } - - /** - * Places the adjoint of this matrix in store (creates store if null.) - * - * @param store The matrix to store the result in. If null, a new matrix is - * created. - * @return store - */ - public Matrix4f adjoint(Matrix4f store) { - if (store == null) { - store = new Matrix4f(); - } - - float fA0 = m00 * m11 - m01 * m10; - float fA1 = m00 * m12 - m02 * m10; - float fA2 = m00 * m13 - m03 * m10; - float fA3 = m01 * m12 - m02 * m11; - float fA4 = m01 * m13 - m03 * m11; - float fA5 = m02 * m13 - m03 * m12; - float fB0 = m20 * m31 - m21 * m30; - float fB1 = m20 * m32 - m22 * m30; - float fB2 = m20 * m33 - m23 * m30; - float fB3 = m21 * m32 - m22 * m31; - float fB4 = m21 * m33 - m23 * m31; - float fB5 = m22 * m33 - m23 * m32; - - store.m00 = +m11 * fB5 - m12 * fB4 + m13 * fB3; - store.m10 = -m10 * fB5 + m12 * fB2 - m13 * fB1; - store.m20 = +m10 * fB4 - m11 * fB2 + m13 * fB0; - store.m30 = -m10 * fB3 + m11 * fB1 - m12 * fB0; - store.m01 = -m01 * fB5 + m02 * fB4 - m03 * fB3; - store.m11 = +m00 * fB5 - m02 * fB2 + m03 * fB1; - store.m21 = -m00 * fB4 + m01 * fB2 - m03 * fB0; - store.m31 = +m00 * fB3 - m01 * fB1 + m02 * fB0; - store.m02 = +m31 * fA5 - m32 * fA4 + m33 * fA3; - store.m12 = -m30 * fA5 + m32 * fA2 - m33 * fA1; - store.m22 = +m30 * fA4 - m31 * fA2 + m33 * fA0; - store.m32 = -m30 * fA3 + m31 * fA1 - m32 * fA0; - store.m03 = -m21 * fA5 + m22 * fA4 - m23 * fA3; - store.m13 = +m20 * fA5 - m22 * fA2 + m23 * fA1; - store.m23 = -m20 * fA4 + m21 * fA2 - m23 * fA0; - store.m33 = +m20 * fA3 - m21 * fA1 + m22 * fA0; - - return store; - } - - /** - * determinant generates the determinate of this matrix. - * - * @return the determinate - */ - public float determinant() { - float fA0 = m00 * m11 - m01 * m10; - float fA1 = m00 * m12 - m02 * m10; - float fA2 = m00 * m13 - m03 * m10; - float fA3 = m01 * m12 - m02 * m11; - float fA4 = m01 * m13 - m03 * m11; - float fA5 = m02 * m13 - m03 * m12; - float fB0 = m20 * m31 - m21 * m30; - float fB1 = m20 * m32 - m22 * m30; - float fB2 = m20 * m33 - m23 * m30; - float fB3 = m21 * m32 - m22 * m31; - float fB4 = m21 * m33 - m23 * m31; - float fB5 = m22 * m33 - m23 * m32; - float fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; - return fDet; - } - - /** - * Sets all of the values in this matrix to zero. - * - * @return this matrix - */ - public Matrix4f zero() { - m00 = m01 = m02 = m03 = 0.0f; - m10 = m11 = m12 = m13 = 0.0f; - m20 = m21 = m22 = m23 = 0.0f; - m30 = m31 = m32 = m33 = 0.0f; - return this; - } - - public Matrix4f add(Matrix4f mat) { - Matrix4f result = new Matrix4f(); - result.m00 = this.m00 + mat.m00; - result.m01 = this.m01 + mat.m01; - result.m02 = this.m02 + mat.m02; - result.m03 = this.m03 + mat.m03; - result.m10 = this.m10 + mat.m10; - result.m11 = this.m11 + mat.m11; - result.m12 = this.m12 + mat.m12; - result.m13 = this.m13 + mat.m13; - result.m20 = this.m20 + mat.m20; - result.m21 = this.m21 + mat.m21; - result.m22 = this.m22 + mat.m22; - result.m23 = this.m23 + mat.m23; - result.m30 = this.m30 + mat.m30; - result.m31 = this.m31 + mat.m31; - result.m32 = this.m32 + mat.m32; - result.m33 = this.m33 + mat.m33; - return result; - } - - /** - * add adds the values of a parameter matrix to this matrix. - * - * @param mat the matrix to add to this. - */ - public void addLocal(Matrix4f mat) { - m00 += mat.m00; - m01 += mat.m01; - m02 += mat.m02; - m03 += mat.m03; - m10 += mat.m10; - m11 += mat.m11; - m12 += mat.m12; - m13 += mat.m13; - m20 += mat.m20; - m21 += mat.m21; - m22 += mat.m22; - m23 += mat.m23; - m30 += mat.m30; - m31 += mat.m31; - m32 += mat.m32; - m33 += mat.m33; - } - - public Vector3f toTranslationVector() { - return new Vector3f(m03, m13, m23); - } - - public void toTranslationVector(Vector3f vector) { - vector.set(m03, m13, m23); - } - - public Quaternion toRotationQuat() { - Quaternion quat = new Quaternion(); - quat.fromRotationMatrix(toRotationMatrix()); - return quat; - } - - public void toRotationQuat(Quaternion q) { - q.fromRotationMatrix(toRotationMatrix()); - } - - public Matrix3f toRotationMatrix() { - return new Matrix3f(m00, m01, m02, m10, m11, m12, m20, m21, m22); - } - - public void toRotationMatrix(Matrix3f mat) { - mat.m00 = m00; - mat.m01 = m01; - mat.m02 = m02; - mat.m10 = m10; - mat.m11 = m11; - mat.m12 = m12; - mat.m20 = m20; - mat.m21 = m21; - mat.m22 = m22; - } - - /** - * Retreives the scale vector from the matrix. - * - * @return the scale vector - */ - public Vector3f toScaleVector() { - Vector3f result = new Vector3f(); - this.toScaleVector(result); - return result; - } - - /** - * Retreives the scale vector from the matrix and stores it into a given - * vector. - * - * @param the vector where the scale will be stored - */ - public void toScaleVector(Vector3f vector) { - float scaleX = (float) Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20); - float scaleY = (float) Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21); - float scaleZ = (float) Math.sqrt(m02 * m02 + m12 * m12 + m22 * m22); - vector.set(scaleX, scaleY, scaleZ); - } - - public void setScale(float x, float y, float z) { - m00 *= x; - m11 *= y; - m22 *= z; - } - - public void setScale(Vector3f scale) { - m00 *= scale.x; - m11 *= scale.y; - m22 *= scale.z; - } - - /** - * setTranslation will set the matrix's translation values. - * - * @param translation the new values for the translation. - * @throws JmeException if translation is not size 3. - */ - public void setTranslation(float[] translation) { - if (translation.length != 3) { - throw new IllegalArgumentException( - "Translation size must be 3." - ); - } - m03 = translation[0]; - m13 = translation[1]; - m23 = translation[2]; - } - - /** - * setTranslation will set the matrix's translation values. - * - * @param x value of the translation on the x axis - * @param y value of the translation on the y axis - * @param z value of the translation on the z axis - */ - public void setTranslation(float x, float y, float z) { - m03 = x; - m13 = y; - m23 = z; - } - - /** - * setTranslation will set the matrix's translation values. - * - * @param translation the new values for the translation. - */ - public void setTranslation(Vector3f translation) { - m03 = translation.x; - m13 = translation.y; - m23 = translation.z; - } - - /** - * setInverseTranslation will set the matrix's inverse - * translation values. - * - * @param translation the new values for the inverse translation. - * @throws JmeException if translation is not size 3. - */ - public void setInverseTranslation(float[] translation) { - if (translation.length != 3) { - throw new IllegalArgumentException( - "Translation size must be 3." - ); - } - m03 = -translation[0]; - m13 = -translation[1]; - m23 = -translation[2]; - } - - /** - * angleRotation sets this matrix to that of a rotation about - * three axes (x, y, z). Where each axis has a specified rotation in - * degrees. These rotations are expressed in a single Vector3f - * object. - * - * @param angles the angles to rotate. - */ - public void angleRotation(Vector3f angles) { - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = (angles.z * FastMath.DEG_TO_RAD); - sy = FastMath.sin(angle); - cy = FastMath.cos(angle); - angle = (angles.y * FastMath.DEG_TO_RAD); - sp = FastMath.sin(angle); - cp = FastMath.cos(angle); - angle = (angles.x * FastMath.DEG_TO_RAD); - sr = FastMath.sin(angle); - cr = FastMath.cos(angle); - - // matrix = (Z * Y) * X - m00 = cp * cy; - m10 = cp * sy; - m20 = -sp; - m01 = sr * sp * cy + cr * -sy; - m11 = sr * sp * sy + cr * cy; - m21 = sr * cp; - m02 = (cr * sp * cy + -sr * -sy); - m12 = (cr * sp * sy + -sr * cy); - m22 = cr * cp; - m03 = 0.0f; - m13 = 0.0f; - m23 = 0.0f; - } - - /** - * setRotationQuaternion builds a rotation from a - * Quaternion. - * - * @param quat the quaternion to build the rotation from. - * @throws NullPointerException if quat is null. - */ - public void setRotationQuaternion(Quaternion quat) { - quat.toRotationMatrix(this); - } - - /** - * setInverseRotationRadians builds an inverted rotation from - * Euler angles that are in radians. - * - * @param angles the Euler angles in radians. - * @throws JmeException if angles is not size 3. - */ - public void setInverseRotationRadians(float[] angles) { - if (angles.length != 3) { - throw new IllegalArgumentException( - "Angles must be of size 3." - ); - } - double cr = FastMath.cos(angles[0]); - double sr = FastMath.sin(angles[0]); - double cp = FastMath.cos(angles[1]); - double sp = FastMath.sin(angles[1]); - double cy = FastMath.cos(angles[2]); - double sy = FastMath.sin(angles[2]); - - m00 = (float) (cp * cy); - m10 = (float) (cp * sy); - m20 = (float) (-sp); - - double srsp = sr * sp; - double crsp = cr * sp; - - m01 = (float) (srsp * cy - cr * sy); - m11 = (float) (srsp * sy + cr * cy); - m21 = (float) (sr * cp); - - m02 = (float) (crsp * cy + sr * sy); - m12 = (float) (crsp * sy - sr * cy); - m22 = (float) (cr * cp); - } - - /** - * setInverseRotationDegrees builds an inverted rotation from - * Euler angles that are in degrees. - * - * @param angles the Euler angles in degrees. - * @throws JmeException if angles is not size 3. - */ - public void setInverseRotationDegrees(float[] angles) { - if (angles.length != 3) { - throw new IllegalArgumentException( - "Angles must be of size 3." - ); - } - float vec[] = new float[3]; - vec[0] = (angles[0] * FastMath.RAD_TO_DEG); - vec[1] = (angles[1] * FastMath.RAD_TO_DEG); - vec[2] = (angles[2] * FastMath.RAD_TO_DEG); - setInverseRotationRadians(vec); - } - - /** - * - * inverseTranslateVect translates a given Vector3f by the - * translation part of this matrix. - * - * @param vec the Vector3f data to be translated. - * @throws JmeException if the size of the Vector3f is not 3. - */ - public void inverseTranslateVect(float[] vec) { - if (vec.length != 3) { - throw new IllegalArgumentException( - "vec must be of size 3." - ); - } - - vec[0] = vec[0] - m03; - vec[1] = vec[1] - m13; - vec[2] = vec[2] - m23; - } - - /** - * - * inverseTranslateVect translates a given Vector3f by the - * translation part of this matrix. - * - * @param data the Vector3f to be translated. - * @throws JmeException if the size of the Vector3f is not 3. - */ - public void inverseTranslateVect(Vector3f data) { - data.x -= m03; - data.y -= m13; - data.z -= m23; - } - - /** - * - * inverseTranslateVect translates a given Vector3f by the - * translation part of this matrix. - * - * @param data the Vector3f to be translated. - * @throws JmeException if the size of the Vector3f is not 3. - */ - public void translateVect(Vector3f data) { - data.x += m03; - data.y += m13; - data.z += m23; - } - - /** - * - * inverseRotateVect rotates a given Vector3f by the rotation - * part of this matrix. - * - * @param vec the Vector3f to be rotated. - */ - public void inverseRotateVect(Vector3f vec) { - float vx = vec.x, vy = vec.y, vz = vec.z; - - vec.x = vx * m00 + vy * m10 + vz * m20; - vec.y = vx * m01 + vy * m11 + vz * m21; - vec.z = vx * m02 + vy * m12 + vz * m22; - } - - public void rotateVect(Vector3f vec) { - float vx = vec.x, vy = vec.y, vz = vec.z; - - vec.x = vx * m00 + vy * m01 + vz * m02; - vec.y = vx * m10 + vy * m11 + vz * m12; - vec.z = vx * m20 + vy * m21 + vz * m22; - } - - /** - * toString returns the string representation of this object. - * It is in a format of a 4x4 matrix. For example, an identity matrix would - * be represented by the following string. com.jme.math.Matrix3f
- * [
- * 1.0 0.0 0.0 0.0
- * 0.0 1.0 0.0 0.0
- * 0.0 0.0 1.0 0.0
- * 0.0 0.0 0.0 1.0
- * ]
- * - * @return the string representation of this object. - */ - @Override - public String toString() { - StringBuilder result = new StringBuilder("Matrix4f\n[\n"); - result.append(" "); - result.append(m00); - result.append(" "); - result.append(m01); - result.append(" "); - result.append(m02); - result.append(" "); - result.append(m03); - result.append(" \n"); - result.append(" "); - result.append(m10); - result.append(" "); - result.append(m11); - result.append(" "); - result.append(m12); - result.append(" "); - result.append(m13); - result.append(" \n"); - result.append(" "); - result.append(m20); - result.append(" "); - result.append(m21); - result.append(" "); - result.append(m22); - result.append(" "); - result.append(m23); - result.append(" \n"); - result.append(" "); - result.append(m30); - result.append(" "); - result.append(m31); - result.append(" "); - result.append(m32); - result.append(" "); - result.append(m33); - result.append(" \n]"); - return result.toString(); - } - - /** - * - * hashCode returns the hash code value as an integer and is - * supported for the benefit of hashing based collection classes such as - * Hashtable, HashMap, HashSet etc. - * - * @return the hashcode for this instance of Matrix4f. - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - int hash = 37; - hash = 37 * hash + Float.floatToIntBits(m00); - hash = 37 * hash + Float.floatToIntBits(m01); - hash = 37 * hash + Float.floatToIntBits(m02); - hash = 37 * hash + Float.floatToIntBits(m03); - - hash = 37 * hash + Float.floatToIntBits(m10); - hash = 37 * hash + Float.floatToIntBits(m11); - hash = 37 * hash + Float.floatToIntBits(m12); - hash = 37 * hash + Float.floatToIntBits(m13); - - hash = 37 * hash + Float.floatToIntBits(m20); - hash = 37 * hash + Float.floatToIntBits(m21); - hash = 37 * hash + Float.floatToIntBits(m22); - hash = 37 * hash + Float.floatToIntBits(m23); - - hash = 37 * hash + Float.floatToIntBits(m30); - hash = 37 * hash + Float.floatToIntBits(m31); - hash = 37 * hash + Float.floatToIntBits(m32); - hash = 37 * hash + Float.floatToIntBits(m33); - - return hash; - } - - /** - * are these two matrices the same? they are is they both have the same mXX - * values. - * - * @param o the object to compare for equality - * @return true if they are equal - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Matrix4f) || o == null) { - return false; - } - - if (this == o) { - return true; - } - - Matrix4f comp = (Matrix4f) o; - if (Float.compare(m00, comp.m00) != 0) { - return false; - } - if (Float.compare(m01, comp.m01) != 0) { - return false; - } - if (Float.compare(m02, comp.m02) != 0) { - return false; - } - if (Float.compare(m03, comp.m03) != 0) { - return false; - } - - if (Float.compare(m10, comp.m10) != 0) { - return false; - } - if (Float.compare(m11, comp.m11) != 0) { - return false; - } - if (Float.compare(m12, comp.m12) != 0) { - return false; - } - if (Float.compare(m13, comp.m13) != 0) { - return false; - } - - if (Float.compare(m20, comp.m20) != 0) { - return false; - } - if (Float.compare(m21, comp.m21) != 0) { - return false; - } - if (Float.compare(m22, comp.m22) != 0) { - return false; - } - if (Float.compare(m23, comp.m23) != 0) { - return false; - } - - if (Float.compare(m30, comp.m30) != 0) { - return false; - } - if (Float.compare(m31, comp.m31) != 0) { - return false; - } - if (Float.compare(m32, comp.m32) != 0) { - return false; - } - if (Float.compare(m33, comp.m33) != 0) { - return false; - } - - return true; - } - - /** - * @return true if this matrix is identity - */ - public boolean isIdentity() { - return (m00 == 1 && m01 == 0 && m02 == 0 && m03 == 0) - && (m10 == 0 && m11 == 1 && m12 == 0 && m13 == 0) - && (m20 == 0 && m21 == 0 && m22 == 1 && m23 == 0) - && (m30 == 0 && m31 == 0 && m32 == 0 && m33 == 1); - } - - /** - * Apply a scale to this matrix. - * - * @param scale the scale to apply - */ - public void scale(Vector3f scale) { - m00 *= scale.getX(); - m10 *= scale.getX(); - m20 *= scale.getX(); - m30 *= scale.getX(); - m01 *= scale.getY(); - m11 *= scale.getY(); - m21 *= scale.getY(); - m31 *= scale.getY(); - m02 *= scale.getZ(); - m12 *= scale.getZ(); - m22 *= scale.getZ(); - m32 *= scale.getZ(); - } - - static boolean equalIdentity(Matrix4f mat) { - if (Math.abs(mat.m00 - 1) > 1e-4) { - return false; - } - if (Math.abs(mat.m11 - 1) > 1e-4) { - return false; - } - if (Math.abs(mat.m22 - 1) > 1e-4) { - return false; - } - if (Math.abs(mat.m33 - 1) > 1e-4) { - return false; - } - - if (Math.abs(mat.m01) > 1e-4) { - return false; - } - if (Math.abs(mat.m02) > 1e-4) { - return false; - } - if (Math.abs(mat.m03) > 1e-4) { - return false; - } - - if (Math.abs(mat.m10) > 1e-4) { - return false; - } - if (Math.abs(mat.m12) > 1e-4) { - return false; - } - if (Math.abs(mat.m13) > 1e-4) { - return false; - } - - if (Math.abs(mat.m20) > 1e-4) { - return false; - } - if (Math.abs(mat.m21) > 1e-4) { - return false; - } - if (Math.abs(mat.m23) > 1e-4) { - return false; - } - - if (Math.abs(mat.m30) > 1e-4) { - return false; - } - if (Math.abs(mat.m31) > 1e-4) { - return false; - } - if (Math.abs(mat.m32) > 1e-4) { - return false; - } - - return true; - } - - // XXX: This tests more solid than converting the q to a matrix and - // multiplying... why? - public void multLocal(Quaternion rotation) { - Vector3f axis = new Vector3f(); - float angle = rotation.toAngleAxis(axis); - Matrix4f matrix4f = new Matrix4f(); - matrix4f.fromAngleAxis(angle, axis); - multLocal(matrix4f); - } - - @Override - public Matrix4f clone() { - try { - return (Matrix4f) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } -} diff --git a/server/java/com/jme3/math/Quaternion.java b/server/java/com/jme3/math/Quaternion.java deleted file mode 100644 index 3db929e1b8..0000000000 --- a/server/java/com/jme3/math/Quaternion.java +++ /dev/null @@ -1,1721 +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 com.jme3.math; - -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.util.logging.Logger; - -import com.jme3.util.TempVars; - -import io.eiren.math.FloatMath; - - -/** - * Quaternion defines a single example of a more general class of - * hypercomplex numbers. Quaternions extends a rotation in three dimensions to a - * rotation in four dimensions. This avoids "gimbal lock" and allows for smooth - * continuous rotation. - * - * Quaternion is defined by four floating point numbers: {x y z w}. - * - * @author Mark Powell - * @author Joshua Slack - */ -public final class Quaternion implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - - private static final Logger logger = Logger.getLogger(Quaternion.class.getName()); - /** - * Represents the identity quaternion rotation (0, 0, 0, 1). - */ - public static final Quaternion IDENTITY = new Quaternion(); - public static final Quaternion DIRECTION_Z = new Quaternion(); - public static final Quaternion ZERO = new Quaternion(0, 0, 0, 0); - - public static final Quaternion X_90_DEG = new Quaternion() - .fromAngleNormalAxis(FastMath.HALF_PI, Vector3f.UNIT_X); - public static final Quaternion X_180_DEG = new Quaternion() - .fromAngleNormalAxis(FastMath.PI, Vector3f.UNIT_X); - public static final Quaternion X_270_DEG = new Quaternion() - .fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_X); - public static final Quaternion Y_90_DEG = new Quaternion() - .fromAngleNormalAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); - public static final Quaternion Y_180_DEG = new Quaternion() - .fromAngleNormalAxis(FastMath.PI, Vector3f.UNIT_Y); - public static final Quaternion Y_270_DEG = new Quaternion() - .fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y); - public static final Quaternion Z_90_DEG = new Quaternion() - .fromAngleNormalAxis(FastMath.HALF_PI, Vector3f.UNIT_Z); - public static final Quaternion Z_180_DEG = new Quaternion() - .fromAngleNormalAxis(FastMath.PI, Vector3f.UNIT_Z); - public static final Quaternion Z_270_DEG = new Quaternion() - .fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Z); - - static { - DIRECTION_Z.fromAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z); - } - protected float x, y, z, w; - - /** - * Constructor instantiates a new Quaternion object - * initializing all values to zero, except w which is initialized to 1. - * - */ - public Quaternion() { - x = 0; - y = 0; - z = 0; - w = 1; - } - - /** - * Constructor instantiates a new Quaternion object from the - * given list of parameters. - * - * @param x the x value of the quaternion. - * @param y the y value of the quaternion. - * @param z the z value of the quaternion. - * @param w the w value of the quaternion. - */ - public Quaternion(float x, float y, float z, float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - public float getX() { - return x; - } - - public float getY() { - return y; - } - - public float getZ() { - return z; - } - - public float getW() { - return w; - } - - /** - * sets the data in a Quaternion object from the given list of - * parameters. - * - * @param x the x value of the quaternion. - * @param y the y value of the quaternion. - * @param z the z value of the quaternion. - * @param w the w value of the quaternion. - * @return this - */ - public Quaternion set(float x, float y, float z, float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - return this; - } - - /** - * Sets the data in this Quaternion object to be equal to the - * passed Quaternion object. The values are copied producing a - * new object. - * - * @param q The Quaternion to copy values from. - * @return this - */ - public Quaternion set(Quaternion q) { - this.x = q.x; - this.y = q.y; - this.z = q.z; - this.w = q.w; - return this; - } - - /** - * Constructor instantiates a new Quaternion object from a - * collection of rotation angles. - * - * @param angles the angles of rotation (x, y, z) that will define the - * Quaternion. - */ - public Quaternion(float[] angles) { - fromAngles(angles); - } - - /** - * Constructor instantiates a new Quaternion object from an - * interpolation between two other quaternions. - * - * @param q1 the first quaternion. - * @param q2 the second quaternion. - * @param interp the amount to interpolate between the two quaternions. - */ - public Quaternion(Quaternion q1, Quaternion q2, float interp) { - slerp(q1, q2, interp); - } - - /** - * Constructor instantiates a new Quaternion object from an - * existing quaternion, creating a copy. - * - * @param q the quaternion to copy. - */ - public Quaternion(Quaternion q) { - this.x = q.x; - this.y = q.y; - this.z = q.z; - this.w = q.w; - } - - /** - * Sets this Quaternion to {0, 0, 0, 1}. Same as calling set(0,0,0,1). - */ - public void loadIdentity() { - x = y = z = 0; - w = 1; - } - - /** - * @return true if this Quaternion is {0,0,0,1} - */ - public boolean isIdentity() { - if (x == 0 && y == 0 && z == 0 && w == 1) { - return true; - } else { - return false; - } - } - - /** - * fromAngles builds a quaternion from the Euler rotation - * angles (y,r,p). - * - * @param angles the Euler angles of rotation (in radians). - */ - public Quaternion fromAngles(float[] angles) { - if (angles.length != 3) { - throw new IllegalArgumentException("Angles array must have three elements"); - } - - return fromAngles(angles[0], angles[1], angles[2]); - } - - /** - * fromAngles builds a Quaternion from the Euler rotation - * angles (x,y,z) aka (pitch, yaw, rall)). Note that we are applying in - * order: (y, z, x) aka (yaw, roll, pitch) but we've ordered them in x, y, - * and z for convenience. - * - * @see http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm - * - * @param xAngle the Euler pitch of rotation (in radians). (aka Attitude, - * often rot around x) - * @param yAngle the Euler yaw of rotation (in radians). (aka Heading, often - * rot around y) - * @param zAngle the Euler roll of rotation (in radians). (aka Bank, often - * rot around z) - */ - public Quaternion fromAngles(float xAngle, float yAngle, float zAngle) { - float angle; - float sinY, sinZ, sinX, cosY, cosZ, cosX; - angle = zAngle * 0.5f; - sinZ = FastMath.sin(angle); - cosZ = FastMath.cos(angle); - angle = yAngle * 0.5f; - sinY = FastMath.sin(angle); - cosY = FastMath.cos(angle); - angle = xAngle * 0.5f; - sinX = FastMath.sin(angle); - cosX = FastMath.cos(angle); - - // variables used to reduce multiplication calls. - float cosYXcosZ = cosY * cosZ; - float sinYXsinZ = sinY * sinZ; - float cosYXsinZ = cosY * sinZ; - float sinYXcosZ = sinY * cosZ; - - w = (cosYXcosZ * cosX - sinYXsinZ * sinX); - x = (cosYXcosZ * sinX + sinYXsinZ * cosX); - y = (sinYXcosZ * cosX + cosYXsinZ * sinX); - z = (cosYXsinZ * cosX - sinYXcosZ * sinX); - - normalizeLocal(); - return this; - } - - /** - * toAngles returns this quaternion converted to Euler rotation - * angles (yaw,roll,pitch).
- * Note that the result is not always 100% accurate due to the implications - * of euler angles. - * - * @see http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm - * - * @param angles the float[] in which the angles should be stored, or null - * if you want a new float[] to be created - * @return the float[] in which the angles are stored. - */ - public float[] toAngles(float[] angles) { - if (angles == null) { - angles = new float[3]; - } else if (angles.length != 3) { - throw new IllegalArgumentException("Angles array must have three elements"); - } - - float sqw = w * w; - float sqx = x * x; - float sqy = y * y; - float sqz = z * z; - float unit = sqx + sqy + sqz + sqw; // if normalized is one, otherwise - // is correction factor - float test = x * y + z * w; - if (test > 0.499 * unit) { // singularity at north pole - angles[1] = 2 * FastMath.atan2(x, w); - angles[2] = FastMath.HALF_PI; - angles[0] = 0; - } else if (test < -0.499 * unit) { // singularity at south pole - angles[1] = -2 * FastMath.atan2(x, w); - angles[2] = -FastMath.HALF_PI; - angles[0] = 0; - } else { - angles[1] = FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // yaw - // or - // bank - angles[2] = FastMath.asin(2 * test / unit); // roll or heading - angles[0] = FastMath.atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); // pitch - // or - // attitude - } - return angles; - } - - /** - * Returns Euler rotation angle around x axis (pitch). - * - * @return - * @see #toAngles(float[]) - */ - public float getPitch() { - float sqw = w * w; - float sqx = x * x; - float sqy = y * y; - float sqz = z * z; - float unit = sqx + sqy + sqz + sqw; // if normalized is one, otherwise - // is correction factor - float test = x * y + z * w; - if (test > 0.499 * unit) { // singularity at north pole - return 0; - } else if (test < -0.499 * unit) { // singularity at south pole - return 0; - } else { - return FastMath.atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); // pitch - // or - // attitude - } - } - - /** - * Returns Euler rotation angle around y axis (yaw). - * - * @return - * @see #toAngles(float[]) - */ - public float getYaw() { - float sqw = w * w; - float sqx = x * x; - float sqy = y * y; - float sqz = z * z; - float unit = sqx + sqy + sqz + sqw; // if normalized is one, otherwise - // is correction factor - float test = x * y + z * w; - if (test > 0.499 * unit) { // singularity at north pole - return 2 * FastMath.atan2(x, w); - } else if (test < -0.499 * unit) { // singularity at south pole - return -2 * FastMath.atan2(x, w); - } else { - return FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // yaw - // or - // bank - } - } - - /** - * Returns Euler rotation angle around z axis (roll). - * - * @return - * @see #toAngles(float[]) - */ - public float getRoll() { - float sqw = w * w; - float sqx = x * x; - float sqy = y * y; - float sqz = z * z; - float unit = sqx + sqy + sqz + sqw; // if normalized is one, otherwise - // is correction factor - float test = x * y + z * w; - if (test > 0.499 * unit) { // singularity at north pole - return FastMath.HALF_PI; - } else if (test < -0.499 * unit) { // singularity at south pole - return -FastMath.HALF_PI; - } else { - return FastMath.asin(2 * test / unit); // roll or heading - } - } - - /** - * - * fromRotationMatrix generates a quaternion from a supplied - * matrix. This matrix is assumed to be a rotational matrix. - * - * @param matrix the matrix that defines the rotation. - */ - public Quaternion fromRotationMatrix(Matrix3f matrix) { - return fromRotationMatrix( - matrix.m00, - matrix.m01, - matrix.m02, - matrix.m10, - matrix.m11, - matrix.m12, - matrix.m20, - matrix.m21, - matrix.m22 - ); - } - - public Quaternion fromRotationMatrix( - float m00, - float m01, - float m02, - float m10, - float m11, - float m12, - float m20, - float m21, - float m22 - ) { - // first normalize the forward (F), up (U) and side (S) vectors of the - // rotation matrix - // so that the scale does not affect the rotation - float lengthSquared = m00 * m00 + m10 * m10 + m20 * m20; - if (lengthSquared != 1f && lengthSquared != 0f) { - lengthSquared = 1.0f / FastMath.sqrt(lengthSquared); - m00 *= lengthSquared; - m10 *= lengthSquared; - m20 *= lengthSquared; - } - lengthSquared = m01 * m01 + m11 * m11 + m21 * m21; - if (lengthSquared != 1f && lengthSquared != 0f) { - lengthSquared = 1.0f / FastMath.sqrt(lengthSquared); - m01 *= lengthSquared; - m11 *= lengthSquared; - m21 *= lengthSquared; - } - lengthSquared = m02 * m02 + m12 * m12 + m22 * m22; - if (lengthSquared != 1f && lengthSquared != 0f) { - lengthSquared = 1.0f / FastMath.sqrt(lengthSquared); - m02 *= lengthSquared; - m12 *= lengthSquared; - m22 *= lengthSquared; - } - - // Use the Graphics Gems code, from - // ftp://ftp.cis.upenn.edu/pub/graphics/shoemake/quatut.ps.Z - // *NOT* the "Matrix and Quaternions FAQ", which has errors! - - // the trace is the sum of the diagonal elements; see - // http://mathworld.wolfram.com/MatrixTrace.html - float t = m00 + m11 + m22; - - // we protect the division by s by ensuring that s>=1 - if (t >= 0) { // |w| >= .5 - float s = FastMath.sqrt(t + 1); // |s|>=1 ... - w = 0.5f * s; - s = 0.5f / s; // so this division isn't bad - x = (m21 - m12) * s; - y = (m02 - m20) * s; - z = (m10 - m01) * s; - } else if ((m00 > m11) && (m00 > m22)) { - float s = FastMath.sqrt(1.0f + m00 - m11 - m22); // |s|>=1 - x = s * 0.5f; // |x| >= .5 - s = 0.5f / s; - y = (m10 + m01) * s; - z = (m02 + m20) * s; - w = (m21 - m12) * s; - } else if (m11 > m22) { - float s = FastMath.sqrt(1.0f + m11 - m00 - m22); // |s|>=1 - y = s * 0.5f; // |y| >= .5 - s = 0.5f / s; - x = (m10 + m01) * s; - z = (m21 + m12) * s; - w = (m02 - m20) * s; - } else { - float s = FastMath.sqrt(1.0f + m22 - m00 - m11); // |s|>=1 - z = s * 0.5f; // |z| >= .5 - s = 0.5f / s; - x = (m02 + m20) * s; - y = (m21 + m12) * s; - w = (m10 - m01) * s; - } - - return this; - } - - /** - * toRotationMatrix converts this quaternion to a rotational - * matrix. Note: the result is created from a normalized version of this - * quat. - * - * @return the rotation matrix representation of this quaternion. - */ - public Matrix3f toRotationMatrix() { - Matrix3f matrix = new Matrix3f(); - return toRotationMatrix(matrix); - } - - /** - * toRotationMatrix converts this quaternion to a rotational - * matrix. The result is stored in result. - * - * @param result The Matrix3f to store the result in. - * @return the rotation matrix representation of this quaternion. - */ - public Matrix3f toRotationMatrix(Matrix3f result) { - - float norm = norm(); - // we explicitly test norm against one here, saving a division - // at the cost of a test and branch. Is it worth it? - float s = (norm == 1f) ? 2f : (norm > 0f) ? 2f / norm : 0; - - // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs - // will be used 2-4 times each. - float xs = x * s; - float ys = y * s; - float zs = z * s; - float xx = x * xs; - float xy = x * ys; - float xz = x * zs; - float xw = w * xs; - float yy = y * ys; - float yz = y * zs; - float yw = w * ys; - float zz = z * zs; - float zw = w * zs; - - // using s=2/norm (instead of 1/norm) saves 9 multiplications by 2 here - result.m00 = 1 - (yy + zz); - result.m01 = (xy - zw); - result.m02 = (xz + yw); - result.m10 = (xy + zw); - result.m11 = 1 - (xx + zz); - result.m12 = (yz - xw); - result.m20 = (xz - yw); - result.m21 = (yz + xw); - result.m22 = 1 - (xx + yy); - - return result; - } - - /** - * toRotationMatrix converts this quaternion to a rotational - * matrix. The result is stored in result. 4th row and 4th column values are - * untouched. Note: the result is created from a normalized version of this - * quat. - * - * @param result The Matrix4f to store the result in. - * @return the rotation matrix representation of this quaternion. - */ - public Matrix4f toRotationMatrix(Matrix4f result) { - TempVars tempv = TempVars.get(); - Vector3f originalScale = tempv.vect1; - - result.toScaleVector(originalScale); - result.setScale(1, 1, 1); - float norm = norm(); - // we explicitly test norm against one here, saving a division - // at the cost of a test and branch. Is it worth it? - float s = (norm == 1f) ? 2f : (norm > 0f) ? 2f / norm : 0; - - // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs - // will be used 2-4 times each. - float xs = x * s; - float ys = y * s; - float zs = z * s; - float xx = x * xs; - float xy = x * ys; - float xz = x * zs; - float xw = w * xs; - float yy = y * ys; - float yz = y * zs; - float yw = w * ys; - float zz = z * zs; - float zw = w * zs; - - // using s=2/norm (instead of 1/norm) saves 9 multiplications by 2 here - result.m00 = 1 - (yy + zz); - result.m01 = (xy - zw); - result.m02 = (xz + yw); - result.m10 = (xy + zw); - result.m11 = 1 - (xx + zz); - result.m12 = (yz - xw); - result.m20 = (xz - yw); - result.m21 = (yz + xw); - result.m22 = 1 - (xx + yy); - - result.setScale(originalScale); - - tempv.release(); - - return result; - } - - /** - * getRotationColumn returns one of three columns specified by - * the parameter. This column is returned as a Vector3f object. - * - * @param i the column to retrieve. Must be between 0 and 2. - * @return the column specified by the index. - */ - public Vector3f getRotationColumn(int i) { - return getRotationColumn(i, null); - } - - /** - * getRotationColumn returns one of three columns specified by - * the parameter. This column is returned as a Vector3f object. - * The value is retrieved as if this quaternion was first normalized. - * - * @param i the column to retrieve. Must be between 0 and 2. - * @param store the vector object to store the result in. if null, a new one - * is created. - * @return the column specified by the index. - */ - public Vector3f getRotationColumn(int i, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - - float norm = norm(); - if (norm != 1.0f) { - norm = FastMath.invSqrt(norm); - } - - float xx = x * x * norm; - float xy = x * y * norm; - float xz = x * z * norm; - float xw = x * w * norm; - float yy = y * y * norm; - float yz = y * z * norm; - float yw = y * w * norm; - float zz = z * z * norm; - float zw = z * w * norm; - - switch (i) { - case 0: - store.x = 1 - 2 * (yy + zz); - store.y = 2 * (xy + zw); - store.z = 2 * (xz - yw); - break; - case 1: - store.x = 2 * (xy - zw); - store.y = 1 - 2 * (xx + zz); - store.z = 2 * (yz + xw); - break; - case 2: - store.x = 2 * (xz + yw); - store.y = 2 * (yz - xw); - store.z = 1 - 2 * (xx + yy); - break; - default: - logger.warning("Invalid column index."); - throw new IllegalArgumentException("Invalid column index. " + i); - } - - return store; - } - - /** - * Gets three rows of rotation matrix. - *

- * The same as transposed columns from {@linkplain #getRotationColumn}. - */ - public void getRotationBasis(Vector3f v1, Vector3f v2, Vector3f v3) { - // This source code from toRotationMatrix method - float norm = norm(); - float s = (norm == 1f) ? 2f : (norm > 0f) ? 2f / norm : 0; - //@formatter:off - float xs = x * s; float ys = y * s; float zs = z * s; - float xx = x * xs; float xy = x * ys; float xz = x * zs; - float xw = w * xs; float yy = y * ys; float yz = y * zs; - float yw = w * ys; float zz = z * zs; float zw = w * zs; - //@formatter:on - v1.set(1f - yy - zz, xy + zw, xz - yw); - v2.set(xy - zw, 1f - xx - zz, yz + xw); - v3.set(xz + yw, yz - xw, 1f - xx - yy); - } - - /** - * fromAngleAxis sets this quaternion to the values specified - * by an angle and an axis of rotation. This method creates an object, so - * use fromAngleNormalAxis if your axis is already normalized. - * - * @param angle the angle to rotate (in radians). - * @param axis the axis of rotation. - * @return this quaternion - */ - public Quaternion fromAngleAxis(float angle, Vector3f axis) { - Vector3f normAxis = axis.normalize(); - fromAngleNormalAxis(angle, normAxis); - return this; - } - - /** - * fromAngleAxis sets this quaternion to the values specified - * by an angle and an axis of rotation. This method creates an object, so - * use fromAngleNormalAxis if your axis is already normalized. - * - * @param angle the angle to rotate (in radians). - * @param x - * @param y - * @param z the axis of rotation. - * @return this quaternion - */ - public Quaternion fromAngleAxis(float angle, float x, float y, float z) { - float length = x * x + y * y + z * z; - if (length != 1f && length != 0f) { - length = 1.0f / FastMath.sqrt(length); - return fromAngleNormalAxis(angle, x * length, y * length, z * length); - } else { - return fromAngleNormalAxis(angle, x, y, z); - } - } - - /** - * fromAngleNormalAxis sets this quaternion to the values - * specified by an angle and a normalized axis of rotation. - * - * @param angle the angle to rotate (in radians). - * @param axis the axis of rotation (already normalized). - */ - public Quaternion fromAngleNormalAxis(float angle, Vector3f axis) { - if (axis.x == 0 && axis.y == 0 && axis.z == 0) { - loadIdentity(); - } else { - float halfAngle = 0.5f * angle; - float sin = FastMath.sin(halfAngle); - w = FastMath.cos(halfAngle); - x = sin * axis.x; - y = sin * axis.y; - z = sin * axis.z; - } - return this; - } - - /** - * fromAngleNormalAxis sets this quaternion to the values - * specified by an angle and a normalized axis of rotation. - * - * @param angle the angle to rotate (in radians). - * @param x - * @param y - * @param z the axis of rotation (already normalized). - */ - public Quaternion fromAngleNormalAxis(float angle, float ax, float ay, float az) { - if (ax == 0 && ay == 0 && az == 0) { - loadIdentity(); - } else { - float halfAngle = 0.5f * angle; - float sin = FastMath.sin(halfAngle); - w = FastMath.cos(halfAngle); - x = sin * ax; - y = sin * ay; - z = sin * az; - } - return this; - } - - /** - * toAngleAxis sets a given angle and axis to that represented - * by the current quaternion. The values are stored as follows: The axis is - * provided as a parameter and built by the method, the angle is returned as - * a float. - * - * @param axisStore the object we'll store the computed axis in. - * @return the angle of rotation in radians. - */ - public float toAngleAxis(Vector3f axisStore) { - float sqrLength = x * x + y * y + z * z; - float angle; - if (sqrLength == 0.0f) { - angle = 0.0f; - if (axisStore != null) { - axisStore.x = 1.0f; - axisStore.y = 0.0f; - axisStore.z = 0.0f; - } - } else { - angle = (2.0f * FastMath.acos(w)); - if (axisStore != null) { - float invLength = (1.0f / FastMath.sqrt(sqrLength)); - axisStore.x = x * invLength; - axisStore.y = y * invLength; - axisStore.z = z * invLength; - } - } - - return angle; - } - - public float angleBetween(Quaternion q2) { - float w = this.w * q2.w + this.x * q2.x + this.y * q2.y + this.z * q2.z; - float x = this.w * q2.x - this.x * q2.w - this.y * q2.z + this.z * q2.y; - float y = this.w * q2.y + this.x * q2.z - this.y * q2.w - this.z * q2.x; - float z = this.w * q2.z - this.x * q2.y + this.y * q2.x - this.z * q2.w; - - // compute cosine and sine of the angle between - // do so in a numerically stable way - return FastMath.atan2(FastMath.sqrt(x * x + y * y + z * z), w); - } - - public Quaternion pureSlerpLocal(Quaternion q2, float t) { - // make it nice and symmetrical - Quaternion q1 = this; - - // get q2 relative to q1 - float rw = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; - float rx = q1.w * q2.x - q1.x * q2.w - q1.y * q2.z + q1.z * q2.y; - float ry = q1.w * q2.y + q1.x * q2.z - q1.y * q2.w - q1.z * q2.x; - float rz = q1.w * q2.z - q1.x * q2.y + q1.y * q2.x - q1.z * q2.w; - - // compute theta robustly - float theta = FastMath.atan2(FastMath.sqrt(rx * rx + ry * ry + rz * rz), rw); - - // compute interpolation variables - float s0 = FastMath.sin((1.0f - t) * theta); - float s1 = FastMath.sin(t * theta); - - // compute interpolated quaternion - float sw = s0 * q1.w + s1 * q2.w; - float sx = s0 * q1.x + s1 * q2.x; - float sy = s0 * q1.y + s1 * q2.y; - float sz = s0 * q1.z + s1 * q2.z; - - // compute the length of the quaternion - float mag = FastMath.sqrt(sw * sw + sx * sx + sy * sy + sz * sz); - - if (mag > 0.0f) { - float iMag = 1.0f / mag; - this.w = iMag * sw; - this.x = iMag * sx; - this.y = iMag * sy; - this.z = iMag * sz; - - } else if (t >= 0.5f) { - this.w = q2.w; - this.x = q2.x; - this.y = q2.y; - this.z = q2.z; - } - // else this == q1, no need to do anything. - - return this; - } - - /** - * @deprecated Direct call to {@link #slerpLocal()}. - */ - public Quaternion slerp(Quaternion q2, float t) { - return this.slerpLocal(q2, t); - } - - /** - * Sets the values of this normalized quaternion from itself to the - * normalized quaternion q2 by t - * - * @param q2 Final interpolation value - * @param t The amount diffrence - */ - public Quaternion slerpLocal(Quaternion q2, float t) { - // make it nice and symmetrical - Quaternion q1 = this; - - float rw = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; - - if (rw < 0) { - return this.pureSlerpLocal(q2.negate(), t); - } else { - return this.pureSlerpLocal(q2, t); - } - } - - - public Quaternion pureSlerp(Quaternion q1, Quaternion q2, float t) { - return set(q1).pureSlerpLocal(q2, t); - } - - /** - * slerp sets this quaternion's value as an interpolation - * between two other normalized quaternions. - * - * @param q1 the first quaternion. - * @param q2 the second quaternion. - * @param t the amount to interpolate between the two quaternions. - */ - public Quaternion slerp(Quaternion q1, Quaternion q2, float t) { - float rw = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; - - if (rw < 0) { - return pureSlerp(q1, q2.negate(), t); - } else { - return pureSlerp(q1, q2, t); - } - } - - /** - * Sets the values of this quaternion to the nlerp from itself to q2 by - * blend. - * - * @param q2 - * @param blend - */ - public void nlerp(Quaternion q2, float blend) { - float dot = dot(q2); - float blendI = 1.0f - blend; - if (dot < 0.0f) { - x = blendI * x - blend * q2.x; - y = blendI * y - blend * q2.y; - z = blendI * z - blend * q2.z; - w = blendI * w - blend * q2.w; - } else { - x = blendI * x + blend * q2.x; - y = blendI * y + blend * q2.y; - z = blendI * z + blend * q2.z; - w = blendI * w + blend * q2.w; - } - normalizeLocal(); - } - - /** - * add adds the values of this quaternion to those of the - * parameter quaternion. The result is returned as a new quaternion. - * - * @param q the quaternion to add to this. - * @return the new quaternion. - */ - public Quaternion add(Quaternion q) { - return new Quaternion(x + q.x, y + q.y, z + q.z, w + q.w); - } - - /** - * add adds the values of this quaternion to those of the - * parameter quaternion. The result is stored in this Quaternion. - * - * @param q the quaternion to add to this. - * @return This Quaternion after addition. - */ - public Quaternion addLocal(Quaternion q) { - this.x += q.x; - this.y += q.y; - this.z += q.z; - this.w += q.w; - return this; - } - - /** - * subtract subtracts the values of the parameter quaternion - * from those of this quaternion. The result is returned as a new - * quaternion. - * - * @param q the quaternion to subtract from this. - * @return the new quaternion. - */ - public Quaternion subtract(Quaternion q) { - return new Quaternion(x - q.x, y - q.y, z - q.z, w - q.w); - } - - /** - * subtract subtracts the values of the parameter quaternion - * from those of this quaternion. The result is stored in this Quaternion. - * - * @param q the quaternion to subtract from this. - * @return This Quaternion after subtraction. - */ - public Quaternion subtractLocal(Quaternion q) { - this.x -= q.x; - this.y -= q.y; - this.z -= q.z; - this.w -= q.w; - return this; - } - - /** - * mult multiplies this quaternion by a parameter quaternion. - * The result is returned as a new quaternion. It should be noted that - * quaternion multiplication is not commutative so q * p != p * q. - * - * @param q the quaternion to multiply this quaternion by. - * @return the new quaternion. - */ - public Quaternion mult(Quaternion q) { - return mult(q, null); - } - - /** - * mult multiplies this quaternion by a parameter quaternion. - * The result is returned as a new quaternion. It should be noted that - * quaternion multiplication is not commutative so q * p != p * q. - * - * It IS safe for q and res to be the same object. It IS NOT safe for this - * and res to be the same object. - * - * @param q the quaternion to multiply this quaternion by. - * @param res the quaternion to store the result in. - * @return the new quaternion. - */ - public Quaternion mult(Quaternion q, Quaternion res) { - if (res == null) { - res = new Quaternion(); - } - float qw = q.w, qx = q.x, qy = q.y, qz = q.z; - res.x = x * qw + y * qz - z * qy + w * qx; - res.y = -x * qz + y * qw + z * qx + w * qy; - res.z = x * qy - y * qx + z * qw + w * qz; - res.w = -x * qx - y * qy - z * qz + w * qw; - return res; - } - - /** - * apply multiplies this quaternion by a parameter matrix - * internally. - * - * @param matrix the matrix to apply to this quaternion. - */ - public void apply(Matrix3f matrix) { - float oldX = x, oldY = y, oldZ = z, oldW = w; - fromRotationMatrix(matrix); - float tempX = x, tempY = y, tempZ = z, tempW = w; - - x = oldX * tempW + oldY * tempZ - oldZ * tempY + oldW * tempX; - y = -oldX * tempZ + oldY * tempW + oldZ * tempX + oldW * tempY; - z = oldX * tempY - oldY * tempX + oldZ * tempW + oldW * tempZ; - w = -oldX * tempX - oldY * tempY - oldZ * tempZ + oldW * tempW; - } - - /** - * - * fromAxes creates a Quaternion that represents - * the coordinate system defined by three axes. These axes are assumed to be - * orthogonal and no error checking is applied. Thus, the user must insure - * that the three axes being provided indeed represents a proper right - * handed coordinate system. - * - * @param axis the array containing the three vectors representing the - * coordinate system. - */ - public Quaternion fromAxes(Vector3f[] axis) { - if (axis.length != 3) { - throw new IllegalArgumentException("Axis array must have three elements"); - } - return fromAxes(axis[0], axis[1], axis[2]); - } - - /** - * - * fromAxes creates a Quaternion that represents - * the coordinate system defined by three axes. These axes are assumed to be - * orthogonal and no error checking is applied. Thus, the user must insure - * that the three axes being provided indeed represents a proper right - * handed coordinate system. - * - * @param xAxis vector representing the x-axis of the coordinate system. - * @param yAxis vector representing the y-axis of the coordinate system. - * @param zAxis vector representing the z-axis of the coordinate system. - */ - public Quaternion fromAxes(Vector3f xAxis, Vector3f yAxis, Vector3f zAxis) { - return fromRotationMatrix( - xAxis.x, - yAxis.x, - zAxis.x, - xAxis.y, - yAxis.y, - zAxis.y, - xAxis.z, - yAxis.z, - zAxis.z - ); - } - - /** - * - * toAxes takes in an array of three vectors. Each vector - * corresponds to an axis of the coordinate system defined by the quaternion - * rotation. - * - * @param axis the array of vectors to be filled. - */ - public void toAxes(Vector3f axis[]) { - Matrix3f tempMat = toRotationMatrix(); - axis[0] = tempMat.getColumn(0, axis[0]); - axis[1] = tempMat.getColumn(1, axis[1]); - axis[2] = tempMat.getColumn(2, axis[2]); - } - - /** - * mult multiplies this quaternion by a parameter vector. The - * result is returned as a new vector. - * - * @param v the vector to multiply this quaternion by. - * @return the new vector. - */ - public Vector3f mult(Vector3f v) { - return mult(v, null); - } - - /** - * mult multiplies this quaternion by a parameter vector. The - * result is stored in the supplied vector - * - * @param v the vector to multiply this quaternion by. - * @return v - */ - public Vector3f multLocal(Vector3f v) { - float tempX, tempY; - tempX = w * w * v.x - + 2 * y * w * v.z - - 2 * z * w * v.y - + x * x * v.x - + 2 * y * x * v.y - + 2 * z * x * v.z - - z * z * v.x - - y * y * v.x; - tempY = 2 * x * y * v.x - + y * y * v.y - + 2 * z * y * v.z - + 2 * w * z * v.x - - z * z * v.y - + w * w * v.y - - 2 * x * w * v.z - - x * x * v.y; - v.z = 2 * x * z * v.x - + 2 * y * z * v.y - + z * z * v.z - - 2 * w * y * v.x - - y * y * v.z - + 2 * w * x * v.y - - x * x * v.z - + w * w * v.z; - v.x = tempX; - v.y = tempY; - return v; - } - - /** - * Multiplies this Quaternion by the supplied quaternion. The result is - * stored in this Quaternion, which is also returned for chaining. Similar - * to this *= q. - * - * @param q The Quaternion to multiply this one by. - * @return This Quaternion, after multiplication. - */ - public Quaternion multLocal(Quaternion q) { - float x1 = x * q.w + y * q.z - z * q.y + w * q.x; - float y1 = -x * q.z + y * q.w + z * q.x + w * q.y; - float z1 = x * q.y - y * q.x + z * q.w + w * q.z; - w = -x * q.x - y * q.y - z * q.z + w * q.w; - x = x1; - y = y1; - z = z1; - return this; - } - - /** - * Multiplies this Quaternion by the supplied quaternion. The result is - * stored in this Quaternion, which is also returned for chaining. Similar - * to this *= q. - * - * @param qx - quat x value - * @param qy - quat y value - * @param qz - quat z value - * @param qw - quat w value - * - * @return This Quaternion, after multiplication. - */ - public Quaternion multLocal(float qx, float qy, float qz, float qw) { - float x1 = x * qw + y * qz - z * qy + w * qx; - float y1 = -x * qz + y * qw + z * qx + w * qy; - float z1 = x * qy - y * qx + z * qw + w * qz; - w = -x * qx - y * qy - z * qz + w * qw; - x = x1; - y = y1; - z = z1; - return this; - } - - /** - * mult multiplies this quaternion by a parameter vector. The - * result is returned as a new vector. - * - * @param v the vector to multiply this quaternion by. - * @param store the vector to store the result in. It IS safe for v and - * store to be the same object. - * @return the result vector. - */ - public Vector3f mult(Vector3f v, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - if (v.x == 0 && v.y == 0 && v.z == 0) { - store.set(0, 0, 0); - } else { - float vx = v.x, vy = v.y, vz = v.z; - store.x = w * w * vx - + 2 * y * w * vz - - 2 * z * w * vy - + x * x * vx - + 2 * y * x * vy - + 2 * z * x * vz - - z * z * vx - - y * y * vx; - store.y = 2 * x * y * vx - + y * y * vy - + 2 * z * y * vz - + 2 * w * z * vx - - z * z * vy - + w * w * vy - - 2 * x * w * vz - - x * x * vy; - store.z = 2 * x * z * vx - + 2 * y * z * vy - + z * z * vz - - 2 * w * y * vx - - y * y * vz - + 2 * w * x * vy - - x * x * vz - + w * w * vz; - } - return store; - } - - /** - * @return X component of vector rotated by quaternion - */ - public float multX(float vx, float vy, float vz) { - return w * w * vx - + 2 * y * w * vz - - 2 * z * w * vy - + x * x * vx - + 2 * y * x * vy - + 2 * z * x * vz - - z * z * vx - - y * y * vx; - } - - /** - * @return Y component of vector rotated by quaternion - */ - public float multY(float vx, float vy, float vz) { - return 2 * x * y * vx - + y * y * vy - + 2 * z * y * vz - + 2 * w * z * vx - - z * z * vy - + w * w * vy - - 2 * x * w * vz - - x * x * vy; - } - - /** - * @return Z component of vector rotated by quaternion - */ - public float multZ(float vx, float vy, float vz) { - return 2 * x * z * vx - + 2 * y * z * vy - + z * z * vz - - 2 * w * y * vx - - y * y * vz - + 2 * w * x * vy - - x * x * vz - + w * w * vz; - } - - /** - * Rotate X axis aligned vector. - */ - public Vector3f multAxisX(float vx, Vector3f store) { - if (store == null) - store = new Vector3f(); - store.x = (w * w + x * x - z * z - y * y) * vx; - store.y = 2f * (x * y + w * z) * vx; - store.z = 2f * (x * z - w * y) * vx; - return store; - } - - /** - * Rotate Y axis aligned vector. - */ - public Vector3f multAxisY(float vy, Vector3f store) { - if (store == null) - store = new Vector3f(); - store.x = 2f * (y * x - z * w) * vy; - store.y = (y * y - z * z + w * w - x * x) * vy; - store.z = 2f * (y * z + w * x) * vy; - return store; - } - - /** - * Rotate Z axis aligned vector. - */ - public Vector3f multAxisZ(float vz, Vector3f store) { - if (store == null) - store = new Vector3f(); - store.x = 2f * (y * w + z * x) * vz; - store.y = 2f * (z * y - x * w) * vz; - store.z = (z * z - y * y - x * x + w * w) * vz; - return store; - } - - /** - * mult multiplies this quaternion by a parameter vector. The - * result is returned as a new vector. - * - * @param vx - * @param vy - * @param vz the vector to multiply this quaternion by. - * @param store the vector to store the result in. It IS safe for v and - * store to be the same object. - * @return the result vector. - */ - public Vector3f mult(float vx, float vy, float vz, Vector3f store) { - if (store == null) { - store = new Vector3f(); - } - if (vx == 0 && vy == 0 && vz == 0) { - store.set(0, 0, 0); - } else { - store.x = w * w * vx - + 2 * y * w * vz - - 2 * z * w * vy - + x * x * vx - + 2 * y * x * vy - + 2 * z * x * vz - - z * z * vx - - y * y * vx; - store.y = 2 * x * y * vx - + y * y * vy - + 2 * z * y * vz - + 2 * w * z * vx - - z * z * vy - + w * w * vy - - 2 * x * w * vz - - x * x * vy; - store.z = 2 * x * z * vx - + 2 * y * z * vy - + z * z * vz - - 2 * w * y * vx - - y * y * vz - + 2 * w * x * vy - - x * x * vz - + w * w * vz; - } - return store; - } - - /** - * mult multiplies this quaternion by a parameter scalar. The - * result is returned as a new quaternion. - * - * @param scalar the quaternion to multiply this quaternion by. - * @return the new quaternion. - */ - public Quaternion mult(float scalar) { - return new Quaternion(scalar * x, scalar * y, scalar * z, scalar * w); - } - - /** - * mult multiplies this quaternion by a parameter scalar. The - * result is stored locally. - * - * @param scalar the quaternion to multiply this quaternion by. - * @return this. - */ - public Quaternion multLocal(float scalar) { - w *= scalar; - x *= scalar; - y *= scalar; - z *= scalar; - return this; - } - - /** - * dot calculates and returns the dot product of this - * quaternion with that of the parameter quaternion. - * - * @param q the quaternion to calculate the dot product of. - * @return the dot product of this and the parameter quaternion. - */ - public float dot(Quaternion q) { - return w * q.w + x * q.x + y * q.y + z * q.z; - } - - /** - * norm returns the norm of this quaternion. This is the dot - * product of this quaternion with itself. - * - * @return the norm of the quaternion. - */ - public float norm() { - return w * w + x * x + y * y + z * z; - } - - /** - * normalizeLocal normalizes the current - * Quaternion. The result is stored internally. - */ - public Quaternion normalizeLocal() { - float n = FastMath.invSqrt(norm()); - x *= n; - y *= n; - z *= n; - w *= n; - return this; - } - - /** - * normalize returns the normalized Quaternion. - */ - public Quaternion normalize() { - Quaternion q = this.clone(); - - float n = FastMath.invSqrt(q.norm()); - q.x *= n; - q.y *= n; - q.z *= n; - q.w *= n; - return q; - } - - /** - * inverse returns the inverse of this quaternion as a new - * quaternion. If this quaternion does not have an inverse (if its normal is - * 0 or less), then null is returned. - * - * @return the inverse of this quaternion or null if the inverse does not - * exist. - */ - public Quaternion inverse() { - float norm = norm(); - if (norm > 0.0) { - float invNorm = 1.0f / norm; - return new Quaternion(-x * invNorm, -y * invNorm, -z * invNorm, w * invNorm); - } - // return an invalid result to flag the error - return null; - } - - /** - * inverse returns the inverse of this quaternion. If this - * quaternion does not have an inverse (if its normal is 0 or less), then - * null is returned. - * - * @return the inverse of this quaternion or null if the inverse does not - * exist. - */ - public Quaternion inverse(Quaternion store) { - float norm = norm(); - if (norm > 0.0) { - float invNorm = 1.0f / norm; - return store.set(-x * invNorm, -y * invNorm, -z * invNorm, w * invNorm); - } - // return an invalid result to flag the error - return null; - } - - /** - * inverse calculates the inverse of this quaternion and - * returns this quaternion after it is calculated. If this quaternion does - * not have an inverse (if it's normal is 0 or less), nothing happens - * - * @return the inverse of this quaternion - */ - public Quaternion inverseLocal() { - float norm = norm(); - if (norm > 0.0) { - float invNorm = 1.0f / norm; - x *= -invNorm; - y *= -invNorm; - z *= -invNorm; - w *= invNorm; - } - return this; - } - - /** - * negateLocal inverts the values of the quaternion and returns - * it. - */ - public Quaternion negateLocal() { - x = -x; - y = -y; - z = -z; - w = -w; - return this; - } - - /** - * negate returns a negated copy of the quaternion. - */ - public Quaternion negate() { - return new Quaternion(-x, -y, -z, -w); - } - - /** - * - * toString creates the string representation of this - * Quaternion. The values of the quaternion are displaced (x, - * y, z, w), in the following manner:
- * (x, y, z, w) - * - * @return the string representation of this object. - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "(" + x + ", " + y + ", " + z + ", " + w + ")"; - } - - /** - * equals determines if two quaternions are logically equal, - * that is, if the values of (x, y, z, w) are the same for both quaternions. - * - * @param o the object to compare for equality - * @return true if they are equal, false otherwise. - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Quaternion)) { - return false; - } - - if (this == o) { - return true; - } - - Quaternion comp = (Quaternion) o; - if (Float.compare(x, comp.x) != 0) { - return false; - } - if (Float.compare(y, comp.y) != 0) { - return false; - } - if (Float.compare(z, comp.z) != 0) { - return false; - } - if (Float.compare(w, comp.w) != 0) { - return false; - } - return true; - } - - /** - * - * hashCode returns the hash code value as an integer and is - * supported for the benefit of hashing based collection classes such as - * Hashtable, HashMap, HashSet etc. - * - * @return the hashcode for this instance of Quaternion. - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - int hash = 37; - hash = 37 * hash + Float.floatToIntBits(x); - hash = 37 * hash + Float.floatToIntBits(y); - hash = 37 * hash + Float.floatToIntBits(z); - hash = 37 * hash + Float.floatToIntBits(w); - return hash; - - } - - /** - * readExternal builds a quaternion from an - * ObjectInput object.
- * NOTE: Used with serialization. Not to be called manually. - * - * @param in the ObjectInput value to read from. - * @throws IOException if the ObjectInput value has problems reading a - * float. - * @see java.io.Externalizable - */ - public void readExternal(ObjectInput in) throws IOException { - x = in.readFloat(); - y = in.readFloat(); - z = in.readFloat(); - w = in.readFloat(); - } - - /** - * writeExternal writes this quaternion out to a - * ObjectOutput object. NOTE: Used with serialization. Not to - * be called manually. - * - * @param out the object to write to. - * @throws IOException if writing to the ObjectOutput fails. - * @see java.io.Externalizable - */ - public void writeExternal(ObjectOutput out) throws IOException { - out.writeFloat(x); - out.writeFloat(y); - out.writeFloat(z); - out.writeFloat(w); - } - - /** - * lookAt is a convienence method for auto-setting the - * quaternion based on a direction and an up vector. It computes the - * rotation to transform the z-axis to point into 'direction' and the y-axis - * to 'up'. - * - * @param direction where to look at in terms of local coordinates - * @param up a vector indicating the local up direction. (typically {0, 1, - * 0} in jME.) - */ - public void lookAt(Vector3f direction, Vector3f up) { - TempVars vars = TempVars.get(); - vars.vect3.set(direction).normalizeLocal(); - vars.vect1.set(up).crossLocal(direction).normalizeLocal(); - vars.vect2.set(direction).crossLocal(vars.vect1).normalizeLocal(); - fromAxes(vars.vect1, vars.vect2, vars.vect3); - vars.release(); - } - - /** - * @return A new quaternion that describes a rotation that would point you - * in the exact opposite direction of this Quaternion. - */ - public Quaternion opposite() { - return opposite(null); - } - - /** - * FIXME: This seems to have singularity type issues with angle == 0, - * possibly others such as PI. - * - * @param store A Quaternion to store our result in. If null, a new one is - * created. - * @return The store quaternion (or a new Quaterion, if store is null) that - * describes a rotation that would point you in the exact opposite direction - * of this Quaternion. - */ - public Quaternion opposite(Quaternion store) { - if (store == null) { - store = new Quaternion(); - } - - Vector3f axis = new Vector3f(); - float angle = toAngleAxis(axis); - - store.fromAngleAxis(FastMath.PI + angle, axis); - return store; - } - - /** - * @return This Quaternion, altered to describe a rotation that would point - * you in the exact opposite direction of where it is pointing currently. - */ - public Quaternion oppositeLocal() { - return opposite(this); - } - - @Override - public Quaternion clone() { - try { - return (Quaternion) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } - - /** - * Sets this quaternion to be a rotation from vec1 to vec2. - *

- * Based on implementation from here: - * https://github.com/toji/gl-matrix/blob/f0583ef53e94bc7e78b78c8a24f09ed5e2f7a20c/src/gl-matrix/quat.js#L54 - * - * @param vec1 - * @param vec2 - * @return this quaternion - */ - public Quaternion angleBetweenVectors(Vector3f vec1, Vector3f vec2) { - float dot = vec1.dot(vec2); - if (FloatMath.lessOrEqualsWithEpsilon(dot, -1)) { - Vector3f cross = vec1.cross(Vector3f.UNIT_X); - if (FloatMath.lessOrEqualsToZero(cross.length())) - cross = vec1.cross(Vector3f.UNIT_Y); - cross.normalizeLocal(); - fromAngleAxis(FloatMath.PI, cross); - } else if (FloatMath.greaterOrEqualsWithEpsilon(dot, 1)) { - loadIdentity(); - } else { - Vector3f cross = vec1.cross(vec2); - x = cross.x; - y = cross.y; - z = cross.z; - w = 1 + dot; - normalizeLocal(); - } - return this; - } - - public static boolean isIdentity(Quaternion q) { - if (Float.compare(q.x, 0) != 0) { - return false; - } - if (Float.compare(q.y, 0) != 0) { - return false; - } - if (Float.compare(q.z, 0) != 0) { - return false; - } - if (Float.compare(q.w, 1) != 0) { - return false; - } - return true; - } -} diff --git a/server/java/com/jme3/math/Transform.java b/server/java/com/jme3/math/Transform.java deleted file mode 100644 index f6cac7b5f8..0000000000 --- a/server/java/com/jme3/math/Transform.java +++ /dev/null @@ -1,399 +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 com.jme3.math; - -/** - * Started Date: Jul 16, 2004
- *
- * Represents a translation, rotation and scale in one object. - * - * @author Jack Lindamood - * @author Joshua Slack - */ -public final class Transform implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - - public static final Transform IDENTITY = new Transform(); - - private Quaternion rot = new Quaternion(); - private Vector3f translation = new Vector3f(); - private Vector3f scale = new Vector3f(1, 1, 1); - - public Transform(Vector3f translation, Quaternion rot) { - this.translation.set(translation); - this.rot.set(rot); - } - - public Transform(Vector3f translation, Quaternion rot, Vector3f scale) { - this(translation, rot); - this.scale.set(scale); - } - - public Transform(Vector3f translation) { - this(translation, Quaternion.IDENTITY); - } - - public Transform(Quaternion rot) { - this(Vector3f.ZERO, rot); - } - - public Transform() { - this(Vector3f.ZERO, Quaternion.IDENTITY); - } - - /** - * Sets this rotation to the given Quaternion value. - * - * @param rot The new rotation for this matrix. - * @return this - */ - public Transform setRotation(Quaternion rot) { - this.rot.set(rot); - return this; - } - - /** - * Sets this translation to the given value. - * - * @param trans The new translation for this matrix. - * @return this - */ - public Transform setTranslation(Vector3f trans) { - this.translation.set(trans); - return this; - } - - /** - * Return the translation vector in this matrix. - * - * @return translation vector. - */ - public Vector3f getTranslation() { - return translation; - } - - /** - * Sets this scale to the given value. - * - * @param scale The new scale for this matrix. - * @return this - */ - public Transform setScale(Vector3f scale) { - this.scale.set(scale); - return this; - } - - /** - * Sets this scale to the given value. - * - * @param scale The new scale for this matrix. - * @return this - */ - public Transform setScale(float scale) { - this.scale.set(scale, scale, scale); - return this; - } - - /** - * Return the scale vector in this matrix. - * - * @return scale vector. - */ - public Vector3f getScale() { - return scale; - } - - /** - * Stores this translation value into the given vector3f. If trans is null, - * a new vector3f is created to hold the value. The value, once stored, is - * returned. - * - * @param trans The store location for this matrix's translation. - * @return The value of this matrix's translation. - */ - public Vector3f getTranslation(Vector3f trans) { - if (trans == null) - trans = new Vector3f(); - trans.set(this.translation); - return trans; - } - - /** - * Stores this rotation value into the given Quaternion. If quat is null, a - * new Quaternion is created to hold the value. The value, once stored, is - * returned. - * - * @param quat The store location for this matrix's rotation. - * @return The value of this matrix's rotation. - */ - public Quaternion getRotation(Quaternion quat) { - if (quat == null) - quat = new Quaternion(); - quat.set(rot); - return quat; - } - - /** - * Return the rotation quaternion in this matrix. - * - * @return rotation quaternion. - */ - public Quaternion getRotation() { - return rot; - } - - /** - * Stores this scale value into the given vector3f. If scale is null, a new - * vector3f is created to hold the value. The value, once stored, is - * returned. - * - * @param scale The store location for this matrix's scale. - * @return The value of this matrix's scale. - */ - public Vector3f getScale(Vector3f scale) { - if (scale == null) - scale = new Vector3f(); - scale.set(this.scale); - return scale; - } - - /** - * Sets this matrix to the interpolation between the first matrix and the - * second by delta amount. - * - * @param t1 The begining transform. - * @param t2 The ending transform. - * @param delta An amount between 0 and 1 representing how far to - * interpolate from t1 to t2. - */ - public void interpolateTransforms(Transform t1, Transform t2, float delta) { - this.rot.slerp(t1.rot, t2.rot, delta); - this.translation.interpolate(t1.translation, t2.translation, delta); - this.scale.interpolate(t1.scale, t2.scale, delta); - } - - /** - * Changes the values of this matrix acording to it's parent. Very similar - * to the concept of Node/Spatial transforms. - * - * @param parent The parent matrix. - * @return This matrix, after combining. - */ - public Transform combineWithParent(Transform parent) { - scale.multLocal(parent.scale); -// rot.multLocal(parent.rot); - parent.rot.mult(rot, rot); - - // This here, is evil code -// parent -// .rot -// .multLocal(translation) -// .multLocal(parent.scale) -// .addLocal(parent.translation); - - translation.multLocal(parent.scale); - parent.rot - .multLocal(translation) - .addLocal(parent.translation); - return this; - } - - /** - * Same as {@link #combineWithParent(Transform)}, but assumes that rotation - * is global, so it's not modified. - * - * @param parent - * @return - */ - public Transform combineWithParentGlobalRotation(Transform parent) { - scale.multLocal(parent.scale); - translation.multLocal(parent.scale); - - parent.rot - .multLocal(translation) - .addLocal(parent.translation); - return this; - } - - /** - * Sets this matrix's translation to the given x,y,z values. - * - * @param x This matrix's new x translation. - * @param y This matrix's new y translation. - * @param z This matrix's new z translation. - * @return this - */ - public Transform setTranslation(float x, float y, float z) { - translation.set(x, y, z); - return this; - } - - /** - * Sets this matrix's scale to the given x,y,z values. - * - * @param x This matrix's new x scale. - * @param y This matrix's new y scale. - * @param z This matrix's new z scale. - * @return this - */ - public Transform setScale(float x, float y, float z) { - scale.set(x, y, z); - return this; - } - - public Vector3f transformVector(final Vector3f in, Vector3f store) { - if (store == null) - store = new Vector3f(); - - // multiply with scale first, then rotate, finally translate (cf. - // Eberly) - return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation); - } - - public Vector3f transformInverseVector(final Vector3f in, Vector3f store) { - if (store == null) - store = new Vector3f(); - - // The author of this code should look above and take the inverse of - // that - // But for some reason, they didnt .. -// in.subtract(translation, store).divideLocal(scale); -// rot.inverse().mult(store, store); - - in.subtract(translation, store); - rot.inverse().mult(store, store); - store.divideLocal(scale); - - return store; - } - - /** - * Loads the identity. Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1. - */ - public void loadIdentity() { - translation.set(0, 0, 0); - scale.set(1, 1, 1); - rot.set(0, 0, 0, 1); - } - - @Override - public String toString() { - return getClass().getSimpleName() - + "[ " - + translation.x - + ", " - + translation.y - + ", " - + translation.z - + "]\n" - + "[ " - + rot.x - + ", " - + rot.y - + ", " - + rot.z - + ", " - + rot.w - + "]\n" - + "[ " - + scale.x - + " , " - + scale.y - + ", " - + scale.z - + "]"; - } - - /** - * Sets this matrix to be equal to the given matrix. - * - * @param matrixQuat The matrix to be equal to. - * @return this - */ - public Transform set(Transform matrixQuat) { - this.translation.set(matrixQuat.translation); - this.rot.set(matrixQuat.rot); - this.scale.set(matrixQuat.scale); - return this; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((rot == null) ? 0 : rot.hashCode()); - result = prime * result + ((scale == null) ? 0 : scale.hashCode()); - result = prime * result + ((translation == null) ? 0 : translation.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Transform other = (Transform) obj; - if (rot == null) { - if (other.rot != null) - return false; - } else if (!rot.equals(other.rot)) - return false; - if (scale == null) { - if (other.scale != null) - return false; - } else if (!scale.equals(other.scale)) - return false; - if (translation == null) { - if (other.translation != null) - return false; - } else if (!translation.equals(other.translation)) - return false; - return true; - } - - @Override - public Transform clone() { - try { - Transform tq = (Transform) super.clone(); - tq.rot = rot.clone(); - tq.scale = scale.clone(); - tq.translation = translation.clone(); - return tq; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } -} diff --git a/server/java/com/jme3/math/Vector2f.java b/server/java/com/jme3/math/Vector2f.java deleted file mode 100644 index 00b7805c1b..0000000000 --- a/server/java/com/jme3/math/Vector2f.java +++ /dev/null @@ -1,718 +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 com.jme3.math; - -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.util.logging.Logger; - - -/** - * Vector2f defines a Vector for a two float value vector. - * - * @author Mark Powell - * @author Joshua Slack - */ -public final class Vector2f implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - private static final Logger logger = Logger.getLogger(Vector2f.class.getName()); - - public static final Vector2f ZERO = new Vector2f(0f, 0f); - public static final Vector2f UNIT_XY = new Vector2f(1f, 1f); - - /** - * the x value of the vector. - */ - public float x; - /** - * the y value of the vector. - */ - public float y; - - /** - * Creates a Vector2f with the given initial x and y values. - * - * @param x The x value of this Vector2f. - * @param y The y value of this Vector2f. - */ - public Vector2f(float x, float y) { - this.x = x; - this.y = y; - } - - /** - * Creates a Vector2f with x and y set to 0. Equivalent to Vector2f(0,0). - */ - public Vector2f() { - x = y = 0; - } - - /** - * Creates a new Vector2f that contains the passed vector's information - * - * @param vector2f The vector to copy - */ - public Vector2f(Vector2f vector2f) { - this.x = vector2f.x; - this.y = vector2f.y; - } - - /** - * set the x and y values of the vector - * - * @param x the x value of the vector. - * @param y the y value of the vector. - * @return this vector - */ - public Vector2f set(float x, float y) { - this.x = x; - this.y = y; - return this; - } - - /** - * set the x and y values of the vector from another vector - * - * @param vec the vector to copy from - * @return this vector - */ - public Vector2f set(Vector2f vec) { - this.x = vec.x; - this.y = vec.y; - return this; - } - - /** - * add adds a provided vector to this vector creating a - * resultant vector which is returned. If the provided vector is null, null - * is returned. - * - * @param vec the vector to add to this. - * @return the resultant vector. - */ - public Vector2f add(Vector2f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - return new Vector2f(x + vec.x, y + vec.y); - } - - /** - * addLocal adds a provided vector to this vector internally, - * and returns a handle to this vector for easy chaining of calls. If the - * provided vector is null, null is returned. - * - * @param vec the vector to add to this vector. - * @return this - */ - public Vector2f addLocal(Vector2f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x += vec.x; - y += vec.y; - return this; - } - - /** - * addLocal adds the provided values to this vector internally, - * and returns a handle to this vector for easy chaining of calls. - * - * @param addX value to add to x - * @param addY value to add to y - * @return this - */ - public Vector2f addLocal(float addX, float addY) { - x += addX; - y += addY; - return this; - } - - /** - * add adds this vector by vec and stores the - * result in result. - * - * @param vec The vector to add. - * @param result The vector to store the result in. - * @return The result vector, after adding. - */ - public Vector2f add(Vector2f vec, Vector2f result) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - if (result == null) - result = new Vector2f(); - result.x = x + vec.x; - result.y = y + vec.y; - return result; - } - - /** - * dot calculates the dot product of this vector with a - * provided vector. If the provided vector is null, 0 is returned. - * - * @param vec the vector to dot with this vector. - * @return the resultant dot product of this vector and a given vector. - */ - public float dot(Vector2f vec) { - if (null == vec) { - logger.warning("Provided vector is null, 0 returned."); - return 0; - } - return x * vec.x + y * vec.y; - } - - /** - * cross calculates the cross product of this vector with a - * parameter vector v. - * - * @param v the vector to take the cross product of with this. - * @return the cross product vector. - */ - public Vector3f cross(Vector2f v) { - return new Vector3f(0, 0, determinant(v)); - } - - public float determinant(Vector2f v) { - return (x * v.y) - (y * v.x); - } - - /** - * Sets this vector to the interpolation by changeAmnt from this to the - * finalVec this=(1-changeAmnt)*this + changeAmnt * finalVec - * - * @param finalVec The final vector to interpolate towards - * @param changeAmnt An amount between 0.0 - 1.0 representing a percentage - * change from this towards finalVec - */ - public Vector2f interpolate(Vector2f finalVec, float changeAmnt) { - this.x = (1 - changeAmnt) * this.x + changeAmnt * finalVec.x; - this.y = (1 - changeAmnt) * this.y + changeAmnt * finalVec.y; - return this; - } - - /** - * Sets this vector to the interpolation by changeAmnt from beginVec to - * finalVec this=(1-changeAmnt)*beginVec + changeAmnt * finalVec - * - * @param beginVec The begining vector (delta=0) - * @param finalVec The final vector to interpolate towards (delta=1) - * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage - * change from beginVec towards finalVec - */ - public Vector2f interpolate( - Vector2f beginVec, - Vector2f finalVec, - float changeAmnt - ) { - this.x = (1 - changeAmnt) * beginVec.x + changeAmnt * finalVec.x; - this.y = (1 - changeAmnt) * beginVec.y + changeAmnt * finalVec.y; - return this; - } - - /** - * Check a vector... if it is null or its floats are NaN or infinite, return - * false. Else return true. - * - * @param vector the vector to check - * @return true or false as stated above. - */ - public static boolean isValidVector(Vector2f vector) { - if (vector == null) - return false; - if ( - Float.isNaN(vector.x) - || - Float.isNaN(vector.y) - ) - return false; - if ( - Float.isInfinite(vector.x) - || - Float.isInfinite(vector.y) - ) - return false; - return true; - } - - /** - * length calculates the magnitude of this vector. - * - * @return the length or magnitude of the vector. - */ - public float length() { - return FastMath.sqrt(lengthSquared()); - } - - /** - * lengthSquared calculates the squared value of the magnitude - * of the vector. - * - * @return the magnitude squared of the vector. - */ - public float lengthSquared() { - return x * x + y * y; - } - - /** - * distanceSquared calculates the distance squared between this - * vector and vector v. - * - * @param v the second vector to determine the distance squared. - * @return the distance squared between the two vectors. - */ - public float distanceSquared(Vector2f v) { - double dx = x - v.x; - double dy = y - v.y; - return (float) (dx * dx + dy * dy); - } - - /** - * distanceSquared calculates the distance squared between this - * vector and vector v. - * - * @param otherX The X coordinate of the v vector - * @param otherY The Y coordinate of the v vector - * @return the distance squared between the two vectors. - */ - public float distanceSquared(float otherX, float otherY) { - double dx = x - otherX; - double dy = y - otherY; - return (float) (dx * dx + dy * dy); - } - - /** - * distance calculates the distance between this vector and - * vector v. - * - * @param v the second vector to determine the distance. - * @return the distance between the two vectors. - */ - public float distance(Vector2f v) { - return FastMath.sqrt(distanceSquared(v)); - } - - /** - * mult multiplies this vector by a scalar. The resultant - * vector is returned. - * - * @param scalar the value to multiply this vector by. - * @return the new vector. - */ - public Vector2f mult(float scalar) { - return new Vector2f(x * scalar, y * scalar); - } - - /** - * multLocal multiplies this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. - * - * @param scalar the value to multiply this vector by. - * @return this - */ - public Vector2f multLocal(float scalar) { - x *= scalar; - y *= scalar; - return this; - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @return this - */ - public Vector2f multLocal(Vector2f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x *= vec.x; - y *= vec.y; - return this; - } - - /** - * Multiplies this Vector2f's x and y by the scalar and stores the result in - * product. The result is returned for chaining. Similar to - * product=this*scalar; - * - * @param scalar The scalar to multiply by. - * @param product The vector2f to store the result in. - * @return product, after multiplication. - */ - public Vector2f mult(float scalar, Vector2f product) { - if (null == product) { - product = new Vector2f(); - } - - product.x = x * scalar; - product.y = y * scalar; - return product; - } - - /** - * divide divides the values of this vector by a scalar and - * returns the result. The values of this vector remain untouched. - * - * @param scalar the value to divide this vectors attributes by. - * @return the result Vector. - */ - public Vector2f divide(float scalar) { - return new Vector2f(x / scalar, y / scalar); - } - - /** - * divideLocal divides this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. Dividing by - * zero will result in an exception. - * - * @param scalar the value to divides this vector by. - * @return this - */ - public Vector2f divideLocal(float scalar) { - x /= scalar; - y /= scalar; - return this; - } - - /** - * negate returns the negative of this vector. All values are - * negated and set to a new vector. - * - * @return the negated vector. - */ - public Vector2f negate() { - return new Vector2f(-x, -y); - } - - /** - * negateLocal negates the internal values of this vector. - * - * @return this. - */ - public Vector2f negateLocal() { - x = -x; - y = -y; - return this; - } - - /** - * subtract subtracts the values of a given vector from those - * of this vector creating a new vector object. If the provided vector is - * null, an exception is thrown. - * - * @param vec the vector to subtract from this vector. - * @return the result vector. - */ - public Vector2f subtract(Vector2f vec) { - return subtract(vec, null); - } - - /** - * subtract subtracts the values of a given vector from those - * of this vector storing the result in the given vector object. If the - * provided vector is null, an exception is thrown. - * - * @param vec the vector to subtract from this vector. - * @param store the vector to store the result in. It is safe for this to be - * the same as vec. If null, a new vector is created. - * @return the result vector. - */ - public Vector2f subtract(Vector2f vec, Vector2f store) { - if (store == null) - store = new Vector2f(); - store.x = x - vec.x; - store.y = y - vec.y; - return store; - } - - /** - * subtract subtracts the given x,y values from those of this - * vector creating a new vector object. - * - * @param valX value to subtract from x - * @param valY value to subtract from y - * @return this - */ - public Vector2f subtract(float valX, float valY) { - return new Vector2f(x - valX, y - valY); - } - - /** - * subtractLocal subtracts a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to subtract - * @return this - */ - public Vector2f subtractLocal(Vector2f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x -= vec.x; - y -= vec.y; - return this; - } - - /** - * subtractLocal subtracts the provided values from this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. - * - * @param valX value to subtract from x - * @param valY value to subtract from y - * @return this - */ - public Vector2f subtractLocal(float valX, float valY) { - x -= valX; - y -= valY; - return this; - } - - /** - * normalize returns the unit vector of this vector. - * - * @return unit vector of this vector. - */ - public Vector2f normalize() { - float length = length(); - if (length != 0) { - return divide(length); - } - - return divide(1); - } - - /** - * normalizeLocal makes this vector into a unit vector of - * itself. - * - * @return this. - */ - public Vector2f normalizeLocal() { - float length = length(); - if (length != 0) { - return divideLocal(length); - } - - return divideLocal(1); - } - - /** - * smallestAngleBetween returns (in radians) the minimum angle - * between two vectors. It is assumed that both this vector and the given - * vector are unit vectors (iow, normalized). - * - * @param otherVector a unit vector to find the angle against - * @return the angle in radians. - */ - public float smallestAngleBetween(Vector2f otherVector) { - float dotProduct = dot(otherVector); - float angle = FastMath.acos(dotProduct); - return angle; - } - - /** - * angleBetween returns (in radians) the angle required to - * rotate a ray represented by this vector to lie colinear to a ray - * described by the given vector. It is assumed that both this vector and - * the given vector are unit vectors (iow, normalized). - * - * @param otherVector the "destination" unit vector - * @return the angle in radians. - */ - public float angleBetween(Vector2f otherVector) { - float angle = FastMath.atan2(otherVector.y, otherVector.x) - - FastMath.atan2(y, x); - return angle; - } - - public float getX() { - return x; - } - - public Vector2f setX(float x) { - this.x = x; - return this; - } - - public float getY() { - return y; - } - - public Vector2f setY(float y) { - this.y = y; - return this; - } - - /** - * getAngle returns (in radians) the angle represented by this - * Vector2f as expressed by a conversion from rectangular coordinates - * (xy) to polar coordinates - * (r, theta). - * - * @return the angle in radians. [-pi, pi) - */ - public float getAngle() { - return FastMath.atan2(y, x); - } - - /** - * zero resets this vector's data to zero internally. - */ - public Vector2f zero() { - x = y = 0; - return this; - } - - /** - * hashCode returns a unique code for this vector object based - * on it's values. If two vectors are logically equivalent, they will return - * the same hash code value. - * - * @return the hash code value of this vector. - */ - @Override - public int hashCode() { - int hash = 37; - hash += 37 * hash + Float.floatToIntBits(x); - hash += 37 * hash + Float.floatToIntBits(y); - return hash; - } - - @Override - public Vector2f clone() { - try { - return (Vector2f) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } - - /** - * Saves this Vector2f into the given float[] object. - * - * @param floats The float[] to take this Vector2f. If null, a new float[2] - * is created. - * @return The array, with X, Y float values in that order - */ - public float[] toArray(float[] floats) { - if (floats == null) { - floats = new float[2]; - } - floats[0] = x; - floats[1] = y; - return floats; - } - - /** - * are these two vectors the same? they are is they both have the same x and - * y values. - * - * @param o the object to compare for equality - * @return true if they are equal - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Vector2f)) { - return false; - } - - if (this == o) { - return true; - } - - Vector2f comp = (Vector2f) o; - if (Float.compare(x, comp.x) != 0) - return false; - if (Float.compare(y, comp.y) != 0) - return false; - return true; - } - - /** - * toString returns the string representation of this vector - * object. The format of the string is such: com.jme.math.Vector2f - * [X=XX.XXXX, Y=YY.YYYY] - * - * @return the string representation of this vector. - */ - @Override - public String toString() { - return "(" + x + ", " + y + ")"; - } - - /** - * Used with serialization. Not to be called manually. - * - * @param in ObjectInput - * @throws IOException - * @throws ClassNotFoundException - * @see java.io.Externalizable - */ - public void readExternal(ObjectInput in) throws IOException, - ClassNotFoundException { - x = in.readFloat(); - y = in.readFloat(); - } - - /** - * Used with serialization. Not to be called manually. - * - * @param out ObjectOutput - * @throws IOException - * @see java.io.Externalizable - */ - public void writeExternal(ObjectOutput out) throws IOException { - out.writeFloat(x); - out.writeFloat(y); - } - - public void rotateAroundOrigin(float angle, boolean cw) { - if (cw) - angle = -angle; - float newX = FastMath.cos(angle) * x - FastMath.sin(angle) * y; - float newY = FastMath.sin(angle) * x + FastMath.cos(angle) * y; - x = newX; - y = newY; - } -} diff --git a/server/java/com/jme3/math/Vector3f.java b/server/java/com/jme3/math/Vector3f.java deleted file mode 100644 index 2d764e4ac4..0000000000 --- a/server/java/com/jme3/math/Vector3f.java +++ /dev/null @@ -1,1101 +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 com.jme3.math; - -import java.util.logging.Logger; - -import io.eiren.math.Vector3d; - -/* - * -- Added *Local methods to cut down on object creation - JS - */ - - -/** - * Vector3f defines a Vector for a three float value tuple. - * Vector3f can represent any three dimensional value, such as a - * vertex, a normal, etc. Utility methods are also included to aid in - * mathematical calculations. - * - * @author Mark Powell - * @author Joshua Slack - */ -public final class Vector3f implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - - private static final Logger logger = Logger.getLogger(Vector3f.class.getName()); - - public final static Vector3f ZERO = new Vector3f(0, 0, 0); - public final static Vector3f NAN = new Vector3f(Float.NaN, Float.NaN, Float.NaN); - public final static Vector3f UNIT_X = new Vector3f(1, 0, 0); - public final static Vector3f UNIT_Y = new Vector3f(0, 1, 0); - public final static Vector3f UNIT_X_Y = new Vector3f(1, 1, 0).normalizeLocal(); - public final static Vector3f UNIT_Z = new Vector3f(0, 0, 1); - public final static Vector3f UNIT_X_Z = new Vector3f(1, 0, 1).normalizeLocal(); - public final static Vector3f UNIT_Y_Z = new Vector3f(0, 1, 1).normalizeLocal(); - public final static Vector3f UNIT_X_Y_Z = new Vector3f(1, 1, 1).normalizeLocal(); - - - public final static Vector3f NEGATIVE_UNIT_X = new Vector3f(-1, 0, 0); - public final static Vector3f NEGATIVE_UNIT_Y = new Vector3f(0, -1, 0); - public final static Vector3f NEGATIVE_UNIT_Z = new Vector3f(0, 0, -1); - - public final static Vector3f UNIT_XYZ = new Vector3f(1, 1, 1); - public final static Vector3f POSITIVE_INFINITY = new Vector3f( - Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY - ); - public final static Vector3f NEGATIVE_INFINITY = new Vector3f( - Float.NEGATIVE_INFINITY, - Float.NEGATIVE_INFINITY, - Float.NEGATIVE_INFINITY - ); - - public final static Vector3f UNIT_PX_PY_PZ = UNIT_X_Y_Z; - public final static Vector3f UNIT_NX_PY_PZ = new Vector3f(-1, 1, 1).normalizeLocal(); - public final static Vector3f UNIT_PX_NY_PZ = new Vector3f(1, -1, 1).normalizeLocal(); - public final static Vector3f UNIT_NX_NY_PZ = new Vector3f(-1, -1, 1).normalizeLocal(); - public final static Vector3f UNIT_PX_PY_NZ = new Vector3f(1, 1, -1).normalizeLocal(); - public final static Vector3f UNIT_NX_PY_NZ = new Vector3f(-1, 1, -1).normalizeLocal(); - public final static Vector3f UNIT_PX_NY_NZ = new Vector3f(1, -1, -1).normalizeLocal(); - public final static Vector3f UNIT_NX_NY_NZ = new Vector3f(-1, -1, -1).normalizeLocal(); - - public final static Vector3f UNIT_PX_PY_0 = UNIT_X_Y; - public final static Vector3f UNIT_PX_NY_0 = new Vector3f(1, -1, 0).normalizeLocal(); - public final static Vector3f UNIT_NX_PY_0 = new Vector3f(-1, 1, 0).normalizeLocal(); - public final static Vector3f UNIT_NX_NY_0 = new Vector3f(-1, -1, 0).normalizeLocal(); - - public final static Vector3f UNIT_PX_0_PZ = UNIT_X_Z; - public final static Vector3f UNIT_PX_0_NZ = new Vector3f(1, 0, -1).normalizeLocal(); - public final static Vector3f UNIT_NX_0_PZ = new Vector3f(-1, 0, 1).normalizeLocal(); - public final static Vector3f UNIT_NX_0_NZ = new Vector3f(-1, 0, -1).normalizeLocal(); - - public final static Vector3f UNIT_0_PY_PZ = UNIT_Y_Z; - public final static Vector3f UNIT_0_PY_NZ = new Vector3f(0, 1, -1).normalizeLocal(); - public final static Vector3f UNIT_0_NY_PZ = new Vector3f(0, -1, 1).normalizeLocal(); - public final static Vector3f UNIT_0_NY_NZ = new Vector3f(0, -1, -1).normalizeLocal(); - - - /** - * the x value of the vector. - */ - public float x; - - /** - * the y value of the vector. - */ - public float y; - - /** - * the z value of the vector. - */ - public float z; - - /** - * Constructor instantiates a new Vector3f with default values - * of (0,0,0). - * - */ - public Vector3f() { - x = y = z = 0; - } - - /** - * Constructor instantiates a new Vector3f with provides - * values. - * - * @param x the x value of the vector. - * @param y the y value of the vector. - * @param z the z value of the vector. - */ - public Vector3f(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - } - - /** - * Constructor instantiates a new Vector3f that is a copy of - * the provided vector - * - * @param copy The Vector3f to copy - */ - public Vector3f(Vector3f copy) { - this.set(copy); - } - - public Vector3f(Vector3d copy) { - this.set((float) copy.x, (float) copy.y, (float) copy.z); - } - - /** - * set sets the x,y,z values of the vector based on passed - * parameters. - * - * @param x the x value of the vector. - * @param y the y value of the vector. - * @param z the z value of the vector. - * @return this vector - */ - public Vector3f set(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - return this; - } - - /** - * set sets the x,y,z values of the vector by copying the - * supplied vector. - * - * @param vect the vector to copy. - * @return this vector - */ - public Vector3f set(Vector3f vect) { - this.x = vect.x; - this.y = vect.y; - this.z = vect.z; - return this; - } - - /** - * - * add adds a provided vector to this vector creating a - * resultant vector which is returned. If the provided vector is null, null - * is returned. - * - * @param vec the vector to add to this. - * @return the resultant vector. - */ - public Vector3f add(Vector3f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - return new Vector3f(x + vec.x, y + vec.y, z + vec.z); - } - - /** - * - * add adds the values of a provided vector storing the values - * in the supplied vector. - * - * @param vec the vector to add to this - * @param result the vector to store the result in - * @return result returns the supplied result vector. - */ - public Vector3f add(Vector3f vec, Vector3f result) { - result.x = x + vec.x; - result.y = y + vec.y; - result.z = z + vec.z; - return result; - } - - /** - * addLocal adds a provided vector to this vector internally, - * and returns a handle to this vector for easy chaining of calls. If the - * provided vector is null, null is returned. - * - * @param vec the vector to add to this vector. - * @return this - */ - public Vector3f addLocal(Vector3f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x += vec.x; - y += vec.y; - z += vec.z; - return this; - } - - /** - * - * add adds the provided values to this vector, creating a new - * vector that is then returned. - * - * @param addX the x value to add. - * @param addY the y value to add. - * @param addZ the z value to add. - * @return the result vector. - */ - public Vector3f add(float addX, float addY, float addZ) { - return new Vector3f(x + addX, y + addY, z + addZ); - } - - /** - * - * add adds the provided values to this vector, creating a new - * vector that is then returned. - * - * @param addX the x value to add. - * @param addY the y value to add. - * @param addZ the z value to add. - * @param store the vector object to store the result in. if null, a new one - * is created. - * @return the result vector. - */ - public Vector3f add(float addX, float addY, float addZ, Vector3f store) { - if (store == null) { - return new Vector3f(x + addX, y + addY, z + addZ); - } else { - return store.set(x + addX, y + addY, z + addZ); - } - } - - /** - * addLocal adds the provided values to this vector internally, - * and returns a handle to this vector for easy chaining of calls. - * - * @param addX value to add to x - * @param addY value to add to y - * @param addZ value to add to z - * @return this - */ - public Vector3f addLocal(float addX, float addY, float addZ) { - x += addX; - y += addY; - z += addZ; - return this; - } - - /** - * - * scaleAdd multiplies this vector by a scalar then adds the - * given Vector3f. - * - * @param scalar the value to multiply this vector by. - * @param add the value to add - */ - public Vector3f scaleAdd(float scalar, Vector3f add) { - x = x * scalar + add.x; - y = y * scalar + add.y; - z = z * scalar + add.z; - return this; - } - - /** - * - * scaleAdd multiplies the given vector by a scalar then adds - * the given vector. - * - * @param scalar the value to multiply this vector by. - * @param mult the value to multiply the scalar by - * @param add the value to add - */ - public Vector3f scaleAdd(float scalar, Vector3f mult, Vector3f add) { - this.x = mult.x * scalar + add.x; - this.y = mult.y * scalar + add.y; - this.z = mult.z * scalar + add.z; - return this; - } - - /** - * - * dot calculates the dot product of this vector with a - * provided vector. If the provided vector is null, 0 is returned. - * - * @param vec the vector to dot with this vector. - * @return the resultant dot product of this vector and a given vector. - */ - public float dot(Vector3f vec) { - if (null == vec) { - logger.warning("Provided vector is null, 0 returned."); - return 0; - } - return x * vec.x + y * vec.y + z * vec.z; - } - - public float dot(float vx, float vy, float vz) { - return x * vx + y * vy + z * vz; - } - - /** - * cross calculates the cross product of this vector with a - * parameter vector v. - * - * @param v the vector to take the cross product of with this. - * @return the cross product vector. - */ - public Vector3f cross(Vector3f v) { - return cross(v, null); - } - - /** - * cross calculates the cross product of this vector with a - * parameter vector v. The result is stored in result - * - * @param v the vector to take the cross product of with this. - * @param result the vector to store the cross product result. - * @return result, after recieving the cross product vector. - */ - public Vector3f cross(Vector3f v, Vector3f result) { - return cross(v.x, v.y, v.z, result); - } - - /** - * cross calculates the cross product of this vector with a - * parameter vector v. The result is stored in result - * - * @param otherX x component of the vector to take the cross product of with - * this. - * @param otherY y component of the vector to take the cross product of with - * this. - * @param otherZ z component of the vector to take the cross product of with - * this. - * @param result the vector to store the cross product result. - * @return result, after recieving the cross product vector. - */ - public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) { - if (result == null) - result = new Vector3f(); - float resX = ((y * otherZ) - (z * otherY)); - float resY = ((z * otherX) - (x * otherZ)); - float resZ = ((x * otherY) - (y * otherX)); - result.set(resX, resY, resZ); - return result; - } - - /** - * crossLocal calculates the cross product of this vector with - * a parameter vector v. - * - * @param v the vector to take the cross product of with this. - * @return this. - */ - public Vector3f crossLocal(Vector3f v) { - return crossLocal(v.x, v.y, v.z); - } - - /** - * crossLocal calculates the cross product of this vector with - * a parameter vector v. - * - * @param otherX x component of the vector to take the cross product of with - * this. - * @param otherY y component of the vector to take the cross product of with - * this. - * @param otherZ z component of the vector to take the cross product of with - * this. - * @return this. - */ - public Vector3f crossLocal(float otherX, float otherY, float otherZ) { - float tempx = (y * otherZ) - (z * otherY); - float tempy = (z * otherX) - (x * otherZ); - z = (x * otherY) - (y * otherX); - x = tempx; - y = tempy; - return this; - } - - /** - * Projects this vector onto another vector - * - * @param other The vector to project this vector onto - * @return A new vector with the projection result - */ - public Vector3f project(Vector3f other) { - float n = this.dot(other); // A . B - float d = other.lengthSquared(); // |B|^2 - return new Vector3f(other).normalizeLocal().multLocal(n / d); - } - - /** - * Projects this vector onto another vector, stores the result in this - * vector - * - * @param other The vector to project this vector onto - * @return This Vector3f, set to the projection result - */ - public Vector3f projectLocal(Vector3f other) { - float n = this.dot(other); // A . B - float d = other.lengthSquared(); // |B|^2 - return set(other).normalizeLocal().multLocal(n / d); - } - - /** - * Returns true if this vector is a unit vector (length() ~= 1), returns - * false otherwise. - * - * @return true if this vector is a unit vector (length() ~= 1), or false - * otherwise. - */ - public boolean isUnitVector() { - float len = length(); - return 0.99f < len && len < 1.01f; - } - - /** - * length calculates the magnitude of this vector. - * - * @return the length or magnitude of the vector. - */ - public float length() { - return FastMath.sqrt(lengthSquared()); - } - - /** - * lengthSquared calculates the squared value of the magnitude - * of the vector. - * - * @return the magnitude squared of the vector. - */ - public float lengthSquared() { - return x * x + y * y + z * z; - } - - /** - * distanceSquared calculates the distance squared between this - * vector and vector v. - * - * @param v the second vector to determine the distance squared. - * @return the distance squared between the two vectors. - */ - public float distanceSquared(Vector3f v) { - double dx = x - v.x; - double dy = y - v.y; - double dz = z - v.z; - return (float) (dx * dx + dy * dy + dz * dz); - } - - /** - * distance calculates the distance between this vector and - * vector v. - * - * @param v the second vector to determine the distance. - * @return the distance between the two vectors. - */ - public float distance(Vector3f v) { - return FastMath.sqrt(distanceSquared(v)); - } - - /** - * - * mult multiplies this vector by a scalar. The resultant - * vector is returned. - * - * @param scalar the value to multiply this vector by. - * @return the new vector. - */ - public Vector3f mult(float scalar) { - return new Vector3f(x * scalar, y * scalar, z * scalar); - } - - /** - * - * mult multiplies this vector by a scalar. The resultant - * vector is supplied as the second parameter and returned. - * - * @param scalar the scalar to multiply this vector by. - * @param product the product to store the result in. - * @return product - */ - public Vector3f mult(float scalar, Vector3f product) { - if (null == product) { - product = new Vector3f(); - } - - product.x = x * scalar; - product.y = y * scalar; - product.z = z * scalar; - return product; - } - - /** - * multLocal multiplies this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. - * - * @param scalar the value to multiply this vector by. - * @return this - */ - public Vector3f multLocal(float scalar) { - x *= scalar; - y *= scalar; - z *= scalar; - return this; - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @return this - */ - public Vector3f multLocal(Vector3f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x *= vec.x; - y *= vec.y; - z *= vec.z; - return this; - } - - /** - * multLocal multiplies this vector by 3 scalars internally, - * and returns a handle to this vector for easy chaining of calls. - * - * @param x - * @param y - * @param z - * @return this - */ - public Vector3f multLocal(float x, float y, float z) { - this.x *= x; - this.y *= y; - this.z *= z; - return this; - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @return this - */ - public Vector3f mult(Vector3f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - return mult(vec, null); - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @param store result vector (null to create a new vector) - * @return this - */ - public Vector3f mult(Vector3f vec, Vector3f store) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - if (store == null) - store = new Vector3f(); - return store.set(x * vec.x, y * vec.y, z * vec.z); - } - - /** - * divide divides the values of this vector by a scalar and - * returns the result. The values of this vector remain untouched. - * - * @param scalar the value to divide this vectors attributes by. - * @return the result Vector. - */ - public Vector3f divide(float scalar) { - scalar = 1f / scalar; - return new Vector3f(x * scalar, y * scalar, z * scalar); - } - - public Vector3f divide(float scalar, Vector3f store) { - scalar = 1f / scalar; - return store.set(x * scalar, y * scalar, z * scalar); - } - - /** - * divideLocal divides this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. Dividing by - * zero will result in an exception. - * - * @param scalar the value to divides this vector by. - * @return this - */ - public Vector3f divideLocal(float scalar) { - scalar = 1f / scalar; - x *= scalar; - y *= scalar; - z *= scalar; - return this; - } - - /** - * divide divides the values of this vector by a scalar and - * returns the result. The values of this vector remain untouched. - * - * @param scalar the value to divide this vectors attributes by. - * @return the result Vector. - */ - public Vector3f divide(Vector3f scalar) { - return new Vector3f(x / scalar.x, y / scalar.y, z / scalar.z); - } - - /** - * divideLocal divides this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. Dividing by - * zero will result in an exception. - * - * @param scalar the value to divides this vector by. - * @return this - */ - public Vector3f divideLocal(Vector3f scalar) { - x /= scalar.x; - y /= scalar.y; - z /= scalar.z; - return this; - } - - /** - * - * negate returns the negative of this vector. All values are - * negated and set to a new vector. - * - * @return the negated vector. - */ - public Vector3f negate() { - return new Vector3f(-x, -y, -z); - } - - /** - * - * negateLocal negates the internal values of this vector. - * - * @return this. - */ - public Vector3f negateLocal() { - x = -x; - y = -y; - z = -z; - return this; - } - - /** - * - * subtract subtracts the values of a given vector from those - * of this vector creating a new vector object. If the provided vector is - * null, null is returned. - * - * @param vec the vector to subtract from this vector. - * @return the result vector. - */ - public Vector3f subtract(Vector3f vec) { - return new Vector3f(x - vec.x, y - vec.y, z - vec.z); - } - - /** - * subtractLocal subtracts a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to subtract - * @return this - */ - public Vector3f subtractLocal(Vector3f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x -= vec.x; - y -= vec.y; - z -= vec.z; - return this; - } - - /** - * - * subtract - * - * @param vec the vector to subtract from this - * @param result the vector to store the result in - * @return result - */ - public Vector3f subtract(Vector3f vec, Vector3f result) { - if (result == null) { - result = new Vector3f(); - } - result.x = x - vec.x; - result.y = y - vec.y; - result.z = z - vec.z; - return result; - } - - /** - * - * subtract subtracts the provided values from this vector, - * creating a new vector that is then returned. - * - * @param subtractX the x value to subtract. - * @param subtractY the y value to subtract. - * @param subtractZ the z value to subtract. - * @return the result vector. - */ - public Vector3f subtract(float subtractX, float subtractY, float subtractZ) { - return new Vector3f(x - subtractX, y - subtractY, z - subtractZ); - } - - /** - * subtractLocal subtracts the provided values from this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. - * - * @param subtractX the x value to subtract. - * @param subtractY the y value to subtract. - * @param subtractZ the z value to subtract. - * @return this - */ - public Vector3f subtractLocal(float subtractX, float subtractY, float subtractZ) { - x -= subtractX; - y -= subtractY; - z -= subtractZ; - return this; - } - - /** - * normalize returns the unit vector of this vector. - * - * @return unit vector of this vector. - */ - public Vector3f normalize() { - float length = x * x + y * y + z * z; - if (length != 1f && length != 0f) { - length = 1.0f / FastMath.sqrt(length); - return new Vector3f(x * length, y * length, z * length); - } - return clone(); - } - - public Vector3f normalize(Vector3f store) { - float length = x * x + y * y + z * z; - if (length != 1f && length != 0f) { - length = 1.0f / FastMath.sqrt(length); - return store.set(x * length, y * length, z * length); - } else { - return store.set(this); - } - } - - /** - * normalizeLocal makes this vector into a unit vector of - * itself. - * - * @return this - */ - public Vector3f normalizeLocal() { - // NOTE: this implementation is more optimized - // than the old jme normalize as this method - // is commonly used. - float length = x * x + y * y + z * z; - if (length != 1f && length != 0f) { - length = 1.0f / FastMath.sqrt(length); - x *= length; - y *= length; - z *= length; - } - return this; - } - - /** - * maxLocal computes the maximum value for each component in - * this and other vector. The result is stored in this vector. - * - * @param other - */ - public Vector3f maxLocal(Vector3f other) { - x = other.x > x ? other.x : x; - y = other.y > y ? other.y : y; - z = other.z > z ? other.z : z; - return this; - } - - /** - * minLocal computes the minimum value for each component in - * this and other vector. The result is stored in this vector. - * - * @param other - */ - public Vector3f minLocal(Vector3f other) { - x = other.x < x ? other.x : x; - y = other.y < y ? other.y : y; - z = other.z < z ? other.z : z; - return this; - } - - /** - * zero resets this vector's data to zero internally. - */ - public Vector3f zero() { - x = y = z = 0; - return this; - } - - /** - * angleBetween returns (in radians) the angle between two - * vectors. It is assumed that both this vector and the given vector are - * unit vectors (iow, normalized). - * - * @param otherVector a unit vector to find the angle against - * @return the angle in radians. - */ - public float angleBetween(Vector3f otherVector) { - float dotProduct = dot(otherVector); - float angle = FastMath.acos(dotProduct); - return angle; - } - - /** - * Sets this vector to the interpolation by changeAmnt from this to the - * finalVec this=(1-changeAmnt)*this + changeAmnt * finalVec - * - * @param finalVec The final vector to interpolate towards - * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage - * change from this towards finalVec - */ - public Vector3f interpolate(Vector3f finalVec, float changeAmnt) { - this.x = (1 - changeAmnt) * this.x + changeAmnt * finalVec.x; - this.y = (1 - changeAmnt) * this.y + changeAmnt * finalVec.y; - this.z = (1 - changeAmnt) * this.z + changeAmnt * finalVec.z; - return this; - } - - /** - * Sets this vector to the interpolation by changeAmnt from beginVec to - * finalVec this=(1-changeAmnt)*beginVec + changeAmnt * finalVec - * - * @param beginVec the beging vector (changeAmnt=0) - * @param finalVec The final vector to interpolate towards - * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage - * change from beginVec towards finalVec - */ - public Vector3f interpolate(Vector3f beginVec, Vector3f finalVec, float changeAmnt) { - this.x = (1 - changeAmnt) * beginVec.x + changeAmnt * finalVec.x; - this.y = (1 - changeAmnt) * beginVec.y + changeAmnt * finalVec.y; - this.z = (1 - changeAmnt) * beginVec.z + changeAmnt * finalVec.z; - return this; - } - - /** - * Check a vector... if it is null or its floats are NaN or infinite, return - * false. Else return true. - * - * @param vector the vector to check - * @return true or false as stated above. - */ - public static boolean isValidVector(Vector3f vector) { - if (vector == null) - return false; - if (Float.isNaN(vector.x) || Float.isNaN(vector.y) || Float.isNaN(vector.z)) - return false; - if (Float.isInfinite(vector.x) || Float.isInfinite(vector.y) || Float.isInfinite(vector.z)) - return false; - return true; - } - - public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) { - w.normalizeLocal(); - generateComplementBasis(u, v, w); - } - - public static void generateComplementBasis(Vector3f u, Vector3f v, Vector3f w) { - float fInvLength; - - if (FastMath.abs(w.x) >= FastMath.abs(w.y)) { - // w.x or w.z is the largest magnitude component, swap them - fInvLength = FastMath.invSqrt(w.x * w.x + w.z * w.z); - u.x = -w.z * fInvLength; - u.y = 0.0f; - u.z = +w.x * fInvLength; - v.x = w.y * u.z; - v.y = w.z * u.x - w.x * u.z; - v.z = -w.y * u.x; - } else { - // w.y or w.z is the largest magnitude component, swap them - fInvLength = FastMath.invSqrt(w.y * w.y + w.z * w.z); - u.x = 0.0f; - u.y = +w.z * fInvLength; - u.z = -w.y * fInvLength; - v.x = w.y * u.z - w.z * u.y; - v.y = -w.x * u.z; - v.z = w.x * u.y; - } - } - - @Override - public Vector3f clone() { - try { - return (Vector3f) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } - - /** - * Saves this Vector3f into the given float[] object. - * - * @param floats The float[] to take this Vector3f. If null, a new float[3] - * is created. - * @return The array, with X, Y, Z float values in that order - */ - public float[] toArray(float[] floats) { - if (floats == null) { - floats = new float[3]; - } - floats[0] = x; - floats[1] = y; - floats[2] = z; - return floats; - } - - /** - * are these two vectors the same? they are is they both have the same x,y, - * and z values. - * - * @param o the object to compare for equality - * @return true if they are equal - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Vector3f)) - return false; - if (this == o) - return true; - Vector3f comp = (Vector3f) o; - if (Float.compare(x, comp.x) != 0) - return false; - if (Float.compare(y, comp.y) != 0) - return false; - if (Float.compare(z, comp.z) != 0) - return false; - return true; - } - - /** - * hashCode returns a unique code for this vector object based - * on it's values. If two vectors are logically equivalent, they will return - * the same hash code value. - * - * @return the hash code value of this vector. - */ - @Override - public int hashCode() { - int hash = 37; - hash += 37 * hash + Float.floatToIntBits(x); - hash += 37 * hash + Float.floatToIntBits(y); - hash += 37 * hash + Float.floatToIntBits(z); - return hash; - } - - /** - * toString returns the string representation of this vector. - * The format is: - * - * org.jme.math.Vector3f [X=XX.XXXX, Y=YY.YYYY, Z=ZZ.ZZZZ] - * - * @return the string representation of this vector. - */ - @Override - public String toString() { - return "(" + x + ", " + y + ", " + z + ")"; - } - - public float getX() { - return x; - } - - public Vector3f setX(float x) { - this.x = x; - return this; - } - - public float getY() { - return y; - } - - public Vector3f setY(float y) { - this.y = y; - return this; - } - - public float getZ() { - return z; - } - - public Vector3f setZ(float z) { - this.z = z; - return this; - } - - /** - * @param index - * @return x value if index == 0, y value if index == 1 or z value if index - * == 2 - * @throws IllegalArgumentException if index is not one of 0, 1, 2. - */ - public float get(int index) { - switch (index) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - } - throw new IllegalArgumentException("index must be either 0, 1 or 2"); - } - - /** - * @param index which field index in this vector to set. - * @param value to set to one of x, y or z. - * @throws IllegalArgumentException if index is not one of 0, 1, 2. - */ - public void set(int index, float value) { - switch (index) { - case 0: - x = value; - return; - case 1: - y = value; - return; - case 2: - z = value; - return; - } - throw new IllegalArgumentException("index must be either 0, 1 or 2"); - } - - public static float angleBetweenVectors(Vector2f vec1, Vector2f vec2) { - return (float) Math - .atan2(vec1.x * vec2.y - vec1.y * vec2.x, vec1.x * vec2.x + vec1.y * vec2.y); - } -} diff --git a/server/java/com/jme3/math/Vector4f.java b/server/java/com/jme3/math/Vector4f.java deleted file mode 100644 index 20f101639e..0000000000 --- a/server/java/com/jme3/math/Vector4f.java +++ /dev/null @@ -1,971 +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 com.jme3.math; - -import java.util.logging.Logger; - - -/** - * Vector4f defines a Vector for a four float value tuple. - * Vector4f can represent any four dimensional value, such as a - * vertex, a normal, etc. Utility methods are also included to aid in - * mathematical calculations. - * - * @author Maarten Steur - */ -public final class Vector4f implements Cloneable, java.io.Serializable { - - static final long serialVersionUID = 1; - - private static final Logger logger = Logger.getLogger(Vector4f.class.getName()); - - public final static Vector4f ZERO = new Vector4f(0, 0, 0, 0); - public final static Vector4f NAN = new Vector4f(Float.NaN, Float.NaN, Float.NaN, Float.NaN); - public final static Vector4f UNIT_X = new Vector4f(1, 0, 0, 0); - public final static Vector4f UNIT_Y = new Vector4f(0, 1, 0, 0); - public final static Vector4f UNIT_Z = new Vector4f(0, 0, 1, 0); - public final static Vector4f UNIT_W = new Vector4f(0, 0, 0, 1); - public final static Vector4f UNIT_XYZW = new Vector4f(1, 1, 1, 1); - public final static Vector4f POSITIVE_INFINITY = new Vector4f( - Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY - ); - public final static Vector4f NEGATIVE_INFINITY = new Vector4f( - Float.NEGATIVE_INFINITY, - Float.NEGATIVE_INFINITY, - Float.NEGATIVE_INFINITY, - Float.NEGATIVE_INFINITY - ); - - /** - * the x value of the vector. - */ - public float x; - - /** - * the y value of the vector. - */ - public float y; - - /** - * the z value of the vector. - */ - public float z; - - /** - * the w value of the vector. - */ - public float w; - - /** - * Constructor instantiates a new Vector3f with default values - * of (0,0,0). - * - */ - public Vector4f() { - x = y = z = w = 0; - } - - /** - * Constructor instantiates a new Vector4f with provides - * values. - * - * @param x the x value of the vector. - * @param y the y value of the vector. - * @param z the z value of the vector. - * @param w the w value of the vector. - */ - public Vector4f(float x, float y, float z, float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - /** - * Constructor instantiates a new Vector3f that is a copy of - * the provided vector - * - * @param copy The Vector3f to copy - */ - public Vector4f(Vector4f copy) { - this.set(copy); - } - - /** - * set sets the x,y,z,w values of the vector based on passed - * parameters. - * - * @param x the x value of the vector. - * @param y the y value of the vector. - * @param z the z value of the vector. - * @param w the w value of the vector. - * @return this vector - */ - public Vector4f set(float x, float y, float z, float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - return this; - } - - /** - * set sets the x,y,z values of the vector by copying the - * supplied vector. - * - * @param vect the vector to copy. - * @return this vector - */ - public Vector4f set(Vector4f vect) { - this.x = vect.x; - this.y = vect.y; - this.z = vect.z; - this.w = vect.w; - return this; - } - - /** - * - * add adds a provided vector to this vector creating a - * resultant vector which is returned. If the provided vector is null, null - * is returned. - * - * @param vec the vector to add to this. - * @return the resultant vector. - */ - public Vector4f add(Vector4f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - return new Vector4f(x + vec.x, y + vec.y, z + vec.z, w + vec.w); - } - - /** - * - * add adds the values of a provided vector storing the values - * in the supplied vector. - * - * @param vec the vector to add to this - * @param result the vector to store the result in - * @return result returns the supplied result vector. - */ - public Vector4f add(Vector4f vec, Vector4f result) { - result.x = x + vec.x; - result.y = y + vec.y; - result.z = z + vec.z; - result.w = w + vec.w; - return result; - } - - /** - * addLocal adds a provided vector to this vector internally, - * and returns a handle to this vector for easy chaining of calls. If the - * provided vector is null, null is returned. - * - * @param vec the vector to add to this vector. - * @return this - */ - public Vector4f addLocal(Vector4f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x += vec.x; - y += vec.y; - z += vec.z; - w += vec.w; - return this; - } - - /** - * - * add adds the provided values to this vector, creating a new - * vector that is then returned. - * - * @param addX the x value to add. - * @param addY the y value to add. - * @param addZ the z value to add. - * @return the result vector. - */ - public Vector4f add(float addX, float addY, float addZ, float addW) { - return new Vector4f(x + addX, y + addY, z + addZ, w + addW); - } - - /** - * addLocal adds the provided values to this vector internally, - * and returns a handle to this vector for easy chaining of calls. - * - * @param addX value to add to x - * @param addY value to add to y - * @param addZ value to add to z - * @return this - */ - public Vector4f addLocal(float addX, float addY, float addZ, float addW) { - x += addX; - y += addY; - z += addZ; - w += addW; - return this; - } - - /** - * - * scaleAdd multiplies this vector by a scalar then adds the - * given Vector3f. - * - * @param scalar the value to multiply this vector by. - * @param add the value to add - */ - public Vector4f scaleAdd(float scalar, Vector4f add) { - x = x * scalar + add.x; - y = y * scalar + add.y; - z = z * scalar + add.z; - w = w * scalar + add.w; - return this; - } - - /** - * - * scaleAdd multiplies the given vector by a scalar then adds - * the given vector. - * - * @param scalar the value to multiply this vector by. - * @param mult the value to multiply the scalar by - * @param add the value to add - */ - public Vector4f scaleAdd(float scalar, Vector4f mult, Vector4f add) { - this.x = mult.x * scalar + add.x; - this.y = mult.y * scalar + add.y; - this.z = mult.z * scalar + add.z; - this.w = mult.w * scalar + add.w; - return this; - } - - /** - * - * dot calculates the dot product of this vector with a - * provided vector. If the provided vector is null, 0 is returned. - * - * @param vec the vector to dot with this vector. - * @return the resultant dot product of this vector and a given vector. - */ - public float dot(Vector4f vec) { - if (null == vec) { - logger.warning("Provided vector is null, 0 returned."); - return 0; - } - return x * vec.x + y * vec.y + z * vec.z + w * vec.w; - } - - public Vector4f project(Vector4f other) { - float n = this.dot(other); // A . B - float d = other.lengthSquared(); // |B|^2 - return new Vector4f(other).normalizeLocal().multLocal(n / d); - } - - /** - * Returns true if this vector is a unit vector (length() ~= 1), returns - * false otherwise. - * - * @return true if this vector is a unit vector (length() ~= 1), or false - * otherwise. - */ - public boolean isUnitVector() { - float len = length(); - return 0.99f < len && len < 1.01f; - } - - /** - * length calculates the magnitude of this vector. - * - * @return the length or magnitude of the vector. - */ - public float length() { - return FastMath.sqrt(lengthSquared()); - } - - /** - * lengthSquared calculates the squared value of the magnitude - * of the vector. - * - * @return the magnitude squared of the vector. - */ - public float lengthSquared() { - return x * x + y * y + z * z + w * w; - } - - /** - * distanceSquared calculates the distance squared between this - * vector and vector v. - * - * @param v the second vector to determine the distance squared. - * @return the distance squared between the two vectors. - */ - public float distanceSquared(Vector4f v) { - double dx = x - v.x; - double dy = y - v.y; - double dz = z - v.z; - double dw = w - v.w; - return (float) (dx * dx + dy * dy + dz * dz + dw * dw); - } - - /** - * distance calculates the distance between this vector and - * vector v. - * - * @param v the second vector to determine the distance. - * @return the distance between the two vectors. - */ - public float distance(Vector4f v) { - return FastMath.sqrt(distanceSquared(v)); - } - - /** - * - * mult multiplies this vector by a scalar. The resultant - * vector is returned. - * - * @param scalar the value to multiply this vector by. - * @return the new vector. - */ - public Vector4f mult(float scalar) { - return new Vector4f(x * scalar, y * scalar, z * scalar, w * scalar); - } - - /** - * - * mult multiplies this vector by a scalar. The resultant - * vector is supplied as the second parameter and returned. - * - * @param scalar the scalar to multiply this vector by. - * @param product the product to store the result in. - * @return product - */ - public Vector4f mult(float scalar, Vector4f product) { - if (null == product) { - product = new Vector4f(); - } - - product.x = x * scalar; - product.y = y * scalar; - product.z = z * scalar; - product.w = w * scalar; - return product; - } - - /** - * multLocal multiplies this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. - * - * @param scalar the value to multiply this vector by. - * @return this - */ - public Vector4f multLocal(float scalar) { - x *= scalar; - y *= scalar; - z *= scalar; - w *= scalar; - return this; - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @return this - */ - public Vector4f multLocal(Vector4f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x *= vec.x; - y *= vec.y; - z *= vec.z; - w *= vec.w; - return this; - } - - /** - * multLocal multiplies this vector by 3 scalars internally, - * and returns a handle to this vector for easy chaining of calls. - * - * @param x - * @param y - * @param z - * @param w - * @return this - */ - public Vector4f multLocal(float x, float y, float z, float w) { - this.x *= x; - this.y *= y; - this.z *= z; - this.w *= w; - return this; - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @return this - */ - public Vector4f mult(Vector4f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - return mult(vec, null); - } - - /** - * multLocal multiplies a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to mult to this vector. - * @param store result vector (null to create a new vector) - * @return this - */ - public Vector4f mult(Vector4f vec, Vector4f store) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - if (store == null) - store = new Vector4f(); - return store.set(x * vec.x, y * vec.y, z * vec.z, w * vec.w); - } - - /** - * divide divides the values of this vector by a scalar and - * returns the result. The values of this vector remain untouched. - * - * @param scalar the value to divide this vectors attributes by. - * @return the result Vector. - */ - public Vector4f divide(float scalar) { - scalar = 1f / scalar; - return new Vector4f(x * scalar, y * scalar, z * scalar, w * scalar); - } - - /** - * divideLocal divides this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. Dividing by - * zero will result in an exception. - * - * @param scalar the value to divides this vector by. - * @return this - */ - public Vector4f divideLocal(float scalar) { - scalar = 1f / scalar; - x *= scalar; - y *= scalar; - z *= scalar; - w *= scalar; - return this; - } - - /** - * divide divides the values of this vector by a scalar and - * returns the result. The values of this vector remain untouched. - * - * @param scalar the value to divide this vectors attributes by. - * @return the result Vector. - */ - public Vector4f divide(Vector4f scalar) { - return new Vector4f(x / scalar.x, y / scalar.y, z / scalar.z, w / scalar.w); - } - - /** - * divideLocal divides this vector by a scalar internally, and - * returns a handle to this vector for easy chaining of calls. Dividing by - * zero will result in an exception. - * - * @param scalar the value to divides this vector by. - * @return this - */ - public Vector4f divideLocal(Vector4f scalar) { - x /= scalar.x; - y /= scalar.y; - z /= scalar.z; - w /= scalar.w; - return this; - } - - /** - * - * negate returns the negative of this vector. All values are - * negated and set to a new vector. - * - * @return the negated vector. - */ - public Vector4f negate() { - return new Vector4f(-x, -y, -z, -w); - } - - /** - * - * negateLocal negates the internal values of this vector. - * - * @return this. - */ - public Vector4f negateLocal() { - x = -x; - y = -y; - z = -z; - w = -w; - return this; - } - - /** - * - * subtract subtracts the values of a given vector from those - * of this vector creating a new vector object. If the provided vector is - * null, null is returned. - * - * @param vec the vector to subtract from this vector. - * @return the result vector. - */ - public Vector4f subtract(Vector4f vec) { - return new Vector4f(x - vec.x, y - vec.y, z - vec.z, w - vec.w); - } - - /** - * subtractLocal subtracts a provided vector to this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. If the provided vector is null, null is returned. - * - * @param vec the vector to subtract - * @return this - */ - public Vector4f subtractLocal(Vector4f vec) { - if (null == vec) { - logger.warning("Provided vector is null, null returned."); - return null; - } - x -= vec.x; - y -= vec.y; - z -= vec.z; - w -= vec.w; - return this; - } - - /** - * - * subtract - * - * @param vec the vector to subtract from this - * @param result the vector to store the result in - * @return result - */ - public Vector4f subtract(Vector4f vec, Vector4f result) { - if (result == null) { - result = new Vector4f(); - } - result.x = x - vec.x; - result.y = y - vec.y; - result.z = z - vec.z; - result.w = w - vec.w; - return result; - } - - /** - * - * subtract subtracts the provided values from this vector, - * creating a new vector that is then returned. - * - * @param subtractX the x value to subtract. - * @param subtractY the y value to subtract. - * @param subtractZ the z value to subtract. - * @param subtractW the w value to subtract. - * @return the result vector. - */ - public Vector4f subtract(float subtractX, float subtractY, float subtractZ, float subtractW) { - return new Vector4f(x - subtractX, y - subtractY, z - subtractZ, w - subtractW); - } - - /** - * subtractLocal subtracts the provided values from this vector - * internally, and returns a handle to this vector for easy chaining of - * calls. - * - * @param subtractX the x value to subtract. - * @param subtractY the y value to subtract. - * @param subtractZ the z value to subtract. - * @param subtractW the w value to subtract. - * @return this - */ - public Vector4f subtractLocal( - float subtractX, - float subtractY, - float subtractZ, - float subtractW - ) { - x -= subtractX; - y -= subtractY; - z -= subtractZ; - w -= subtractW; - return this; - } - - /** - * normalize returns the unit vector of this vector. - * - * @return unit vector of this vector. - */ - public Vector4f normalize() { -// float length = length(); -// if (length != 0) { -// return divide(length); -// } -// -// return divide(1); - float length = x * x + y * y + z * z + w * w; - if (length != 1f && length != 0f) { - length = 1.0f / FastMath.sqrt(length); - return new Vector4f(x * length, y * length, z * length, w * length); - } - return clone(); - } - - /** - * normalizeLocal makes this vector into a unit vector of - * itself. - * - * @return this. - */ - public Vector4f normalizeLocal() { - // NOTE: this implementation is more optimized - // than the old jme normalize as this method - // is commonly used. - float length = x * x + y * y + z * z + w * w; - if (length != 1f && length != 0f) { - length = 1.0f / FastMath.sqrt(length); - x *= length; - y *= length; - z *= length; - w *= length; - } - return this; - } - - /** - * maxLocal computes the maximum value for each component in - * this and other vector. The result is stored in this vector. - * - * @param other - */ - public Vector4f maxLocal(Vector4f other) { - x = other.x > x ? other.x : x; - y = other.y > y ? other.y : y; - z = other.z > z ? other.z : z; - w = other.w > w ? other.w : w; - return this; - } - - /** - * minLocal computes the minimum value for each component in - * this and other vector. The result is stored in this vector. - * - * @param other - */ - public Vector4f minLocal(Vector4f other) { - x = other.x < x ? other.x : x; - y = other.y < y ? other.y : y; - z = other.z < z ? other.z : z; - w = other.w < w ? other.w : w; - return this; - } - - /** - * zero resets this vector's data to zero internally. - */ - public Vector4f zero() { - x = y = z = w = 0; - return this; - } - - /** - * angleBetween returns (in radians) the angle between two - * vectors. It is assumed that both this vector and the given vector are - * unit vectors (iow, normalized). - * - * @param otherVector a unit vector to find the angle against - * @return the angle in radians. - */ - public float angleBetween(Vector4f otherVector) { - float dotProduct = dot(otherVector); - float angle = FastMath.acos(dotProduct); - return angle; - } - - /** - * Sets this vector to the interpolation by changeAmnt from this to the - * finalVec this=(1-changeAmnt)*this + changeAmnt * finalVec - * - * @param finalVec The final vector to interpolate towards - * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage - * change from this towards finalVec - */ - public Vector4f interpolate(Vector4f finalVec, float changeAmnt) { - this.x = (1 - changeAmnt) * this.x + changeAmnt * finalVec.x; - this.y = (1 - changeAmnt) * this.y + changeAmnt * finalVec.y; - this.z = (1 - changeAmnt) * this.z + changeAmnt * finalVec.z; - this.w = (1 - changeAmnt) * this.w + changeAmnt * finalVec.w; - return this; - } - - /** - * Sets this vector to the interpolation by changeAmnt from beginVec to - * finalVec this=(1-changeAmnt)*beginVec + changeAmnt * finalVec - * - * @param beginVec the beging vector (changeAmnt=0) - * @param finalVec The final vector to interpolate towards - * @param changeAmnt An amount between 0.0 - 1.0 representing a precentage - * change from beginVec towards finalVec - */ - public Vector4f interpolate(Vector4f beginVec, Vector4f finalVec, float changeAmnt) { - this.x = (1 - changeAmnt) * beginVec.x + changeAmnt * finalVec.x; - this.y = (1 - changeAmnt) * beginVec.y + changeAmnt * finalVec.y; - this.z = (1 - changeAmnt) * beginVec.z + changeAmnt * finalVec.z; - this.w = (1 - changeAmnt) * beginVec.w + changeAmnt * finalVec.w; - return this; - } - - /** - * Check a vector... if it is null or its floats are NaN or infinite, return - * false. Else return true. - * - * @param vector the vector to check - * @return true or false as stated above. - */ - public static boolean isValidVector(Vector4f vector) { - if (vector == null) - return false; - if ( - Float.isNaN(vector.x) - || - Float.isNaN(vector.y) - || - Float.isNaN(vector.z) - || - Float.isNaN(vector.w) - ) - return false; - if ( - Float.isInfinite(vector.x) - || - Float.isInfinite(vector.y) - || - Float.isInfinite(vector.z) - || - Float.isInfinite(vector.w) - ) - return false; - return true; - } - - @Override - public Vector4f clone() { - try { - return (Vector4f) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); // can not happen - } - } - - /** - * Saves this Vector3f into the given float[] object. - * - * @param floats The float[] to take this Vector3f. If null, a new float[3] - * is created. - * @return The array, with X, Y, Z float values in that order - */ - public float[] toArray(float[] floats) { - if (floats == null) { - floats = new float[4]; - } - floats[0] = x; - floats[1] = y; - floats[2] = z; - floats[3] = w; - return floats; - } - - /** - * are these two vectors the same? they are is they both have the same x,y, - * and z values. - * - * @param o the object to compare for equality - * @return true if they are equal - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof Vector4f)) { - return false; - } - - if (this == o) { - return true; - } - - Vector4f comp = (Vector4f) o; - if (Float.compare(x, comp.x) != 0) - return false; - if (Float.compare(y, comp.y) != 0) - return false; - if (Float.compare(z, comp.z) != 0) - return false; - if (Float.compare(w, comp.w) != 0) - return false; - return true; - } - - /** - * hashCode returns a unique code for this vector object based - * on it's values. If two vectors are logically equivalent, they will return - * the same hash code value. - * - * @return the hash code value of this vector. - */ - @Override - public int hashCode() { - int hash = 37; - hash += 37 * hash + Float.floatToIntBits(x); - hash += 37 * hash + Float.floatToIntBits(y); - hash += 37 * hash + Float.floatToIntBits(z); - hash += 37 * hash + Float.floatToIntBits(w); - return hash; - } - - /** - * toString returns the string representation of this vector. - * The format is: - * - * org.jme.math.Vector3f [X=XX.XXXX, Y=YY.YYYY, Z=ZZ.ZZZZ, W=WW.WWWW] - * - * @return the string representation of this vector. - */ - @Override - public String toString() { - return "(" + x + ", " + y + ", " + z + ", " + w + ")"; - } - - public float getX() { - return x; - } - - public Vector4f setX(float x) { - this.x = x; - return this; - } - - public float getY() { - return y; - } - - public Vector4f setY(float y) { - this.y = y; - return this; - } - - public float getZ() { - return z; - } - - public Vector4f setZ(float z) { - this.z = z; - return this; - } - - public float getW() { - return w; - } - - public Vector4f setW(float w) { - this.w = w; - return this; - } - - /** - * @param index - * @return x value if index == 0, y value if index == 1 or z value if index - * == 2 - * @throws IllegalArgumentException if index is not one of 0, 1, 2. - */ - public float get(int index) { - switch (index) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - case 3: - return w; - } - throw new IllegalArgumentException("index must be either 0, 1, 2 or 3"); - } - - /** - * @param index which field index in this vector to set. - * @param value to set to one of x, y, z or w. - * @throws IllegalArgumentException if index is not one of 0, 1, 2, 3. - */ - public void set(int index, float value) { - switch (index) { - case 0: - x = value; - return; - case 1: - y = value; - return; - case 2: - z = value; - return; - case 3: - w = value; - return; - } - throw new IllegalArgumentException("index must be either 0, 1, 2 or 3"); - } - -} diff --git a/server/java/com/jme3/system/NanoTimer.java b/server/java/com/jme3/system/NanoTimer.java deleted file mode 100644 index b99dcf2dd3..0000000000 --- a/server/java/com/jme3/system/NanoTimer.java +++ /dev/null @@ -1,105 +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 com.jme3.system; - -/** - * NanoTimer is a System.nanoTime implementation of - * Timer. This is primarily useful for headless applications - * running on a server. - * - * @author Matthew D. Hicks - */ -public class NanoTimer extends Timer { - - private static final long TIMER_RESOLUTION = 1000000000L; - private static final float INVERSE_TIMER_RESOLUTION = 1f / TIMER_RESOLUTION; - - private long startTime; - private long previousTime; - private float tpf; - private float fps; - private long currentTime; - - public NanoTimer() { - startTime = System.nanoTime(); - } - - /** - * Returns the time in seconds. The timer starts at 0.0 seconds. - * - * @return the current time in seconds - */ - - protected long getTimeInternal() { - return System.nanoTime() - startTime; - } - - @Override - public float getTimeInSeconds() { - return getTime() * INVERSE_TIMER_RESOLUTION; - } - - @Override - public long getTime() { - return currentTime; - } - - @Override - public long getResolution() { - return TIMER_RESOLUTION; - } - - @Override - public float getFrameRate() { - return fps; - } - - @Override - public float getTimePerFrame() { - return tpf; - } - - @Override - public void update() { - currentTime = getTimeInternal(); - tpf = (currentTime - previousTime) * (1.0f / TIMER_RESOLUTION); - fps = 1.0f / tpf; - previousTime = getTime(); - } - - @Override - public void reset() { - startTime = System.nanoTime(); - currentTime = getTimeInternal(); - previousTime = getTime(); - } -} diff --git a/server/java/com/jme3/system/Timer.java b/server/java/com/jme3/system/Timer.java deleted file mode 100644 index ea0a61dfc8..0000000000 --- a/server/java/com/jme3/system/Timer.java +++ /dev/null @@ -1,93 +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 com.jme3.system; - -/** - * Timer is the base class for a high resolution timer. It is - * created from getTimer("display system") - * - * @author Mark Powell - * @version $Id: Timer.java,v 1.18 2007/03/09 10:19:34 rherlitz Exp $ - */ -public abstract class Timer { - - /** - * Returns the current time in ticks. A tick is an arbitrary measure of time - * defined by the timer implementation. The number of ticks per second is - * given by getResolution(). The timer starts at 0 ticks. - * - * @return a long value representing the current time - */ - public abstract long getTime(); - - /** - * Returns the time in seconds. The timer starts at 0.0 seconds. - * - * @return the current time in seconds - */ - public float getTimeInSeconds() { - return getTime() / (float) getResolution(); - } - - /** - * Returns the resolution of the timer. - * - * @return the number of timer ticks per second - */ - public abstract long getResolution(); - - /** - * Returns the "calls per second". If this is called every frame, then it - * will return the "frames per second". - * - * @return The "calls per second". - */ - public abstract float getFrameRate(); - - /** - * Returns the time, in seconds, between the last call and the current one. - * - * @return Time between this call and the last one. - */ - public abstract float getTimePerFrame(); - - /** - * update recalculates the frame rate based on the previous - * call to update. It is assumed that update is called each frame. - */ - public abstract void update(); - - /** - * Reset the timer to 0. Clear any tpf history. - */ - public abstract void reset(); -} diff --git a/server/java/com/jme3/util/TempVars.java b/server/java/com/jme3/util/TempVars.java deleted file mode 100644 index 46f33010d1..0000000000 --- a/server/java/com/jme3/util/TempVars.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 com.jme3.util; - -import com.jme3.math.*; - - -/** - * Temporary variables assigned to each thread. Engine classes may access these - * temp variables with TempVars.get(), all retrieved TempVars instances must be - * returned via TempVars.release(). This returns an available instance of the - * TempVar class ensuring this particular instance is never used elsewhere in - * the mean time. - */ -public class TempVars { - - /** - * Allow X instances of TempVars in a single thread. - */ - private static final int STACK_SIZE = 5; - - /** - * TempVarsStack contains a stack of TempVars. Every time - * TempVars.get() is called, a new entry is added to the stack, and the - * index incremented. When TempVars.release() is called, the entry is - * checked against the current instance and then the index is decremented. - */ - private static class TempVarsStack { - - int index = 0; - TempVars[] tempVars = new TempVars[STACK_SIZE]; - } - - /** - * ThreadLocal to store a TempVarsStack for each thread. This ensures each - * thread has a single TempVarsStack that is used only in method calls in - * that thread. - */ - private static final ThreadLocal varsLocal = new ThreadLocal() { - - @Override - public TempVarsStack initialValue() { - return new TempVarsStack(); - } - }; - /** - * This instance of TempVars has been retrieved but not released yet. - */ - private boolean isUsed = false; - - private TempVars() { - } - - /** - * Acquire an instance of the TempVar class. You have to release the - * instance after use by calling the release() method. If more than - * STACK_SIZE (currently 5) instances are requested in a single thread then - * an ArrayIndexOutOfBoundsException will be thrown. - * - * @return A TempVar instance - */ - public static TempVars get() { - TempVarsStack stack = varsLocal.get(); - - TempVars instance = stack.tempVars[stack.index]; - - if (instance == null) { - // Create new - instance = new TempVars(); - - // Put it in there - stack.tempVars[stack.index] = instance; - } - - stack.index++; - - instance.isUsed = true; - - return instance; - } - - /** - * Releases this instance of TempVars. Once released, the contents of the - * TempVars are undefined. The TempVars must be released in the opposite - * order that they are retrieved, e.g. Acquiring vars1, then acquiring - * vars2, vars2 MUST be released first otherwise an exception will be - * thrown. - */ - public void release() { - if (!isUsed) { - throw new IllegalStateException("This instance of TempVars was already released!"); - } - - isUsed = false; - - TempVarsStack stack = varsLocal.get(); - - // Return it to the stack - stack.index--; - - // Check if it is actually there - if (stack.tempVars[stack.index] != this) { - throw new IllegalStateException( - "An instance of TempVars has not been released in a called method!" - ); - } - } - - /** - * Color - */ - public final ColorRGBA color = new ColorRGBA(); - /** - * General vectors. - */ - public final Vector3f vect1 = new Vector3f(); - public final Vector3f vect2 = new Vector3f(); - public final Vector3f vect3 = new Vector3f(); - public final Vector3f vect4 = new Vector3f(); - public final Vector3f vect5 = new Vector3f(); - public final Vector3f vect6 = new Vector3f(); - public final Vector3f vect7 = new Vector3f(); - // seems the maximum number of vector used is 7 in com.jme3.bounding.java - public final Vector3f vect8 = new Vector3f(); - public final Vector3f vect9 = new Vector3f(); - public final Vector3f vect10 = new Vector3f(); - public final Vector4f vect4f = new Vector4f(); - public final Vector3f[] tri = { new Vector3f(), - new Vector3f(), - new Vector3f() }; - /** - * 2D vector - */ - public final Vector2f vect2d = new Vector2f(); - public final Vector2f vect2d2 = new Vector2f(); - /** - * General matrices. - */ - public final Matrix3f tempMat3 = new Matrix3f(); - public final Matrix4f tempMat4 = new Matrix4f(); - public final Matrix4f tempMat42 = new Matrix4f(); - /** - * General quaternions. - */ - public final Quaternion quat1 = new Quaternion(); - public final Quaternion quat2 = new Quaternion(); - - public final float[] matrixWrite = new float[16]; -} diff --git a/server/java/io/eiren/math/FloatMath.java b/server/java/io/eiren/math/FloatMath.java deleted file mode 100644 index 90320fd62c..0000000000 --- a/server/java/io/eiren/math/FloatMath.java +++ /dev/null @@ -1,672 +0,0 @@ -package io.eiren.math; - -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.math.Vector4f; - - -public class FloatMath { - - public static final float PI = (float) Math.PI; - public static final float TWO_PI = (float) (Math.PI * 2); - public static final float ANGLE_EPSILON = 0.028f; // in degrees (float - // epsilon for sin/cos) - public static final float ANGLE_EPSILON_RAD = toRad(ANGLE_EPSILON); - - public static final float ZERO_TOLERANCE_F = FastMath.ZERO_TOLERANCE; - public static final double ZERO_TOLERANCE_D = 0.0001d; - - public static final float SQRT_TWO = (float) Math.sqrt(2f); - public static final float INV_SQRT_TWO = 1f / SQRT_TWO; - public static final float SQRT_THREE = (float) Math.sqrt(3f); - public static final float INV_SQRT_THREE = 1f / SQRT_THREE; - public static final float TWO_FPI = PI * 2; - - public static final float SIN_75_DEG = 0.965926f; - public static final float SIN_60_DEG = 0.866025f; - public static final float SIN_45_DEG = 0.707107f; - public static final float SIN_30_DEG = 0.5f; - public static final float SIN_15_DEG = 0.258819f; - - public static final float COS_75_DEG = 0.258819f; - public static final float COS_60_DEG = 0.5f; - public static final float COS_45_DEG = 0.707107f; - public static final float COS_30_DEG = 0.866025f; - public static final float COS_15_DEG = 0.965926f; - - public static final int TEN_BITS = ~(~0 << 10); - public static final int TENTH_BIT = 1 << 10; - public static final int TEN_BITS_MAX = ~(~0 << 9); - public static final int TEN_BITS_MAX_UNSIGNED = ~(~0 << 10); - public static final int TWO_BITS = ~(~0 << 2); - public static final int SECOND_BIT = 1 << 2; - public static final int TWO_BITS_MAX = ~(~0 << 1); - public static final int TWO_BITS_MAX_UNSIGNED = ~(~0 << 2); - - public static float roundIfZero(float x) { - return Math.abs(x) < ZERO_TOLERANCE_F ? 0.0f : x; - } - - public static boolean equalsToZero(float x) { - return Math.abs(x) < ZERO_TOLERANCE_F; - } - - public static boolean lessThanZero(float x) { - return (x < -ZERO_TOLERANCE_F); - } - - public static boolean lessOrEqualsToZero(float x) { - return (x < ZERO_TOLERANCE_F); - } - - public static boolean greaterThanZero(float x) { - return (x > ZERO_TOLERANCE_F); - } - - public static boolean greaterOrEqualsToZero(float x) { - return (x > -ZERO_TOLERANCE_F); - } - - public static boolean equalsToZero(float x, float epsilon) { - return Math.abs(x) < epsilon; - } - - public static boolean equalsWithEpsilon(float x, float y) { - return Math.abs(x - y) < ZERO_TOLERANCE_F; - } - - public static boolean equalsWithEpsilon(float x, float y, float epsilon) { - return Math.abs(x - y) < epsilon; - } - - public static boolean lessWithEpsilon(float x, float y) { - return (x < y - ZERO_TOLERANCE_F); - } - - public static boolean lessOrEqualsWithEpsilon(float x, float y) { - return (x < y + ZERO_TOLERANCE_F); - } - - public static boolean lessWithEpsilon(float x, float y, float epsilon) { - return (x < y - epsilon); - } - - public static boolean lessOrEqualsWithEpsilon(float x, float y, float epsilon) { - return (x < y + epsilon); - } - - public static boolean greaterWithEpsilon(float x, float y) { - return (x > y + ZERO_TOLERANCE_F); - } - - public static boolean greaterOrEqualsWithEpsilon(float x, float y) { - return (x > y - ZERO_TOLERANCE_F); - } - - public static boolean greaterWithEpsilon(float x, float y, float epsilon) { - return (x > y + epsilon); - } - - public static boolean greaterOrEqualsWithEpsilon(float x, float y, float epsilon) { - return (x > y - epsilon); - } - - public static double roundIfZero(double x) { - return Math.abs(x) < ZERO_TOLERANCE_D ? 0.0d : x; - } - - public static boolean equalsToZero(double x) { - return Math.abs(x) < ZERO_TOLERANCE_D; - } - - public static boolean equalsWithEpsilon(double x, double y) { - return Math.abs(x - y) < ZERO_TOLERANCE_D; - } - - public static boolean lessWithEpsilon(double x, double y) { - return (x < y - ZERO_TOLERANCE_D); - } - - public static boolean lessOrEqualsWithEpsilon(double x, double y) { - return (x < y + ZERO_TOLERANCE_D); - } - - public static boolean greaterWithEpsilon(double x, double y) { - return (x > y + ZERO_TOLERANCE_D); - } - - public static boolean greaterOrEqualsWithEpsilon(double x, double y) { - return (x > y - ZERO_TOLERANCE_D); - } - - public static float toDegrees(float angrad) { - return angrad * 180.0f / PI; - } - - public static float toRad(float deg) { - return deg / 180.0f * PI; - } - - public static boolean radEqual(float angle1, float angle2) { - float diff = clampRad(angle1 - angle2); - return Math.abs(diff) < ANGLE_EPSILON_RAD; - } - - public static boolean degreesEqual(float angle1, float angle2) { - float diff = clampDegrees(angle1 - angle2); - return Math.abs(diff) < ANGLE_EPSILON; - } - - /** - * @deprecated use {@link #normalizeRad(float)} - */ - @Deprecated - public static float clampRad(float angle) { - return normalizeRad(angle); - } - - public static float normalizeRad(float angle) { - return FastMath.normalize(angle, -FastMath.PI, FastMath.PI); - } - - /** - * @deprecated use {@link #normalizeDegrees(float)} - */ - @Deprecated - public static float clampDegrees(float angle) { - return normalizeDegrees(angle); - } - - public static float normalizeDegrees(float angle) { - return FastMath.normalize(angle, -180f, 180f); - } - - public static float animateEase(float t) { - // Special case of Bezier interpolation (p0 = p1 = 0, p2 = p3 = 1) - return (3.0f - 2.0f * t) * t * t; - } - - public static float animateEaseIn(float t) { - return t * t; - } - - /** - * Lineary remaps value from the source interval to the target interval. - * details - */ - public static float mapValue( - float value, - float sourceStart, - float sourceEnd, - float targetStart, - float targetEnd - ) { - return targetStart - + (value - sourceStart) * (targetEnd - targetStart) / (sourceEnd - sourceStart); - } - - /** - * Clamps the given value and remaps to the target interval. - *

- * Note the source interval values should be sorted. - */ - public static float mapValueWithClampBefore( - float value, - float sourceBottom, - float sourceTop, - float targetBottom, - float targetTop - ) { - return mapValue( - clamp(value, sourceBottom, sourceTop), - sourceBottom, - sourceTop, - targetBottom, - targetTop - ); - } - - /** - * Remaps the given value to the target interval and clamps. - *

- * Note the target interval values should be sorted. - */ - public static float mapValueWithClampAfter( - float value, - float sourceBottom, - float sourceTop, - float targetBottom, - float targetTop - ) { - return clamp( - mapValue(value, sourceBottom, sourceTop, targetBottom, targetTop), - targetBottom, - targetTop - ); - } - - public static 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 * (3f - 2f * x); - } - - public static float smootherstep(float edge0, float edge1, float x) { - // Scale, and clamp x to 0..1 range - x = FastMath.clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); - // Evaluate polynomial - return x * x * x * (x * (x * 6f - 15f) + 10f); - } - - /** - * Applies linear contrast (with clamping). - * - * @param t - input value in range (0..1) - * @param k - contrast factor in range (-1..1): - *

- * @return contrasted value in range (0..1) - */ - public static float contrastLinear(float t, float k) { - float x = 2f * t - 1f; // -1..1 - float gamma = (1f + k) / (1f - k); - float f = FastMath.clamp(gamma * x, -1f, 1f); // -1..1 - return 0.5f * (f + 1f); // 0..1 - } - - /** - * Applies non-linear contrast by power function. - * - * @param t - input value in range (0..1) - * @param k - contrast factor in range (-1..1) exclusive: - * - * @return contrasted value in range (0..1) - */ - public static float contrastPower(float t, float k) { - float x = 2f * t - 1f; // -1..1 - float gamma = (1f - k) / (1f + k); - float f = FastMath.sign(x) * FastMath.pow(FastMath.abs(x), gamma); // -1..1 - return 0.5f * (f + 1f); // 0..1 - } - - /** - * Applies non-linear contrast by square splines. - * - * @param t - input value in range (0..1) - * @param k - contrast factor in range (-1..1): - * - * @return contrasted value in range (0..1) - */ - public static float contrastQuadricSpline(float t, float k) { - float x = 2f * t - 1f; // -1..1 - float f = x * (1f + k * (1f - FastMath.abs(x))); // -1..1 - return 0.5f * (f + 1f); // 0..1 - } - - /** - * Applies non-linear contrast by square splines inverted function. - * - * @param t - input value in range (0..1) - * @param k - contrast factor in range (-2..2): - * - * @return contrasted value in range (0..1) - */ - public static float contrastInvertQuadricSpline(float t, float k) { - float x = 2f * t - 1f; // -1..1 - float g; - if (k > 0) { - g = FastMath.sign(x) * FastMath.sqrt(FastMath.abs(x)) - 2f * x; - } else { - g = FastMath.sign(x) * (FastMath.sqrt(1f - FastMath.abs(x)) - 1f); - } - float f = (1f + k) * x + k * g; // -1..1 - return 0.5f * (f + 1f); // 0..1 - } - - /** - * Applies non-linear contrast by cubic splines. - * - * @param t - input value in range (0..1) - * @param k - contrast factor in range (-1..1): - * - * @return contrasted value in range (0..1) - */ - public static float contrastCubicSpline(float t, float k) { - float x = 2f * t - 1f; // -1..1 - float f = x * (1f + FastMath.abs(k) * (x * x - 1f)); - if (k < 0) - f -= x * 3f * k * (1f - FastMath.abs(x)); - return 0.5f * (f + 1f); // 0..1 - } - - public static float fraction(float f) { - return f - (int) f; - } - - public static double fraction(double d) { - return d - (long) d; - } - - /** - * @deprecated Do not copy {@link Math} methods. - */ - @Deprecated - public static float min(float a, float b) { - return a > b ? b : a; - } - - public static float min(float a, float b, float c) { - return Math.min(Math.min(a, b), c); - } - - public static float min(float a, float b, float c, float d) { - return Math.min(Math.min(a, b), Math.min(c, d)); - } - - /** - * @deprecated Do not copy {@link Math} methods. - */ - @Deprecated - public static float max(float a, float b) { - return a > b ? a : b; - } - - public static float max(float a, float b, float c) { - return Math.max(Math.max(a, b), c); - } - - public static float max(float a, float b, float c, float d) { - return Math.max(Math.max(a, b), Math.max(c, d)); - } - - public static float cos(float value) { - return (float) Math.cos(value); - } - - public static float sin(float value) { - return (float) Math.sin(value); - } - - public static float ceil(float value) { - return (float) Math.ceil(value); - } - - public static float floor(float value) { - return (float) Math.floor(value); - } - - public static float pow(float value, float power) { - return (float) Math.pow(value, power); - } - - /** - * @deprecated Do not copy {@link Math} methods. - */ - @Deprecated - public static float abs(float value) { - return (float) Math.abs(value); - } - - /** - * @deprecated Do not copy {@link Math} methods. - */ - @Deprecated - public static float round(float value) { - return (float) Math.round(value); - } - - public static float sqrt(float value) { - return (float) Math.sqrt(value); - } - - public static float distance(float x0, float y0, float z0, float x1, float y1, float z1) { - return distance(x1 - x0, y1 - y0, z1 - z0); - } - - public static float distance(float x, float y, float z) { - return sqrt(sqrDistance(x, y, z)); - } - - public static float sqrDistance(float x, float y, float z) { - return x * x + y * y + z * z; - } - - public static float distance(float x, float y) { - return sqrt(sqrDistance(x, y)); - } - - public static float sqrDistance(float x, float y) { - return x * x + y * y; - } - - public static float sqrDistance(Vector3f v, float x1, float y1, float z1) { - return sqrDistance(x1 - v.x, y1 - v.y, z1 - v.z); - } - - public static float sqrDistance(float x0, float y0, float z0, float x1, float y1, float z1) { - return sqrDistance(x1 - x0, y1 - y0, z1 - z0); - } - - public static float hypot(float x, float y) { - return FastMath.sqrt(x * x + y * y); - } - - public static float hypot(float x, float y, float z) { - return FastMath.sqrt(x * x + y * y + z * z); - } - - /** - * The same as FastMath.clamp - */ - public static float clamp(float value, float min, float max) { - if (value <= min) - return min; - if (value >= max) - return max; - return value; - } - - public static Vector3f int2101010RevToFloats(int packedValue, Vector3f store) { - if (store == null) - store = new Vector3f(); - store.x = packedValue & TEN_BITS_MAX; - if ((packedValue & TENTH_BIT) != 0) - store.x *= -1; - store.y = (packedValue >>> 10) & TEN_BITS_MAX; - if ((packedValue & (TENTH_BIT << 10)) != 0) - store.y *= -1; - store.z = (packedValue >>> 20) & TEN_BITS_MAX; - if ((packedValue & (TENTH_BIT << 20)) != 0) - store.z *= -1; - return store; - } - - public static int floatToInt210101Rev(Vector3f values) { - int store = 0; - store |= ((int) values.x) & TEN_BITS_MAX; - if (values.x < 0) - store |= TENTH_BIT; - store |= (((int) values.y) & TEN_BITS_MAX) << 10; - if (values.y < 0) - store |= TENTH_BIT << 10; - store |= (((int) values.z) & TEN_BITS_MAX) << 20; - if (values.z < 0) - store |= TENTH_BIT << 20; - return store; - } - - public static int floatToInt210101RevNormalized(Vector3f values) { - int store = 0; - store |= ((int) (values.x * TEN_BITS)) & TEN_BITS_MAX; - if (values.x < 0) - store |= TENTH_BIT; - store |= (((int) (values.y * TEN_BITS)) & TEN_BITS_MAX) << 10; - if (values.y < 0) - store |= TENTH_BIT << 10; - store |= (((int) (values.z * TEN_BITS)) & TEN_BITS_MAX) << 20; - if (values.z < 0) - store |= TENTH_BIT << 20; - return store; - } - - public static int floatToUnsignedInt210101Rev(Vector3f values) { - int store = 0; - store |= ((int) values.x) & TEN_BITS; - store |= (((int) values.y) & TEN_BITS) << 10; - store |= (((int) values.z) & TEN_BITS) << 20; - return store; - } - - public static int floatToUnsignedInt210101RevNormalized(Vector3f values) { - int store = 0; - store |= ((int) (values.x * TEN_BITS)) & TEN_BITS; - store |= (((int) (values.y * TEN_BITS)) & TEN_BITS) << 10; - store |= (((int) (values.z * TEN_BITS)) & TEN_BITS) << 20; - return store; - } - - public static int floatToInt210101Rev(float x, float y, float z) { - int store = 0; - store |= ((int) x) & TEN_BITS_MAX; - if (x < 0) - store |= TENTH_BIT; - store |= (((int) y) & TEN_BITS_MAX) << 10; - if (y < 0) - store |= TENTH_BIT << 10; - store |= (((int) z) & TEN_BITS_MAX) << 20; - if (z < 0) - store |= TENTH_BIT << 20; - return store; - } - - public static int floatToUnsignedInt210101Rev(float x, float y, float z) { - int store = 0; - store |= ((int) x) & TEN_BITS; - store |= (((int) y) & TEN_BITS) << 10; - store |= (((int) z) & TEN_BITS) << 20; - return store; - } - - public static Vector4f int2101010RevToFloats(int packedValue, Vector4f store) { - if (store == null) - store = new Vector4f(); - store.x = packedValue & TEN_BITS_MAX; - if ((packedValue & TENTH_BIT) != 0) - store.x *= -1; - store.y = (packedValue >>> 10) & TEN_BITS_MAX; - if ((packedValue & (TENTH_BIT << 10)) != 0) - store.y *= -1; - store.z = (packedValue >>> 20) & TEN_BITS_MAX; - if ((packedValue & (TENTH_BIT << 20)) != 0) - store.z *= -1; - store.w = (packedValue >>> 30) & TWO_BITS_MAX; - if ((packedValue & (SECOND_BIT << 30)) != 0) - store.w *= -1; - return store; - } - - public static int floatToInt210101Rev(Vector4f values) { - int store = 0; - store |= ((int) values.x) & TEN_BITS_MAX; - if (values.x < 0) - store |= TENTH_BIT; - store |= (((int) values.y) & TEN_BITS_MAX) << 10; - if (values.y < 0) - store |= TENTH_BIT << 10; - store |= (((int) values.z) & TEN_BITS_MAX) << 20; - if (values.z < 0) - store |= TENTH_BIT << 20; - store |= (((int) values.z) & TWO_BITS_MAX) << 30; - if (values.w < 0) - store |= SECOND_BIT << 30; - return store; - } - - public static int floatToUnsignedInt210101Rev(Vector4f values) { - int store = 0; - store |= ((int) values.x) & TEN_BITS; - store |= (((int) values.y) & TEN_BITS) << 10; - store |= (((int) values.z) & TEN_BITS) << 20; - store |= (((int) values.z) & TWO_BITS) << 30; - return store; - } - - public static Vector3f unsignedInt2101010RevToFloats(int packedValue, Vector3f store) { - if (store == null) - store = new Vector3f(); - store.x = packedValue & TEN_BITS; - store.y = (packedValue >>> 10) & TEN_BITS; - store.z = (packedValue >>> 20) & TEN_BITS; - return store; - } - - public static Vector4f unsignedInt2101010RevToFloats(int packedValue, Vector4f store) { - if (store == null) - store = new Vector4f(); - store.x = packedValue & TEN_BITS; - store.y = (packedValue >>> 10) & TEN_BITS; - store.z = (packedValue >>> 20) & TEN_BITS; - store.w = (packedValue >>> 30) & TWO_BITS; - return store; - } - - public static Vector3f int2101010RevNormalizedToFloats(int packedValue, Vector3f store) { - store = int2101010RevToFloats(packedValue, store); - store.x /= TEN_BITS_MAX; - store.y /= TEN_BITS_MAX; - store.z /= TEN_BITS_MAX; - return store; - } - - public static Vector4f int2101010RevNormalizedToFloats(int packedValue, Vector4f store) { - store = int2101010RevToFloats(packedValue, store); - store.x /= TEN_BITS_MAX; - store.y /= TEN_BITS_MAX; - store.z /= TEN_BITS_MAX; - store.w /= TWO_BITS_MAX; - return store; - } - - public static Vector3f unsignedInt2101010RevNormalizedToFloats( - int packedValue, - Vector3f store - ) { - store = unsignedInt2101010RevToFloats(packedValue, store); - store.x /= TEN_BITS; - store.y /= TEN_BITS; - store.z /= TEN_BITS; - return store; - } - - public static Vector4f unsignedInt2101010RevNormalizedToFloats( - int packedValue, - Vector4f store - ) { - store = unsignedInt2101010RevToFloats(packedValue, store); - store.x /= TEN_BITS; - store.y /= TEN_BITS; - store.z /= TEN_BITS; - store.w /= TWO_BITS; - return store; - } -} diff --git a/server/java/io/eiren/math/Vector3d.java b/server/java/io/eiren/math/Vector3d.java deleted file mode 100644 index 14a1806920..0000000000 --- a/server/java/io/eiren/math/Vector3d.java +++ /dev/null @@ -1,257 +0,0 @@ -package io.eiren.math; - -import com.jme3.math.Vector3f; - - -public class Vector3d implements Cloneable { - - public double x; - public double y; - public double z; - - public Vector3d() { - } - - public Vector3d(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Vector3d(double x1, double y1, double z1, double x2, double y2, double z2) { - this.x = x2 - x1; - this.y = y2 - y1; - this.z = z2 - z1; - } - - public Vector3d(Vector3f src) { - this(src.x, src.y, src.z); - } - - public Vector3d set(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - return this; - } - - public Vector3d set(Vector3d v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - return this; - } - - public Vector3d add(double addX, double addY, double addZ) { - return new Vector3d(this.x + addX, this.y + addY, this.z + addZ); - } - - public Vector3d addLocal(Vector3d vec) { - return addLocal(vec.x, vec.y, vec.z); - } - - public Vector3d addLocal(double addX, double addY, double addZ) { - x += addX; - y += addY; - z += addZ; - return this; - } - - public Vector3d substract(double subX, double subY, double subZ) { - return new Vector3d(this.x - subX, this.y - subY, this.z - subZ); - } - - public Vector3d substractLocal(Vector3d vec) { - if (null == vec) { - return null; - } - x -= vec.x; - y -= vec.y; - z -= vec.z; - return this; - } - - public Vector3d substractLocal(double subX, double subY, double subZ) { - x -= subX; - y -= subY; - z -= subZ; - return this; - } - - public Vector3d negate() { - return new Vector3d(-x, -y, -z); - } - - public Vector3d negateLocal() { - x = -x; - y = -y; - z = -z; - return this; - } - - public Vector3d mult(double scalar) { - return new Vector3d(x * scalar, y * scalar, z * scalar); - } - - public Vector3d multLocal(double scalar) { - x *= scalar; - y *= scalar; - z *= scalar; - return this; - } - - public Vector3d divide(double scalar) { - return new Vector3d(x / scalar, y / scalar, z / scalar); - } - - public Vector3d divideLocal(double scalar) { - x /= scalar; - y /= scalar; - z /= scalar; - return this; - } - - public double dot(Vector3d v) { - return x * v.x + y * v.y + z * v.z; - } - - public double dot(double vx, double vy, double vz) { - return x * vx + y * vy + z * vz; - } - - public Vector3d cross(Vector3d other, Vector3d result) { - if (result == null) - result = new Vector3d(); - double resX = ((y * other.z) - (z * other.y)); - double resY = ((z * other.x) - (x * other.z)); - double resZ = ((x * other.y) - (y * other.x)); - result.set(resX, resY, resZ); - return result; - } - - @Override - public Vector3d clone() { - return new Vector3d(this.x, this.y, this.z); - } - - public Vector3d normalize() { - double length = x * x + y * y + z * z; - if (length != 1.0 && length != 0.0) { - double invLength = 1.0 / Math.sqrt(length); - return mult(invLength); - } - return clone(); - } - - public Vector3d normalizeLocal() { - double length = x * x + y * y + z * z; - if (length != 1.0 && length != 0.0) { - length = Math.sqrt(length); - double invLength = 1.0 / length; - x *= invLength; - z *= invLength; - y *= invLength; - } - return this; - } - - public Vector3f toVector3f() { - return new Vector3f((float) x, (float) y, (float) z); - } - - public double length() { - return Math.sqrt(x * x + y * y + z * z); - } - - public double lengthSquared() { - return x * x + y * y + z * z; - } - - @Override - public String toString() { - return new StringBuilder("Vector3D{") - .append(x) - .append(',') - .append(y) - .append(',') - .append(z) - .append('}') - .toString(); - } - - public void rotateAroundX(float f) { - double f1 = Math.cos(f); - double f2 = Math.sin(f); - double d = x; - double d1 = y * f1 + z * f2; - double d2 = z * f1 - y * f2; - x = (float) d; - y = (float) d1; - z = (float) d2; - } - - public void rotateAroundY(float f) { - double f1 = Math.cos(f); - double f2 = Math.sin(f); - double d = x * f1 + z * f2; - double d1 = y; - double d2 = z * f1 - x * f2; - x = (float) d; - y = (float) d1; - z = (float) d2; - } - - public double distanceTo(Vector3d vec3d) { - return Math.sqrt(squaredDistance(vec3d)); - } - - public double squaredDistance(Vector3d point) { - return squaredDistance(point.x, point.y, point.z); - } - - public double squaredDistance(double toX, double toY, double toZ) { - return (this.x - toX) * (this.x - toX) - + (this.y - toY) * (this.y - toY) - + (this.z - toZ) * (this.z - toZ); - } - - public Vector3d add(Vector3d dir) { - return add(dir.x, dir.y, dir.z); - } - - public Vector3d substract(Vector3d dir) { - return substract(dir.x, dir.y, dir.z); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - long temp; - temp = Double.doubleToLongBits(x); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(y); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(z); - result = prime * result + (int) (temp ^ (temp >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Vector3d other = (Vector3d) obj; - if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) - return false; - if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) - return false; - if (Double.doubleToLongBits(z) != Double.doubleToLongBits(other.z)) - return false; - return true; - } -} diff --git a/server/java/io/eiren/util/BufferedTimer.java b/server/java/io/eiren/util/BufferedTimer.java deleted file mode 100644 index 4bba98941a..0000000000 --- a/server/java/io/eiren/util/BufferedTimer.java +++ /dev/null @@ -1,130 +0,0 @@ -package io.eiren.util; - -import java.beans.ConstructorProperties; - -import com.jme3.system.NanoTimer; - - -/** - * This timer accumulate measured TPF and returns average/min/max FPS value - */ -public class BufferedTimer extends NanoTimer { - - private final float measureInterval; - private float averageTpf; - private float averageFps; - private float averageFrameRenderTime; - private float sumFrameRenderTime; - private float sumTpf; - private float minFpsCurrent; - private float maxFpsCurrent; - private float maxFps; - private float minFps; - private int count; - private boolean measured = false; - - /** - * Measure average tpf over the provided inverval in seconds - * - * @param measureInterval interval to measure averages over - */ - public BufferedTimer(float measureInterval) { - averageFps = 0; - sumTpf = 0; - count = 0; - this.measureInterval = measureInterval; - } - - public float getAverageFPS() { - return averageFps; - } - - public float getMinFPS() { - return minFps; - } - - public float getMaxFPS() { - return maxFps; - } - - public void addRenderTime(float renderTime) { - sumFrameRenderTime += renderTime; - } - - public float getAverageFrameRenderTime() { - return averageFrameRenderTime; - } - - public boolean isMeasured() { - if (measured) { - measured = false; - return true; - } - return false; - } - - public TimerSample getCurrentData() { - return new TimerSample(getFrameRate(), minFps, maxFps, averageFps); - } - - @Override - public void update() { - super.update(); - // Accumulate instant rate - sumTpf += getTimePerFrame(); - float fps = getFrameRate(); - if (fps < minFpsCurrent) - minFpsCurrent = fps; - if (fps > maxFpsCurrent) - maxFpsCurrent = fps; - ++count; - // Calculate results once per measure interval - if (!measured || sumTpf > measureInterval) { - // Average results - averageTpf = sumTpf / count; - averageFps = 1.0f / averageTpf; - averageFrameRenderTime = sumFrameRenderTime / count; - minFps = minFpsCurrent; - maxFps = maxFpsCurrent; - // Reset counter - sumTpf = 0; - sumFrameRenderTime = 0; - minFpsCurrent = Float.MAX_VALUE; - maxFpsCurrent = 0; - count = 0; - measured = true; - } - } - - public static class TimerSample { - - public float fps; - public float minFps; - public float maxFps; - public float averageFps; - - @ConstructorProperties({ "fps", "minFps", "maxFps", "averageFps" }) - public TimerSample(float fps, float minFps, float maxFps, float averageFps) { - this.fps = fps; - this.minFps = minFps; - this.maxFps = maxFps; - this.averageFps = averageFps; - } - - public float getFps() { - return fps; - } - - public float getMinFps() { - return minFps; - } - - public float getMaxFps() { - return maxFps; - } - - public float getAverageFps() { - return averageFps; - } - } -} diff --git a/server/java/io/eiren/util/MacOSX.java b/server/java/io/eiren/util/MacOSX.java deleted file mode 100644 index e9f027123c..0000000000 --- a/server/java/io/eiren/util/MacOSX.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.eiren.util; - -import java.awt.Image; -import java.awt.Toolkit; -import java.lang.reflect.Method; -import java.util.List; - - -public class MacOSX { - - public static void setIcons(List icons) { - try { - Class applicationClass = Class.forName("com.apple.eawt.Application"); - Method m = applicationClass.getDeclaredMethod("getApplication"); - Object application = m.invoke(null); - m = application.getClass().getDeclaredMethod("setDockIconImage", Image.class); - m.invoke(application, icons.get(icons.size() - 1)); - } catch (Exception e) {} - } - - public static void setTitle(String title) { - try { - Class applicationClass = Class.forName("com.apple.eawt.Application"); - Method m = applicationClass.getDeclaredMethod("getApplication"); - Object application = m.invoke(null); - m = application.getClass().getDeclaredMethod("setDockIconImage", String.class); - m.invoke(application, title); - } catch (Exception e) {} - } - - public static boolean hasRetinaDisplay() { - Object obj = Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor"); - if (obj instanceof Float) { - Float f = (Float) obj; - int scale = f.intValue(); - return (scale == 2); // 1 indicates a regular mac display. - } - return false; - } - -} diff --git a/server/java/io/eiren/util/OperatingSystem.java b/server/java/io/eiren/util/OperatingSystem.java deleted file mode 100644 index 7182e7df23..0000000000 --- a/server/java/io/eiren/util/OperatingSystem.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.eiren.util; - -import java.io.File; - - -public enum OperatingSystem { - - //@formatter:off - LINUX("linux", new String[]{"linux", "unix"}), - WINDOWS("windows", new String[]{"win"}), - OSX("osx", new String[]{"mac"}), - UNKNOWN("unknown", new String[0]); - //@fomatter: on - - private final String[] aliases; - public final String name; - private static OperatingSystem currentPlatform; - - private OperatingSystem(String name, String[] aliases) { - this.aliases = aliases; - this.name = name; - } - - public static String getJavaExecutable(boolean forceConsole) { - String separator = System.getProperty("file.separator"); - String path = System.getProperty("java.home") + separator + "bin" + separator; - if(getCurrentPlatform() == WINDOWS) { - if(!forceConsole && new File(path + "javaw.exe").isFile()) - return path + "javaw.exe"; - return path + "java.exe"; - } - return path + "java"; - } - - public static OperatingSystem getCurrentPlatform() { - if(currentPlatform != null) - return currentPlatform; - String osName = System.getProperty("os.name").toLowerCase(); - for(OperatingSystem os : values()) { - for(String alias : os.aliases) { - if(osName.contains(alias)) - return currentPlatform = os; - } - } - return UNKNOWN; - } -} \ No newline at end of file diff --git a/server/java/io/eiren/util/StringUtils.java b/server/java/io/eiren/util/StringUtils.java deleted file mode 100644 index 7ee9369640..0000000000 --- a/server/java/io/eiren/util/StringUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.eiren.util; - -import java.text.DecimalFormatSymbols; -import java.util.Locale; - - -public class StringUtils { - - private static char DECIMAL_SEP; - - public static char getDecimalSeparator() { - if (DECIMAL_SEP == '\u0000') { - final Locale l = Locale.getDefault(Locale.Category.FORMAT); - // Formatter.java always use "." in the Locale.US - DECIMAL_SEP = (l == null || l.equals(Locale.US) - ? '.' - : DecimalFormatSymbols.getInstance(l).getDecimalSeparator()); - } - return DECIMAL_SEP; - } - - public static String prettyNumber(float f) { - return prettyNumber(f, 4); - } - - public static String prettyNumber(float f, int numDigits) { - String str = String.format("%." + numDigits + "f", f); - if (numDigits != 0) - str = org.apache.commons.lang3.StringUtils.stripEnd(str, "0"); - char lastChar = str.charAt(str.length() - 1); - if (lastChar == getDecimalSeparator()) - str = str.substring(0, str.length() - 1); - return str; - } -} diff --git a/server/java/io/eiren/util/Util.java b/server/java/io/eiren/util/Util.java deleted file mode 100644 index 85fe39b57d..0000000000 --- a/server/java/io/eiren/util/Util.java +++ /dev/null @@ -1,176 +0,0 @@ -package io.eiren.util; - -import java.io.Closeable; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - - -public class Util { - - public static void close(Object r) { - try { - if (r != null) { - if (r instanceof Closeable) - ((Closeable) r).close(); - else if (r instanceof AutoCloseable) - ((AutoCloseable) r).close(); - } - } catch (Exception e) {} - } - - public static void close(Object r1, Object r2) { - close(r1); - close(r2); - } - - public static void close(Object... r) { - for (int i = 0; i < r.length; ++i) - try { - if (r[i] != null) { - if (r[i] instanceof Closeable) - ((Closeable) r[i]).close(); - else if (r[i] instanceof AutoCloseable) - ((AutoCloseable) r[i]).close(); - } - } catch (Exception e) {} - } - - public static void close(AutoCloseable... r) { - for (int i = 0; i < r.length; ++i) - try { - if (r[i] != null) - r[i].close(); - } catch (Exception e) {} - } - - public static void close(Closeable... r) { - for (int i = 0; i < r.length; ++i) - try { - if (r[i] != null) - r[i].close(); - } catch (Exception e) {} - } - - /** - *

- * Performs a deep toString of provided object. It shows content of arrays, - * collections and maps (trove not supported yet). - *

- *

- * Highly ineffective, use only for debug. - *

- * - * @param object - * @return - */ - public static String toString(Object object) { - if (object == null) - return "null"; - StringBuilder buf = new StringBuilder(); - elementToString(object, buf, new HashSet()); - return buf.toString(); - } - - private static void deepToString(Map m, StringBuilder buf, Set dejaVu) { - if (m == null) { - buf.append("null"); - return; - } - if (m.size() == 0) { - buf.append("{}"); - return; - } - dejaVu.add(m); - buf.append('{'); - Iterator> iterator = m.entrySet().iterator(); - boolean has = false; - while (iterator.hasNext()) { - if (has) - buf.append(','); - Entry e = iterator.next(); - elementToString(e.getKey(), buf, dejaVu); - buf.append(':'); - elementToString(e.getValue(), buf, dejaVu); - has = true; - } - buf.append('}'); - dejaVu.remove(m); - } - - private static void deepToString( - Collection list, - StringBuilder buf, - Set dejaVu - ) { - Object[] array = list.toArray(); - deepToString(array, buf, dejaVu); - } - - private static void deepToString(Object[] a, StringBuilder buf, Set dejaVu) { - if (a == null) { - buf.append("null"); - return; - } - if (a.length == 0) { - buf.append("[]"); - return; - } - dejaVu.add(a); - buf.append('['); - for (int i = 0; i < a.length; i++) { - if (i != 0) - buf.append(','); - Object element = a[i]; - elementToString(element, buf, dejaVu); - } - buf.append(']'); - dejaVu.remove(a); - } - - @SuppressWarnings("unchecked") - private static void elementToString(Object element, StringBuilder buf, Set dejaVu) { - if (element == null) { - buf.append("null"); - } else { - Class eClass = element.getClass(); - if (eClass.isArray()) { - if (eClass == byte[].class) - buf.append(Arrays.toString((byte[]) element)); - else if (eClass == short[].class) - buf.append(Arrays.toString((short[]) element)); - else if (eClass == int[].class) - buf.append(Arrays.toString((int[]) element)); - else if (eClass == long[].class) - buf.append(Arrays.toString((long[]) element)); - else if (eClass == char[].class) - buf.append(Arrays.toString((char[]) element)); - else if (eClass == float[].class) - buf.append(Arrays.toString((float[]) element)); - else if (eClass == double[].class) - buf.append(Arrays.toString((double[]) element)); - else if (eClass == boolean[].class) - buf.append(Arrays.toString((boolean[]) element)); - else { // element is an array of object references - if (dejaVu.contains(element)) - buf.append("[...]"); - else - deepToString((Object[]) element, buf, dejaVu); - } - } else { // element is non-null and not an array - if (element instanceof Collection) - deepToString((Collection) element, buf, dejaVu); - else if (element instanceof Map) - deepToString((Map) element, buf, dejaVu); - else if (element instanceof CharSequence) - buf.append('"').append(element.toString()).append('"'); - else - buf.append(element.toString()); - } - } - } -} diff --git a/server/java/io/eiren/util/ann/AWTThread.java b/server/java/io/eiren/util/ann/AWTThread.java deleted file mode 100644 index a4ca9828c7..0000000000 --- a/server/java/io/eiren/util/ann/AWTThread.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -@Retention(value = RetentionPolicy.SOURCE) -public @interface AWTThread { - -} diff --git a/server/java/io/eiren/util/ann/DebugSwitch.java b/server/java/io/eiren/util/ann/DebugSwitch.java deleted file mode 100644 index 9b7827bec4..0000000000 --- a/server/java/io/eiren/util/ann/DebugSwitch.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - - -@Target({ ElementType.FIELD, ElementType.METHOD }) -public @interface DebugSwitch { -} diff --git a/server/java/io/eiren/util/ann/NativeUnsafe.java b/server/java/io/eiren/util/ann/NativeUnsafe.java deleted file mode 100644 index 52052dcb36..0000000000 --- a/server/java/io/eiren/util/ann/NativeUnsafe.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Marks methods and classes that use unsafe or direct access to memory. Proceed - * with caution. - * - * @author Rena - */ -@Retention(value = RetentionPolicy.RUNTIME) -@Target({ ElementType.METHOD, ElementType.TYPE }) -public @interface NativeUnsafe { - -} diff --git a/server/java/io/eiren/util/ann/Synchronize.java b/server/java/io/eiren/util/ann/Synchronize.java deleted file mode 100644 index d18d9f8339..0000000000 --- a/server/java/io/eiren/util/ann/Synchronize.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -/** - *

- * Означает необходимость обязательной синхронизации этого меcта во внешних - * методах. В аргументах передаётся название поля для синхронизации. - *

- *

- * Методы, помеченные данной аннотацией могут вызывать только Thread-Safe - * методы, либо методы, помеченные такой же аннотацией с тем же полем - * синхронизации. - *

- *

- * Поля, помеченные данной аннотацией должны быть синхронизированны на указанное - * поле при чтении или записи. - *

- * - * @see {@link ThreadSafe}, {@link ThreadSecure}, {@link ThreadSafeSingle} - * @author Rena - */ -@Retention(value = RetentionPolicy.SOURCE) -public @interface Synchronize { - - String[] value(); - -} diff --git a/server/java/io/eiren/util/ann/ThreadSafe.java b/server/java/io/eiren/util/ann/ThreadSafe.java deleted file mode 100644 index c74fcfb39b..0000000000 --- a/server/java/io/eiren/util/ann/ThreadSafe.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -/** - *

- * Методы, помеченные этой аннотацией должны быть Thread-Safe. - *

- *

- * Важно: данные методы гарантированно должны обеспечивать потоковую - * безопасность, но не обязаны обеспечивать концессивность (полноту данных или - * точность синхронизации). - *

- *

- * Для полностью потоко-безопасных методов можно использовать аннотацию - * {@link ThreadSecure}. - *

- * - * @see {@link ThreadSecure}, {@link Synchronize}, {@link ThreadSafeSingle} - * @author Rena - */ -@Retention(value = RetentionPolicy.SOURCE) -public @interface ThreadSafe { - -} diff --git a/server/java/io/eiren/util/ann/ThreadSafeSingle.java b/server/java/io/eiren/util/ann/ThreadSafeSingle.java deleted file mode 100644 index 0e918499e9..0000000000 --- a/server/java/io/eiren/util/ann/ThreadSafeSingle.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -/** - * Соблюдает те же требования что и {@link ThreadSafe} но при условии, что сам - * метод вызывается только из одного потока одновременно. - * - * @see {@link ThreadSafe}, {@link ThreadSecure}, {@link Synchronize} - * @author Rena - */ -@Retention(value = RetentionPolicy.SOURCE) -public @interface ThreadSafeSingle { - -} diff --git a/server/java/io/eiren/util/ann/ThreadSecure.java b/server/java/io/eiren/util/ann/ThreadSecure.java deleted file mode 100644 index 2b375fe365..0000000000 --- a/server/java/io/eiren/util/ann/ThreadSecure.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -/** - *

- * Методы, помеченные этой аннотацией должны быть полностью Thread-Safe. - *

- *

- * Важно: данные методы гарантированно должны обеспечивать потоковую - * безопасность и консистентность (полноту данных и точность синхронизации). - *

- * - * @see {@link ThreadSafe}, {@link Synchronize}, {@link ThreadSafeSingle} - * @author Rena - */ -@Retention(value = RetentionPolicy.SOURCE) -public @interface ThreadSecure { - -} diff --git a/server/java/io/eiren/util/ann/Transient.java b/server/java/io/eiren/util/ann/Transient.java deleted file mode 100644 index 3502dff425..0000000000 --- a/server/java/io/eiren/util/ann/Transient.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.eiren.util.ann; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - *

- * Означает что поле используется для временных или быстро изменяющихся - * переменных. - *

- *

- * Поле помеченное этой аннотацией не влияет на долгосрочное состояние объекта, - * не участвует в сериализации, вычислении equals и hashCode, не определяет - * поведение объекта для внешнего кода. Поэтому такие поля не должны - * использоваться внешним кодом, их состояние имеет смысл только для самого - * объекта в котором они объявлены. - *

- * Примеры: - *
    - *
  • Временный объект, который используется в методах для внутренних - * вычислений. Например векторные и матричные вычисления.
  • - *
  • Внутренний флаг для мультитрединга. Например, флаг апдейта графического - * состояния взводимый из игрового потока.
  • - *
  • Выведенное значение или структура, которое инициализируется самим - * объектом по фиксированному правилу. Например, производное значение от - * переменной параметризующей объект. Инициализируемый в конструкторе lookup - * table.
  • - *
- * - * @author tort32 - */ -@Retention(value = RetentionPolicy.SOURCE) -@Target({ ElementType.FIELD }) -public @interface Transient { - -} diff --git a/server/java/io/eiren/util/collections/FastList.java b/server/java/io/eiren/util/collections/FastList.java deleted file mode 100644 index 6a2ff809c8..0000000000 --- a/server/java/io/eiren/util/collections/FastList.java +++ /dev/null @@ -1,547 +0,0 @@ -package io.eiren.util.collections; - -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; - - -@SuppressWarnings("unchecked") -public class FastList extends AbstractList - implements RandomAccess, Cloneable, RemoveAtSwapList { - - private static final Object[] emptyArray = new Object[0]; - - public static final int MAX_ARRAY_SIZE = 2147483639; - - protected int size = 0; - protected Object[] array; - - public FastList(int capacity) { - array = capacity == 0 ? emptyArray : new Object[capacity]; - } - - public FastList() { - this(5); - } - - public FastList(Collection source) { - this(source.size()); - addAll(source); - } - - public FastList(FastList source) { - this(source.size); - addAllInternal(0, source.array, source.size); - } - - public FastList(E[] source) { - this(source.length); - addAll(source); - } - - public FastList(E source) { - this(); - add(source); - } - - private FastList(Object[] arr, int size) { - this(size); - System.arraycopy(arr, 0, array, 0, size); - this.size = size; - } - - private FastList(boolean f) { - } - - public static FastList reuseArray(E[] source) { - FastList list = new FastList<>(true); - list.array = source; - list.size = source.length; - return list; - } - - private void checkBounds(int index) { - if (index < 0 || index >= size) - throw new ArrayIndexOutOfBoundsException( - new StringBuilder("Index: ") - .append(index) - .append(", size: ") - .append(size) - .toString() - ); - } - - public void ensureCapacity(int numToFit) { - if (array.length < size + numToFit) - grow(numToFit + size); - } - - private void grow(int i) { - int j = array.length; - int k = j + (j >> 1); - if (k - i < 0) - k = i; - if (k - 2147483639 > 0) - k = hugeCapacity(i); - array = Arrays.copyOf(array, k); - } - - private static int hugeCapacity(int i) { - if (i < 0) - throw new OutOfMemoryError("Huge capacity negative: " + i); - else - return i <= MAX_ARRAY_SIZE ? MAX_ARRAY_SIZE : 2147483647; - } - - public void copyInto(Object[] anArray) { - System.arraycopy(array, 0, anArray, 0, size); - } - - @Override - public E get(int index) { - checkBounds(index); - return (E) array[index]; - } - - public E unsafeGet(int index) { - return (E) array[index]; - } - - @Override - public boolean isEmpty() { - return size == 0; - } - - @Override - public int size() { - return size; - } - - @Override - public int indexOf(Object obj) { - for (int j = 0; j < size; j++) - if (obj == array[j]) - return j; - return -1; - } - - @Override - public int lastIndexOf(Object obj) { - for (int j = size - 1; j >= 0; j--) - if (obj == array[j]) - return j; - return -1; - } - - @Override - public boolean contains(Object obj) { - return indexOf(obj) >= 0; - } - - public void trimToSize() { - int i = array.length; - if (size < i) - array = Arrays.copyOf(array, size); - } - - @Override - public Object[] toArray() { - return Arrays.copyOf(array, size); - } - - @Override - public T[] toArray(T aobj[]) { - if (aobj.length < size) - return (T[]) Arrays.copyOf(array, size, aobj.getClass()); - System.arraycopy(array, 0, aobj, 0, size); - if (aobj.length > size) - aobj[size] = null; - return aobj; - } - - @Override - public boolean add(E e) { - ensureCapacity(1); - array[size++] = e; - return true; - } - - @Override - public E remove(int i) { - checkBounds(i); - E obj = (E) array[i]; - removeInternal(i); - return obj; - } - - @Override - public boolean remove(Object obj) { - for (int j = 0; j < size; j++) - if (obj == array[j]) { - removeInternal(j); - return true; - } - return false; - } - - public boolean removeAll(Object[] toRemove) { - boolean removed = false; - for (int i = toRemove.length - 1; i >= 0; --i) { - int index = indexOf(toRemove[i]); - if (index != -1) { - removeInternal(index); - removed = true; - } - } - return removed; - } - - protected void removeInternal(int i) { - int j = size - i - 1; - if (j > 0) - System.arraycopy(array, i + 1, array, i, j); - array[--size] = null; - } - - public void unsafeRemove(int i) { - removeInternal(i); - } - - @Override - public boolean removeAll(Collection c) { - Objects.requireNonNull(c); - return batchRemove(c, false); - } - - @Override - public boolean retainAll(Collection c) { - Objects.requireNonNull(c); - return batchRemove(c, true); - } - - private boolean batchRemove(Collection c, boolean complement) { - final Object[] elementData = this.array; - int r = 0, w = 0; - boolean modified = false; - try { - for (; r < size; r++) - if (c.contains(elementData[r]) == complement) - elementData[w++] = elementData[r]; - } finally { - // Preserve behavioral compatibility with AbstractCollection, - // even if c.contains() throws. - if (r != size) { - System.arraycopy(elementData, r, elementData, w, size - r); - w += size - r; - } - if (w != size) { - for (int i = w; i < size; i++) - elementData[i] = null; - size = w; - modified = true; - } - } - return modified; - } - - @Override - public void clear() { - for (int i = 0; i < size; i++) - array[i] = null; - size = 0; - } - - public void fakeClear() { - size = 0; - } - - @Override - public boolean addAll(Collection collection) { - return addAll(size, collection); - } - - public void addAll(E[] arr) { - addAllInternal(size, arr, arr.length); - } - - public void addAll(E[] arr, int limit) { - addAllInternal(size, arr, limit); - } - - public void addAll(int index, E[] arr) { - addAllInternal(index, arr, arr.length); - } - - public void addAll(int index, E[] arr, int limit) { - addAllInternal(index, arr, limit); - } - - private void addAllInternal(int index, Object[] arr, int limit) { - if (limit > arr.length) - limit = arr.length; - if (limit == 1) { - add(index, (E) arr[0]); - } else if (limit > 0) { - if (index >= size) { - ensureCapacity(size - index + limit); - System.arraycopy(arr, 0, array, index, limit); - size = index + limit; - } else { - if (array.length < size + limit) { - Object[] newArray = new Object[size + limit]; - System.arraycopy(array, 0, newArray, 0, index); - System.arraycopy(arr, 0, newArray, index, limit); - System.arraycopy(array, index, newArray, index + limit, size - index); - array = newArray; - } else { - System.arraycopy(array, index, array, index + 1, size - index); - System.arraycopy(arr, 0, array, index, limit); - } - size += limit; - } - } - } - - @Override - public boolean addAll(int index, Collection collection) { - if (collection.size() > 0) { - if (collection instanceof FastList) { - addAllInternal( - index, - ((FastList) collection).array, - collection.size() - ); - } else if (collection instanceof RandomAccess) { - Object[] arr = collection.toArray(new Object[collection.size()]); - addAllInternal(index, arr, arr.length); - } else { - if (index >= size) { - ensureCapacity(size - index + collection.size()); - Iterator iterator = collection.iterator(); - int i = index; - while (iterator.hasNext()) - array[i++] = iterator.next(); - size = index + collection.size(); - } else { - if (array.length < size + collection.size()) { - Object[] newArray = new Object[size + collection.size()]; - System.arraycopy(array, 0, newArray, 0, index); - Iterator iterator = collection.iterator(); - int i = index; - while (iterator.hasNext()) - newArray[i++] = iterator.next(); - System - .arraycopy( - array, - index, - newArray, - index + collection.size(), - size - index - ); - array = newArray; - } else { - System.arraycopy(array, index, array, index + 1, size - index); - Iterator iterator = collection.iterator(); - while (iterator.hasNext()) - array[index++] = iterator.next(); - } - size += collection.size(); - } - } - return true; - } - return false; - } - - @Override - public void add(int index, E element) { - if (index >= size) { - ensureCapacity(size - index + 1); - size = index + 1; - array[index] = element; - } else { - if (array.length < size + 1) { - Object[] newArray = new Object[size + 1]; - System.arraycopy(array, 0, newArray, 0, index); - newArray[index] = element; - System.arraycopy(array, index, newArray, index + 1, size - index); - array = newArray; - } else { - System.arraycopy(array, index, array, index + 1, size - index); - array[index] = element; - } - size++; - } - } - - @Override - public E set(int index, E element) { - checkBounds(index); - E oldValue = (E) array[index]; - array[index] = element; - return oldValue; - } - - @Override - public FastList clone() { - return new FastList(array, size); - } - - @Override - public void forEach(Consumer action) { - Objects.requireNonNull(action); - final int expectedModCount = modCount; - final E[] elementData = (E[]) this.array; - final int size = this.size; - for (int i = 0; modCount == expectedModCount && i < size; i++) { - action.accept(elementData[i]); - } - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - - @Override - public E removeAtSwap(int i) { - checkBounds(i); - E obj = (E) array[i]; - removeAtSwapInternal(i); - return obj; - } - - @Override - public boolean removeAtSwap(Object obj) { - for (int j = 0; j < size; j++) - if (obj == array[j]) { - removeAtSwapInternal(j); - return true; - } - return false; - } - - protected void removeAtSwapInternal(int i) { - int j = size - i - 1; - if (j > 0) - array[i] = array[size - 1]; - array[--size] = null; - } - - @Override - public void removeRange(int i, int toIndex) { - checkBounds(i); - checkBounds(toIndex); - int j = size - toIndex - 1; - if (j > 0) - System.arraycopy(array, toIndex + 1, array, i, j); - size -= (toIndex - i + 1); - Arrays.fill(array, i, toIndex, null); - } - - @Override - public void replaceAll(UnaryOperator operator) { - Objects.requireNonNull(operator); - for (int i = 0; i < size; ++i) - set(i, operator.apply(get(i))); - } - - @Override - public void sort(Comparator c) { - Arrays.sort((E[]) array, 0, size, c); - } - - @Override - public int hashCode() { - int hashCode = 1; - for (int i = 0; i < size; ++i) { - Object o = array[i]; - hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode()); - } - return hashCode; - } - - @Override - public Spliterator spliterator() { - return Spliterators.spliterator(array, 0, size, Spliterator.ORDERED); - } - - /** - * Special comodification iterator. Use with caution. - *

- * To get element type correctly assign result to reference type - * {@code FastList.SkipFastListIterator} - * - * @return skip iterator to iterate this list in thread-safe manner - */ - public SkipFastListIterator skipIterator() { - return new SkipFastListIterator(); - } - - @Override - public boolean removeIf(Predicate filter) { - Objects.requireNonNull(filter); - // figure out which elements are to be removed - // any exception thrown from the filter predicate at this stage - // will leave the collection unmodified - int removeCount = 0; - final BitSet removeSet = new BitSet(size); - final int expectedModCount = modCount; - final int size = this.size; - for (int i = 0; modCount == expectedModCount && i < size; i++) { - final E element = (E) array[i]; - if (filter.test(element)) { - removeSet.set(i); - removeCount++; - } - } - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - // shift surviving elements left over the spaces left by removed - // elements - final boolean anyToRemove = removeCount > 0; - if (anyToRemove) { - final int newSize = size - removeCount; - for (int i = 0, j = 0; (i < size) && (j < newSize); i++, j++) { - i = removeSet.nextClearBit(i); - array[j] = array[i]; - } - for (int k = newSize; k < size; k++) { - array[k] = null; // Let gc do its work - } - this.size = newSize; - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - modCount++; - } - - return anyToRemove; - } - - public class SkipFastListIterator implements ResettableIterator, SkipIterator { - - public int position; - - @Override - public boolean hasNext() { - return position < size; - } - - @Override - public E next() { - Object[] arr = array; - if (arr.length > position) { - return (E) arr[position++]; - } - position++; // Increase position so hasNext() never loops infinitely - return null; - } - - @Override - public void reset() { - position = 0; - } - } -} diff --git a/server/java/io/eiren/util/collections/RemoveAtSwapFastList.java b/server/java/io/eiren/util/collections/RemoveAtSwapFastList.java deleted file mode 100644 index 1c00001e1e..0000000000 --- a/server/java/io/eiren/util/collections/RemoveAtSwapFastList.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.eiren.util.collections; - -import java.util.Collection; - - -/** - * FastList that performs Remove-At-Swap on stanard remove() operations. - * - *

- * Remove operations breaks ordering of this list - * - * @author Rena - * - * @param - */ -public class RemoveAtSwapFastList extends FastList { - - public RemoveAtSwapFastList(int capacity) { - super(capacity); - } - - public RemoveAtSwapFastList() { - } - - public RemoveAtSwapFastList(Collection source) { - super(source); - } - - public RemoveAtSwapFastList(E[] source) { - super(source); - } - - public RemoveAtSwapFastList(E source) { - super(source); - } - - @Override - protected void removeInternal(int i) { - super.removeAtSwapInternal(i); - } -} diff --git a/server/java/io/eiren/util/collections/RemoveAtSwapList.java b/server/java/io/eiren/util/collections/RemoveAtSwapList.java deleted file mode 100644 index ab6fbfcc1a..0000000000 --- a/server/java/io/eiren/util/collections/RemoveAtSwapList.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.eiren.util.collections; - -import java.util.List; - - -public interface RemoveAtSwapList extends List { - - public E removeAtSwap(int i); - - public boolean removeAtSwap(Object object); -} diff --git a/server/java/io/eiren/util/collections/ResettableIterator.java b/server/java/io/eiren/util/collections/ResettableIterator.java deleted file mode 100644 index 8f145d42c6..0000000000 --- a/server/java/io/eiren/util/collections/ResettableIterator.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.eiren.util.collections; - -import java.util.Iterator; - - -/** - * {@link Iterator} that can be reset and iterated from the start by using - * {@link #reset()} - * - * @author Rena - * - * @param - */ -public interface ResettableIterator extends Iterator { - - public void reset(); -} diff --git a/server/java/io/eiren/util/collections/SkipIterator.java b/server/java/io/eiren/util/collections/SkipIterator.java deleted file mode 100644 index 9c79579adc..0000000000 --- a/server/java/io/eiren/util/collections/SkipIterator.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.eiren.util.collections; - -import java.util.Iterator; - - -/** - * {@link Iterator} that can return null on {@link #next()} or can lie on - * {@link #hasNext()}. It is not thread-secure! - * - * @param the type of elements returned by this iterator - */ -public interface SkipIterator extends Iterator { - - @Override - E next(); -} diff --git a/server/java/io/eiren/util/logging/DefaultGLog.java b/server/java/io/eiren/util/logging/DefaultGLog.java deleted file mode 100644 index 78d834099b..0000000000 --- a/server/java/io/eiren/util/logging/DefaultGLog.java +++ /dev/null @@ -1,137 +0,0 @@ -package io.eiren.util.logging; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.logging.Level; -import java.util.logging.Logger; - - -public class DefaultGLog extends Thread implements IGLog { - - private final Logger logger; - - public static class LogEntry { - - private Level level; - private String message; - private Throwable t; - - public LogEntry(Level level, String message, Throwable t) { - this(level, message); - this.t = t; - } - - public LogEntry(Level level, String message) { - this.level = level; - this.message = message; - this.t = null; - } - - public Level getLevel() { - return level; - } - - public String getMessage() { - return message; - } - - public Throwable getException() { - return t; - } - } - - private final ArrayBlockingQueue queue = new ArrayBlockingQueue(50000); - private volatile LoggerRecorder recorder; - - @Override - public void info(String message) { - add(new LogEntry(Level.INFO, message)); - } - - @Override - public void info(String message, Throwable t) { - add(new LogEntry(Level.INFO, message, t)); - } - - @Override - public void severe(String message) { - add(new LogEntry(Level.SEVERE, message)); - } - - @Override - public void severe(String message, Throwable t) { - add(new LogEntry(Level.SEVERE, message, t)); - } - - @Override - public void warning(String message) { - add(new LogEntry(Level.WARNING, message)); - } - - @Override - public void warning(String message, Throwable t) { - add(new LogEntry(Level.WARNING, message, t)); - } - - @Override - public void debug(String message) { - add(new LogEntry(Level.INFO, "[DBG] " + message)); - } - - @Override - public void debug(String message, Throwable t) { - add(new LogEntry(Level.INFO, "[DBG] " + message, t)); - } - - @Override - public void log(Level level, String message) { - add(new LogEntry(level, message)); - } - - @Override - public void log(Level level, String message, Throwable t) { - add(new LogEntry(level, message, t)); - } - - private void add(LogEntry entry) { - try { - queue.put(entry); - } catch (InterruptedException e) {} - try { - if (recorder != null) - recorder.addEntry(entry); - } catch (NullPointerException e) {} - } - - @Override - public void setRecorder(LoggerRecorder recorder) { - this.recorder = recorder; - } - - @Override - public LoggerRecorder removeRecorder() { - LoggerRecorder lr = this.recorder; - this.recorder = null; - return lr; - } - - public DefaultGLog(Logger logger) { - super("Logger"); - this.logger = logger; - this.setDaemon(true); - this.setPriority(7); - this.start(); - } - - @Override - public void run() { - while (true) { - try { - LogEntry log = queue.take(); - if (log.t != null) - logger.log(log.level, log.message, log.t); - else - logger.log(log.level, log.message); - } catch (InterruptedException e) {} - } - } -} diff --git a/server/java/io/eiren/util/logging/FileLogFormatter.java b/server/java/io/eiren/util/logging/FileLogFormatter.java deleted file mode 100644 index 24d67afa05..0000000000 --- a/server/java/io/eiren/util/logging/FileLogFormatter.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.eiren.util.logging; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.SimpleDateFormat; -import java.util.logging.Formatter; -import java.util.logging.Level; -import java.util.logging.LogRecord; - - -public class FileLogFormatter extends Formatter { - - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - @Override - public String format(LogRecord record) { - StringBuilder sb = new StringBuilder(); - sb.append(dateFormat.format(record.getMillis())); - Level localLevel = record.getLevel(); - if (localLevel == Level.FINEST) - sb.append(" [FINEST] "); - else if (localLevel == Level.FINER) - sb.append(" [FINER] "); - else if (localLevel == Level.FINE) - sb.append(" [FINE] "); - else if (localLevel == Level.INFO) - sb.append(" [INFO] "); - else if (localLevel == Level.WARNING) - sb.append(" [WARNING] "); - else if (localLevel == Level.SEVERE) - sb.append(" [SEVERE] "); - else - sb.append(" [" + localLevel.getLocalizedName() + "] "); - - sb.append(record.getMessage()); - sb.append('\n'); - - Throwable localThrowable = record.getThrown(); - if (localThrowable != null) { - StringWriter localStringWriter = new StringWriter(); - localThrowable.printStackTrace(new PrintWriter(localStringWriter)); - sb.append(localStringWriter.toString()); - } - - String message = sb.toString(); - Object parameters[] = record.getParameters(); - if (parameters == null || parameters.length == 0) - return message; - if ( - message.indexOf("{0") >= 0 - || message.indexOf("{1") >= 0 - || message.indexOf("{2") >= 0 - || message.indexOf("{3") >= 0 - ) - return java.text.MessageFormat.format(message, parameters); - return message; - } -} diff --git a/server/java/io/eiren/util/logging/IGLog.java b/server/java/io/eiren/util/logging/IGLog.java deleted file mode 100644 index f21744a19a..0000000000 --- a/server/java/io/eiren/util/logging/IGLog.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.eiren.util.logging; - -import java.util.logging.Level; - - -public interface IGLog { - - public void info(String message); - - public void severe(String message); - - public void warning(String message); - - public void debug(String message); - - public default void info(String message, Throwable t) { - log(Level.INFO, message, t); - } - - public default void severe(String message, Throwable t) { - log(Level.SEVERE, message, t); - } - - public default void warning(String message, Throwable t) { - log(Level.WARNING, message, t); - } - - public default void debug(String message, Throwable t) { - log(Level.INFO, "[DBG] " + message, t); - } - - public void log(Level level, String message); - - public void log(Level level, String message, Throwable t); - - public void setRecorder(LoggerRecorder recorder); - - public LoggerRecorder removeRecorder(); - - static class GLevel extends Level { - - private static final long serialVersionUID = -539856764608026895L; - - private GLevel(String s, int i) { - super(s, i); - } - } -} diff --git a/server/java/io/eiren/util/logging/LogManager.java b/server/java/io/eiren/util/logging/LogManager.java deleted file mode 100644 index 05ba0619ec..0000000000 --- a/server/java/io/eiren/util/logging/LogManager.java +++ /dev/null @@ -1,136 +0,0 @@ -package io.eiren.util.logging; - -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.text.SimpleDateFormat; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.ConsoleHandler; -import java.util.logging.FileHandler; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; - - -public class LogManager { - - private static AtomicBoolean initialized = new AtomicBoolean(false); - - public static Logger global = Logger.getLogger(""); - public static final IGLog log = new DefaultGLog(global); - public static ConsoleHandler handler; - - public static void initialize(File logsDir, File mainLogDir) - throws SecurityException, IOException { - if (initialized.getAndSet(true)) - return; - FileLogFormatter loc = new FileLogFormatter(); - if (mainLogDir != null) { - if (!mainLogDir.exists()) - mainLogDir.mkdirs(); - File lastLogFile = new File(mainLogDir, "log_last.log"); - if (lastLogFile.exists()) - lastLogFile.delete(); - File mainLog = new File(mainLogDir, "log_main.log"); - FileHandler mHandler = new FileHandler(mainLog.getPath(), true); - FileHandler filehandler = new FileHandler(lastLogFile.getPath(), true); - mHandler.setFormatter(loc); - filehandler.setFormatter(loc); - global.addHandler(mHandler); - global.addHandler(filehandler); - } - if (logsDir != null) { - if (!logsDir.exists()) - logsDir.mkdir(); - if (!logsDir.isDirectory()) - System.out.println("*** WARNING *** LOG FOLDER IS NOT A DIRECTORY!"); - File currentLog = new File( - logsDir, - "log_" - + new SimpleDateFormat("yyyy-MM-dd") - .format(Long.valueOf(System.currentTimeMillis())) - + ".log" - ); - FileHandler filehandler2 = new FileHandler(currentLog.getPath(), true); - filehandler2.setFormatter(loc); - global.addHandler(filehandler2); - } - } - - public static void replaceMainHandler(ConsoleHandler newHandler) { - handler.close(); - global.removeHandler(handler); - handler = newHandler; - global.addHandler(newHandler); - } - - public static void addHandler(Handler add) { - global.addHandler(add); - } - - public static void removeHandler(Handler remove) { - global.removeHandler(remove); - } - - public static void enablePreciseTimestamp() { - handler.setFormatter(new PreciseConsoleLogFormatter()); - } - - public static void info(String message) { - log.info(message); - } - - public static void severe(String message) { - log.severe(message); - } - - public static void warning(String message) { - log.warning(message); - } - - public static void debug(String message) { - log.debug(message); - } - - public static void info(String message, Throwable t) { - log.info(message, t); - } - - public static void severe(String message, Throwable t) { - log.severe(message, t); - } - - public static void warning(String message, Throwable t) { - log.warning(message, t); - } - - public static void debug(String message, Throwable t) { - log.debug(message, t); - } - - public static void log(Level level, String message) { - log.log(level, message); - } - - public static void log(Level level, String message, Throwable t) { - log.log(level, message, t); - } - - static { - boolean hasConsoleHandler = false; - for (Handler h : global.getHandlers()) { - if (h instanceof ConsoleHandler) { - handler = (ConsoleHandler) h; - hasConsoleHandler = true; - } - } - if (!hasConsoleHandler) { - handler = new ConsoleHandler(); - global.addHandler(handler); - } - handler.setFormatter(new ShortConsoleLogFormatter()); - - System.setOut(new PrintStream(new LoggerOutputStream(log, Level.INFO), true)); - System.setErr(new PrintStream(new LoggerOutputStream(log, Level.SEVERE), true)); - } -} diff --git a/server/java/io/eiren/util/logging/LoggerOutputStream.java b/server/java/io/eiren/util/logging/LoggerOutputStream.java deleted file mode 100644 index 0a866937fd..0000000000 --- a/server/java/io/eiren/util/logging/LoggerOutputStream.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.eiren.util.logging; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.logging.Level; - - -public class LoggerOutputStream extends ByteArrayOutputStream { - - private static final String separator = System.getProperty("line.separator"); - - private final IGLog logger; - private final Level level; - private final String prefix; - private final StringBuilder buffer = new StringBuilder(); - - public LoggerOutputStream(IGLog logger, Level level) { - this(logger, level, ""); - } - - public LoggerOutputStream(IGLog logger, Level level, String prefix) { - super(); - this.logger = logger; - this.level = level; - this.prefix = prefix; - } - - @Override - public void flush() throws IOException { - synchronized (this) { - super.flush(); - String record = this.toString(); - super.reset(); - if (record.length() > 0) { - buffer.append(record); - if (record.contains(separator)) { - String s = buffer.toString(); - String[] split = s.split(separator); - for (int i = 0; i < split.length; ++i) - logger.log(level, prefix + split[i]); - buffer.setLength(0); - // buffer.append(split[split.length - 1]); - } - } - } - } - - @Override - public void close() throws IOException { - flush(); - } -} diff --git a/server/java/io/eiren/util/logging/LoggerRecorder.java b/server/java/io/eiren/util/logging/LoggerRecorder.java deleted file mode 100644 index 2fc4f93920..0000000000 --- a/server/java/io/eiren/util/logging/LoggerRecorder.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.eiren.util.logging; - -import java.util.List; - -import io.eiren.util.collections.FastList; -import io.eiren.util.logging.DefaultGLog.LogEntry; - - -public class LoggerRecorder { - - private final List recorded = new FastList(); - - public LoggerRecorder() { - } - - public synchronized void addEntry(LogEntry e) { - recorded.add(e); - } - - public List getEntries() { - return recorded; - } -} diff --git a/server/java/io/eiren/util/logging/PreciseConsoleLogFormatter.java b/server/java/io/eiren/util/logging/PreciseConsoleLogFormatter.java deleted file mode 100644 index 69abe91ddd..0000000000 --- a/server/java/io/eiren/util/logging/PreciseConsoleLogFormatter.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.eiren.util.logging; - -import java.text.SimpleDateFormat; -import java.util.logging.LogRecord; - - -/** - * Format message timestamp as time passed from the start with milliseconds. - */ -public class PreciseConsoleLogFormatter extends ShortConsoleLogFormatter { - - private final long startMills; - - public PreciseConsoleLogFormatter() { - startMills = System.currentTimeMillis(); - } - - @Override - protected SimpleDateFormat createDateFormat() { - return new SimpleDateFormat("mm:ss.SSS"); - } - - @Override - protected void buildMessage(StringBuilder builder, LogRecord record) { - builder.append(date.format(record.getMillis() - startMills)); - builder.append(" ["); - builder.append(record.getLevel().getLocalizedName().toUpperCase()); - builder.append("] "); - builder.append(record.getMessage()); - builder.append('\n'); - } -} diff --git a/server/java/io/eiren/util/logging/ShortConsoleLogFormatter.java b/server/java/io/eiren/util/logging/ShortConsoleLogFormatter.java deleted file mode 100644 index f95749084b..0000000000 --- a/server/java/io/eiren/util/logging/ShortConsoleLogFormatter.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.eiren.util.logging; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.SimpleDateFormat; -import java.util.logging.Formatter; -import java.util.logging.LogRecord; - - -public class ShortConsoleLogFormatter extends Formatter { - - protected final SimpleDateFormat date; - - public ShortConsoleLogFormatter() { - this.date = createDateFormat(); - } - - protected SimpleDateFormat createDateFormat() { - return new SimpleDateFormat("HH:mm:ss"); - } - - protected void buildMessage(StringBuilder builder, LogRecord record) { - builder.append(date.format(record.getMillis())); - builder.append(" ["); - builder.append(record.getLevel().getLocalizedName().toUpperCase()); - builder.append("] "); - builder.append(record.getMessage()); - builder.append('\n'); - } - - @Override - public String format(LogRecord record) { - StringBuilder builder = new StringBuilder(); - Throwable ex = record.getThrown(); - - buildMessage(builder, record); - - if (ex != null) { - StringWriter writer = new StringWriter(); - ex.printStackTrace(new PrintWriter(writer)); - builder.append(writer); - } - - String message = builder.toString(); - Object parameters[] = record.getParameters(); - if (parameters == null || parameters.length == 0) - return message; - if ( - message.indexOf("{0") >= 0 - || message.indexOf("{1") >= 0 - || message.indexOf("{2") >= 0 - || message.indexOf("{3") >= 0 - ) - return java.text.MessageFormat.format(message, parameters); - return message; - } - -} diff --git a/server/java/io/eiren/yaml/YamlException.java b/server/java/io/eiren/yaml/YamlException.java deleted file mode 100644 index 9bbb720c12..0000000000 --- a/server/java/io/eiren/yaml/YamlException.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.eiren.yaml; - -/** - * Configuration exception. - * - * @author sk89q - */ -public class YamlException extends Exception { - - private static final long serialVersionUID = -2442886939908724203L; - - public YamlException() { - super(); - } - - public YamlException(String msg) { - super(msg); - } - - public YamlException(String msg, Throwable t) { - super(msg, t); - } -} diff --git a/server/java/io/eiren/yaml/YamlFile.java b/server/java/io/eiren/yaml/YamlFile.java deleted file mode 100644 index c0c7332329..0000000000 --- a/server/java/io/eiren/yaml/YamlFile.java +++ /dev/null @@ -1,149 +0,0 @@ -package io.eiren.yaml; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; - -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.BaseConstructor; -import org.yaml.snakeyaml.constructor.SafeConstructor; -import org.yaml.snakeyaml.reader.UnicodeReader; -import org.yaml.snakeyaml.representer.Representer; - - -/** - * YAML configuration loader. To use this class, construct it with path to a - * file and call its load() method. For specifying node paths in the various - * get*() methods, they support SK's path notation, allowing you to select child - * nodes by delimiting node names with periods. - * - *

- * For example, given the following configuration file: - *

- * - *
- * members:
- *     - Hollie
- *     - Jason
- *     - Bobo
- *     - Aya
- *     - Tetsu
- * worldguard:
- *     fire:
- *         spread: false
- *         blocks: [cloth, rock, glass]
- * sturmeh:
- *     cool: false
- *     eats:
- *         babies: true
- * 
- * - *

- * Calling code could access sturmeh's baby eating state by using - * getBoolean("sturmeh.eats.babies", false). For lists, there are - * methods such as getStringList that will return a type safe list. - * - *

- * This class is currently incomplete. It is not yet possible to get a node. - *

- * - * @author sk89q - */ -public class YamlFile extends YamlNode { - - private static Representer defaultRepresenter = new Representer(); - - private Representer representer = defaultRepresenter; - private BaseConstructor constructor = new SafeConstructor(); - private DumperOptions options = new DumperOptions(); - - { - options.setIndent(4); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.AUTO); - } - - public YamlFile(Map rootMap) { - super(rootMap); - } - - public YamlFile() { - super(new HashMap()); - } - - public DumperOptions getOptions() { - return options; - } - - public void setRepresenter(Representer representer) { - this.representer = representer; - } - - public void setBaseConstructor(BaseConstructor constr) { - this.constructor = constr; - } - - /** - * Loads the configuration file. All errors are thrown away. - * - * @throws YamlException - */ - public void load(InputStream input) throws YamlException { - try { - Yaml yaml = new Yaml(constructor, representer, options); - read(yaml.load(new UnicodeReader(input))); - } catch (YamlException e) { - throw e; - } catch (Exception e) { - throw new YamlException("Exception while parsing yaml", e); - } - } - - /** - * Saves the configuration to disk. All errors are clobbered. - * - * @return true if it was successful - * @throws UnsupportedEncodingException - */ - public void save(OutputStream output) { - Yaml yaml = new Yaml(constructor, representer, options); - try { - yaml.dump(root, new OutputStreamWriter(output, "UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); - } - } - - @SuppressWarnings("unchecked") - private void read(Object input) throws YamlException { - try { - root = (Map) (input == null ? new HashMap() : input); - } catch (ClassCastException e) { - throw new YamlException( - "Root document must be an key-value structure, recieved: " + input - ); - } - } - - /** - * This method returns an empty ConfigurationNode for using as a default in - * methods that select a node from a node list. - * - * @return - */ - public static YamlNode getEmptyNode() { - return new YamlNode(new HashMap()); - } - - public static YamlNode getEmptySortedNode() { - return new YamlNode(new TreeMap()); - } - - public static void setDefaultRepresenter(Representer r) { - defaultRepresenter = r; - } -} diff --git a/server/java/io/eiren/yaml/YamlNode.java b/server/java/io/eiren/yaml/YamlNode.java deleted file mode 100644 index b64cd01e58..0000000000 --- a/server/java/io/eiren/yaml/YamlNode.java +++ /dev/null @@ -1,642 +0,0 @@ -package io.eiren.yaml; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import io.eiren.util.Util; - - -/** - * Represents a configuration node. - * - * @author sk89q - */ -public class YamlNode { - - public Map root; - - public YamlNode(Map root) { - this.root = root; - } - - public Object getProperty(String path) { - return getProperty(path, false); - } - - /** - * Gets a property at a location. This will either return an Object or null, - * with null meaning that no configuration value exists at that location. - * This could potentially return a default value (not yet implemented) as - * defined by a plugin, if this is a plugin-tied configuration. - * - * @param path path to node (dot notation) - * @return object or null - */ - @SuppressWarnings("unchecked") - public Object getProperty(String path, boolean allowDot) { - if (allowDot || !path.contains(".")) { - Object val = root.get(path); - if (val == null) { - return null; - } - return val; - } - - String[] parts = path.split("\\."); - Map node = root; - - for (int i = 0; i < parts.length; i++) { - Object o = node.get(parts[i]); - if (o == null) - return null; - - if (i == parts.length - 1) - return o; - - try { - node = (Map) o; - } catch (ClassCastException e) { - return null; - } - } - - return null; - } - - public void setProperty(String path, Object value) { - setProperty(path, value, false); - } - - /** - * Set the property at a location. This will override existing configuration - * data to have it conform to key/value mappings. - * - * @param path - * @param value - */ - @SuppressWarnings("unchecked") - public void setProperty(String path, Object value, boolean allowDot) { - if (value instanceof YamlNode) - value = ((YamlNode) value).root; - if (allowDot || !path.contains(".")) { - root.put(path, value); - return; - } - - String[] parts = path.split("\\."); - Map node = root; - - for (int i = 0; i < parts.length; i++) { - Object o = node.get(parts[i]); - - // Found our target! - if (i == parts.length - 1) { - node.put(parts[i], value); - return; - } - - if (o == null || !(o instanceof Map)) { - // This will override existing configuration data! - o = new HashMap(); - node.put(parts[i], o); - } - - node = (Map) o; - } - } - - public void merge(YamlNode node) { - merge(node.root); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void merge(Map map) { - Iterator> iterator = map.entrySet().iterator(); - while (iterator.hasNext()) { - Entry e = iterator.next(); - if (e.getValue() == null) - continue; - Object old = root.get(e.getKey()); - if (old == null) { - root.put(e.getKey(), e.getValue()); - } else if (old instanceof Map) { - if (!(e.getValue() instanceof Map)) { - root.put(e.getKey(), e.getValue()); - } else { - new YamlNode((Map) old) - .merge((Map) e.getValue()); - } - } else if (old instanceof List) { - if (!(e.getValue() instanceof List)) { - root.put(e.getKey(), e.getValue()); - } else { - ((List) old).addAll((List) e.getValue()); - } - } - } - } - - /** - * Gets a string at a location. This will either return an String or null, - * with null meaning that no configuration value exists at that location. If - * the object at the particular location is not actually a string, it will - * be converted to its string representation. - * - * @param path path to node (dot notation) - * @return string or null - */ - public String getString(String path) { - Object o = getProperty(path); - if (o == null) - return null; - return o.toString(); - } - - /** - * Gets a string at a location. This will either return an String or the - * default value. If the object at the particular location is not actually a - * string, it will be converted to its string representation. - * - * @param path path to node (dot notation) - * @param def default value - * @return string or default - */ - public String getString(String path, String def) { - String o = getString(path); - if (o == null) - return def; - return o; - } - - public int getInt(String path, int def) { - return getInt(path, def, false); - } - - /** - * Gets an integer at a location. This will either return an integer or the - * default value. If the object at the particular location is not actually a - * integer, the default value will be returned. However, other number types - * will be casted to an integer. - * - * @param path path to node (dot notation) - * @param def default value - * @return int or default - */ - public int getInt(String path, int def, boolean allowDot) { - Integer o = castInt(getProperty(path, allowDot)); - if (o == null) - return def; - else - return o; - } - - public long getLong(String path, long def) { - Long o = castLong(getProperty(path)); - if (o == null) - return def; - else - return o; - } - - /** - * Gets a double at a location. This will either return an double or the - * default value. If the object at the particular location is not actually a - * double, the default value will be returned. However, other number types - * will be casted to an double. - * - * @param path path to node (dot notation) - * @param def default value - * @return double or default - */ - public double getDouble(String path, double def) { - Double o = castDouble(getProperty(path)); - if (o == null) - return def; - else - return o; - } - - public float getFloat(String path, float def) { - return getFloat(path, def, false); - } - - public float getFloat(String path, float def, boolean allowDot) { - Float o = castFloat(getProperty(path, allowDot)); - if (o == null) - return def; - else - return o; - } - - /** - * Gets a boolean at a location. This will either return an boolean or the - * default value. If the object at the particular location is not actually a - * boolean, the default value will be returned. - * - * @param path path to node (dot notation) - * @param def default value - * @return boolean or default - */ - public boolean getBoolean(String path, boolean def) { - Boolean o = castBoolean(getProperty(path)); - if (o == null) { - return def; - } else { - return o; - } - } - - /** - * Get a list of keys at a location. If the map at the particular location - * does not exist or it is not a map, null will be returned. - * - * @param path path to node (dot notation) - * @return list of keys - */ - @SuppressWarnings("unchecked") - public List getKeys(String path) { - if (path == null) - return new ArrayList(root.keySet()); - Object o = getProperty(path); - if (o == null) { - return null; - } else if (o instanceof Map) { - return new ArrayList(((Map) o).keySet()); - } else { - return null; - } - } - - /** - * Gets a list of objects at a location. If the list is not defined, null - * will be returned. The node must be an actual list. - * - * @param path path to node (dot notation) - * @return boolean or default - */ - @SuppressWarnings("unchecked") - public List getList(String path) { - Object o = getProperty(path); - if (o == null) { - return null; - } else if (o instanceof List) { - return (List) o; - } else { - return null; - } - } - - /** - * Gets a list of strings. Non-valid entries will not be in the list. There - * will be no null slots. If the list is not defined, the default will be - * returned. 'null' can be passed for the default and an empty list will be - * returned instead. If an item in the list is not a string, it will be - * converted to a string. The node must be an actual list and not just a - * string. - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of strings - */ - public List getStringList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(0); - } - - List list = new ArrayList(); - for (Object o : raw) { - if (o == null) { - continue; - } - - list.add(o.toString()); - } - - return list; - } - - /** - * Gets a list of integers. Non-valid entries will not be in the list. There - * will be no null slots. If the list is not defined, the default will be - * returned. 'null' can be passed for the default and an empty list will be - * returned instead. The node must be an actual list and not just an - * integer. - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getIntList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(0); - } - - List list = new ArrayList(); - for (Object o : raw) { - Integer i = castInt(o); - if (i != null) { - list.add(i); - } - } - - return list; - } - - /** - * Gets a list of doubles. Non-valid entries will not be in the list. There - * will be no null slots. If the list is not defined, the default will be - * returned. 'null' can be passed for the default and an empty list will be - * returned instead. The node must be an actual list and cannot be just a - * double. - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getDoubleList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(0); - } - - List list = new ArrayList(); - for (Object o : raw) { - Double i = castDouble(o); - if (i != null) { - list.add(i); - } - } - - return list; - } - - /** - * Gets a list of booleans. Non-valid entries will not be in the list. There - * will be no null slots. If the list is not defined, the default will be - * returned. 'null' can be passed for the default and an empty list will be - * returned instead. The node must be an actual list and cannot be just a - * boolean, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - public List getBooleanList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(0); - } - - List list = new ArrayList(); - for (Object o : raw) { - Boolean tetsu = castBoolean(o); - if (tetsu != null) { - list.add(tetsu); - } - } - - return list; - } - - /** - * Gets a list of nodes. Non-valid entries will not be in the list. There - * will be no null slots. If the list is not defined, the default will be - * returned. 'null' can be passed for the default and an empty list will be - * returned instead. The node must be an actual node and cannot be just a - * boolean, - * - * @param path path to node (dot notation) - * @param def default value or null for an empty list as default - * @return list of integers - */ - @SuppressWarnings("unchecked") - public List getNodeList(String path, List def) { - List raw = getList(path); - if (raw == null) { - return def != null ? def : new ArrayList(0); - } - - List list = new ArrayList(); - for (Object o : raw) { - if (o instanceof Map) { - list.add(new YamlNode((Map) o)); - } - } - - return list; - } - - public YamlNode getNode(String path) { - return getNode(path, false); - } - - /** - * Get a configuration node at a path. If the node doesn't exist or the path - * does not lead to a node, null will be returned. A node has key/value - * mappings. - * - * @param path - * @return node or null - */ - @SuppressWarnings("unchecked") - public YamlNode getNode(String path, boolean allowDot) { - Object raw = getProperty(path, allowDot); - if (raw instanceof Map) { - return new YamlNode((Map) raw); - } - - return null; - } - - /** - * Get a list of nodes at a location. If the map at the particular location - * does not exist or it is not a map, null will be returned. - * - * @param path path to node (dot notation) - * @return map of nodes - */ - @SuppressWarnings("unchecked") - public Map getNodes(String path) { - Object o = getProperty(path); - if (o == null) { - return null; - } else if (o instanceof Map) { - Map nodes = new HashMap(); - - for (Map.Entry entry : ((Map) o).entrySet()) { - if (entry.getValue() instanceof Map) { - nodes.put(entry.getKey(), new YamlNode((Map) entry.getValue())); - } - } - - return nodes; - } else { - return null; - } - } - - /** - * Casts a value to an integer. May return null. - * - * @param o - * @return - */ - private static Integer castInt(Object o) { - if (o == null) { - return null; - } else if (o instanceof Byte) { - return (int) (Byte) o; - } else if (o instanceof Integer) { - return (Integer) o; - } else if (o instanceof Double) { - return (int) (double) (Double) o; - } else if (o instanceof Float) { - return (int) (float) (Float) o; - } else if (o instanceof Long) { - return (int) (long) (Long) o; - } else { - return null; - } - } - - private static Long castLong(Object o) { - if (o == null) { - return null; - } else if (o instanceof Byte) { - return (long) (Byte) o; - } else if (o instanceof Integer) { - return (long) (int) (Integer) o; - } else if (o instanceof Double) { - return (long) (double) (Double) o; - } else if (o instanceof Float) { - return (long) (float) (Float) o; - } else if (o instanceof Long) { - return (Long) o; - } else { - return null; - } - } - - /** - * Casts a value to a double. May return null. - * - * @param o - * @return - */ - private static Double castDouble(Object o) { - if (o == null) { - return null; - } else if (o instanceof Float) { - return (double) (Float) o; - } else if (o instanceof Double) { - return (Double) o; - } else if (o instanceof Byte) { - return (double) (Byte) o; - } else if (o instanceof Integer) { - return (double) (Integer) o; - } else if (o instanceof Long) { - return (double) (Long) o; - } else { - return null; - } - } - - private static Float castFloat(Object o) { - if (o == null) { - return null; - } else if (o instanceof Float) { - return (Float) o; - } else if (o instanceof Double) { - return ((Double) o).floatValue(); - } else if (o instanceof Byte) { - return (float) (Byte) o; - } else if (o instanceof Integer) { - return (float) (Integer) o; - } else if (o instanceof Long) { - return (float) (Long) o; - } else { - return null; - } - } - - /** - * Casts a value to a boolean. May return null. - * - * @param o - * @return - */ - private static Boolean castBoolean(Object o) { - if (o == null) { - return null; - } else if (o instanceof Boolean) { - return (Boolean) o; - } else { - return null; - } - } - - public void removeProperty(String path) { - removeProperty(path, false); - } - - /** - * Remove the property at a location. This will override existing - * configuration data to have it conform to key/value mappings. - * - * @param path - */ - @SuppressWarnings("unchecked") - public void removeProperty(String path, boolean allowDot) { - if (allowDot || !path.contains(".")) { - root.remove(path); - return; - } - - String[] parts = path.split("\\."); - Map node = root; - - for (int i = 0; i < parts.length; i++) { - Object o = node.get(parts[i]); - - // Found our target! - if (i == parts.length - 1) { - node.remove(parts[i]); - return; - } - - node = (Map) o; - if (node == null) - return; - } - } - - @SuppressWarnings("unchecked") - protected void fullDump(Map target, String prefix) { - Iterator> i = root.entrySet().iterator(); - while (i.hasNext()) { - Entry e = i.next(); - if (e.getValue() instanceof Map) - new YamlNode((Map) e.getValue()) - .fullDump(target, prefix + e.getKey() + "."); - else - target.put(prefix + e.getKey(), e.getValue()); - } - } - - public Map fullDump() { - Map map = new HashMap(); - fullDump(map, ""); - return map; - } - - @Override - public String toString() { - return Util.toString(root); - } -} diff --git a/server/java/org/json/JSONArray.java b/server/java/org/json/JSONArray.java deleted file mode 100644 index 578ba899c8..0000000000 --- a/server/java/org/json/JSONArray.java +++ /dev/null @@ -1,880 +0,0 @@ -package org.json; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; - - -/** - * A JSONArray is an ordered sequence of values. Its external text form is a - * string wrapped in square brackets with commas separating the values. The - * internal form is an object having get and opt - * methods for accessing the values by index, and put methods for - * adding or replacing values. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the - * JSONObject.NULL object. - *

- * The constructor can convert a JSON text into a Java object. The - * toString method converts to JSON text. - *

- * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. - *

- * The texts produced by the toString methods strictly conform to - * JSON syntax rules. The constructors are more forgiving in the texts they will - * accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing bracket.
  • - *
  • The null value will be inserted when there is , - *  (comma) elision.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
  • Values can be separated by ; (semicolon) as - * well as by , (comma).
  • - *
- * - * @author JSON.org - * @version 2012-04-20 - */ -public class JSONArray { - - /** - * The arrayList where the JSONArray's properties are kept. - */ - private final ArrayList myArrayList; - - /** - * Construct an empty JSONArray. - */ - public JSONArray() { - this.myArrayList = new ArrayList(); - } - - public JSONArray(int initialLength) { - this.myArrayList = new ArrayList(initialLength); - } - - /** - * Construct a JSONArray from a JSONTokener. - * - * @param x A JSONTokener - * @throws JSONException If there is a syntax error. - */ - public JSONArray(JSONTokener x) throws JSONException { - this(); - if (x.nextClean() != '[') { - throw x.syntaxError("A JSONArray text must start with '['"); - } - if (x.nextClean() != ']') { - x.back(); - for (;;) { - if (x.nextClean() == ',') { - x.back(); - this.myArrayList.add(JSONObject.NULL); - } else { - x.back(); - this.myArrayList.add(x.nextValue()); - } - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == ']') { - return; - } - x.back(); - break; - case ']': - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); - } - } - } - } - - /** - * Construct a JSONArray from a source JSON text. - * - * @param source A string that begins with [ (left - * bracket) and ends with ]  (right - * bracket). - * @throws JSONException If there is a syntax error. - */ - public JSONArray(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONArray from a Collection. - * - * @param collection A Collection. - */ - public JSONArray(Collection collection) { - this.myArrayList = new ArrayList(); - if (collection != null) { - Iterator iter = collection.iterator(); - while (iter.hasNext()) { - this.myArrayList.add(JSONObject.wrap(iter.next())); - } - } - } - - /** - * Construct a JSONArray from an array - * - * @throws JSONException If not an array. - */ - public JSONArray(Object array) { - this(); - if (array.getClass().isArray()) { - int length = Array.getLength(array); - for (int i = 0; i < length; i += 1) { - this.put(JSONObject.wrap(Array.get(array, i))); - } - } else { - throw new IllegalArgumentException( - "JSONArray initial value should be a string or collection or array." - ); - } - } - - /** - * Get the object value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return An object value. - * @throws JSONException If there is no value for the index. - */ - public Object get(int index) throws JSONException { - Object object = this.opt(index); - if (object == null) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - return object; - } - - /** - * Get the boolean value associated with an index. The string values "true" - * and "false" are converted to boolean. - * - * @param index The index must be between 0 and length() - 1. - * @return The truth. - * @throws JSONException If there is no value for the index or if the value - * is not convertible to boolean. - */ - public boolean getBoolean(int index) throws JSONException { - Object object = this.get(index); - if ( - object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object).equalsIgnoreCase("false")) - ) { - return false; - } else if ( - object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object).equalsIgnoreCase("true")) - ) { - return true; - } - throw new JSONException("JSONArray[" + index + "] is not a boolean."); - } - - /** - * Get the double value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException If the key is not found or if the value cannot be - * converted to a number. - */ - public double getDouble(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the int value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException If the key is not found or if the value is not a - * number. - */ - public int getInt(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the JSONArray associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return A JSONArray value. - * @throws JSONException If there is no value for the index. or if the value - * is not a JSONArray - */ - public JSONArray getJSONArray(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); - } - - /** - * Get the JSONObject associated with an index. - * - * @param index subscript - * @return A JSONObject value. - * @throws JSONException If there is no value for the index or if the value - * is not a JSONObject - */ - public JSONObject getJSONObject(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); - } - - /** - * Get the long value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException If the key is not found or if the value cannot be - * converted to a number. - */ - public long getLong(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the string associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return A string value. - * @throws JSONException If there is no string value for the index. - */ - public String getString(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONArray[" + index + "] not a string."); - } - - /** - * Determine if the value is null. - * - * @param index The index must be between 0 and length() - 1. - * @return true if the value at the index is null, or if there is no value. - */ - public boolean isNull(int index) { - return JSONObject.NULL.equals(this.opt(index)); - } - - /** - * Make a string from the contents of this JSONArray. The - * separator string is inserted between each element. Warning: - * This method assumes that the data structure is acyclical. - * - * @param separator A string that will be inserted between the elements. - * @return a string. - * @throws JSONException If the array contains an invalid number. - */ - public String join(String separator) throws JSONException { - int len = this.length(); - StringBuffer sb = new StringBuffer(); - - for (int i = 0; i < len; i += 1) { - if (i > 0) { - sb.append(separator); - } - sb.append(JSONObject.valueToString(this.myArrayList.get(i))); - } - return sb.toString(); - } - - /** - * Get the number of elements in the JSONArray, included nulls. - * - * @return The length (or size). - */ - public int length() { - return this.myArrayList.size(); - } - - /** - * Get the optional object value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return An object value, or null if there is no object at that index. - */ - public Object opt(int index) { - return (index < 0 || index >= this.length()) ? null : this.myArrayList.get(index); - } - - /** - * Get the optional boolean value associated with an index. It returns false - * if there is no value at that index, or if the value is not Boolean.TRUE - * or the String "true". - * - * @param index The index must be between 0 and length() - 1. - * @return The truth. - */ - public boolean optBoolean(int index) { - return this.optBoolean(index, false); - } - - /** - * Get the optional boolean value associated with an index. It returns the - * defaultValue if there is no value at that index or if it is not a Boolean - * or the String "true" or "false" (case insensitive). - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue A boolean default. - * @return The truth. - */ - public boolean optBoolean(int index, boolean defaultValue) { - try { - return this.getBoolean(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional double value associated with an index. NaN is returned - * if there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - */ - public double optDouble(int index) { - return this.optDouble(index, Double.NaN); - } - - /** - * Get the optional double value associated with an index. The defaultValue - * is returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index subscript - * @param defaultValue The default value. - * @return The value. - */ - public double optDouble(int index, double defaultValue) { - try { - return this.getDouble(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional int value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - */ - public int optInt(int index) { - return this.optInt(index, 0); - } - - /** - * Get the optional int value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue The default value. - * @return The value. - */ - public int optInt(int index, int defaultValue) { - try { - return this.getInt(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional JSONArray associated with an index. - * - * @param index subscript - * @return A JSONArray value, or null if the index has no value, or if the - * value is not a JSONArray. - */ - public JSONArray optJSONArray(int index) { - Object o = this.opt(index); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get the optional JSONObject associated with an index. Null is returned if - * the key is not found, or null if the index has no value, or if the value - * is not a JSONObject. - * - * @param index The index must be between 0 and length() - 1. - * @return A JSONObject value. - */ - public JSONObject optJSONObject(int index) { - Object o = this.opt(index); - return o instanceof JSONObject ? (JSONObject) o : null; - } - - /** - * Get the optional long value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - */ - public long optLong(int index) { - return this.optLong(index, 0); - } - - /** - * Get the optional long value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue The default value. - * @return The value. - */ - public long optLong(int index, long defaultValue) { - try { - return this.getLong(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional string value associated with an index. It returns an - * empty string if there is no value at that index. If the value is not a - * string and is not null, then it is coverted to a string. - * - * @param index The index must be between 0 and length() - 1. - * @return A String value. - */ - public String optString(int index) { - return this.optString(index, ""); - } - - /** - * Get the optional string associated with an index. The defaultValue is - * returned if the key is not found. - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue The default value. - * @return A String value. - */ - public String optString(int index, String defaultValue) { - Object object = this.opt(index); - return JSONObject.NULL.equals(object) ? defaultValue : object.toString(); - } - - /** - * Append a boolean value. This increases the array's length by one. - * - * @param value A boolean value. - * @return this. - */ - public JSONArray put(boolean value) { - this.put(value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param value A Collection value. - * @return this. - */ - public JSONArray put(Collection value) { - this.put(new JSONArray(value)); - return this; - } - - /** - * Append a double value. This increases the array's length by one. - * - * @param value A double value. - * @throws JSONException if the value is not finite. - * @return this. - */ - public JSONArray put(double value) throws JSONException { - Double d = new Double(value); - JSONObject.testValidity(d); - this.put(d); - return this; - } - - /** - * Append an int value. This increases the array's length by one. - * - * @param value An int value. - * @return this. - */ - public JSONArray put(int value) { - this.put(new Integer(value)); - return this; - } - - /** - * Append an long value. This increases the array's length by one. - * - * @param value A long value. - * @return this. - */ - public JSONArray put(long value) { - this.put(new Long(value)); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject which - * is produced from a Map. - * - * @param value A Map value. - * @return this. - */ - public JSONArray put(Map value) { - this.put(new JSONObject(value)); - return this; - } - - /** - * Append an object value. This increases the array's length by one. - * - * @param value An object value. The value should be a Boolean, Double, - * Integer, JSONArray, JSONObject, Long, or String, or the JSONObject.NULL - * object. - * @return this. - */ - public JSONArray put(Object value) { - this.myArrayList.add(value); - return this; - } - - /** - * Put or replace a boolean value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index The subscript. - * @param value A boolean value. - * @return this. - * @throws JSONException If the index is negative. - */ - public JSONArray put(int index, boolean value) throws JSONException { - this.put(index, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param index The subscript. - * @param value A Collection value. - * @return this. - * @throws JSONException If the index is negative or if the value is not - * finite. - */ - public JSONArray put(int index, Collection value) throws JSONException { - this.put(index, new JSONArray(value)); - return this; - } - - /** - * Put or replace a double value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index The subscript. - * @param value A double value. - * @return this. - * @throws JSONException If the index is negative or if the value is not - * finite. - */ - public JSONArray put(int index, double value) throws JSONException { - this.put(index, new Double(value)); - return this; - } - - /** - * Put or replace an int value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index The subscript. - * @param value An int value. - * @return this. - * @throws JSONException If the index is negative. - */ - public JSONArray put(int index, int value) throws JSONException { - this.put(index, new Integer(value)); - return this; - } - - /** - * Put or replace a long value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index The subscript. - * @param value A long value. - * @return this. - * @throws JSONException If the index is negative. - */ - public JSONArray put(int index, long value) throws JSONException { - this.put(index, new Long(value)); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject that - * is produced from a Map. - * - * @param index The subscript. - * @param value The Map value. - * @return this. - * @throws JSONException If the index is negative or if the the value is an - * invalid number. - */ - public JSONArray put(int index, Map value) throws JSONException { - this.put(index, new JSONObject(value)); - return this; - } - - /** - * Put or replace an object value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index The subscript. - * @param value The value to put into the array. The value should be a - * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the - * JSONObject.NULL object. - * @return this. - * @throws JSONException If the index is negative or if the the value is an - * invalid number. - */ - public JSONArray put(int index, Object value) throws JSONException { - JSONObject.testValidity(value); - if (index < 0) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - if (index < this.length()) { - this.myArrayList.set(index, value); - } else { - while (index != this.length()) { - this.put(JSONObject.NULL); - } - this.put(value); - } - return this; - } - - /** - * Remove an index and close the hole. - * - * @param index The index of the element to be removed. - * @return The value that was associated with the index, or null if there - * was no value. - */ - public Object remove(int index) { - Object o = this.opt(index); - this.myArrayList.remove(index); - return o; - } - - /** - * Produce a JSONObject by combining a JSONArray of names with the values of - * this JSONArray. - * - * @param names A JSONArray containing a list of key strings. These will be - * paired with the values. - * @return A JSONObject, or null if there are no names or if this JSONArray - * has no values. - * @throws JSONException If any of the names are null. - */ - public JSONObject toJSONObject(JSONArray names) throws JSONException { - if (names == null || names.length() == 0 || this.length() == 0) { - return null; - } - JSONObject jo = new JSONObject(); - for (int i = 0; i < names.length(); i += 1) { - jo.put(names.getString(i), this.opt(i)); - } - return jo; - } - - /** - * Make a JSON text of this JSONArray. For compactness, no unnecessary - * whitespace is added. If it is not possible to produce a syntactically - * correct JSON text then null will be returned instead. This could occur if - * the array contains an invalid number. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, transmittable representation of the - * array. - */ - @Override - public String toString() { - try { - return '[' + this.join(",") + ']'; - } catch (Exception e) { - return null; - } - } - - /** - * Make a prettyprinted JSON text of this JSONArray. Warning: This method - * assumes that the data structure is acyclical. - * - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @return a printable, displayable, transmittable representation of the - * object, beginning with [ (left bracket) - * and ending with ]  (right bracket). - * @throws JSONException - */ - public String toString(int indentFactor) throws JSONException { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - return this.write(sw, indentFactor, 0).toString(); - } - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @param indent The indention of the top level. - * @return The writer. - * @throws JSONException - */ - Writer write(Writer writer, int indentFactor, int indent) throws JSONException { - try { - boolean commanate = false; - int length = this.length(); - writer.write('['); - - if (length == 1) { - JSONObject.writeValue(writer, this.myArrayList.get(0), indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - - for (int i = 0; i < length; i += 1) { - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, newindent); - JSONObject.writeValue(writer, this.myArrayList.get(i), indentFactor, newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, indent); - } - writer.write(']'); - return writer; - } catch (IOException e) { - throw new JSONException(e); - } - } -} diff --git a/server/java/org/json/JSONException.java b/server/java/org/json/JSONException.java deleted file mode 100644 index 64ae077a93..0000000000 --- a/server/java/org/json/JSONException.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.json; - -/** - * The JSONException is thrown by the JSON.org classes when things are amiss. - * - * @author JSON.org - * @version 2010-12-24 - */ -public class JSONException extends RuntimeException { - - private static final long serialVersionUID = 0; - - /** - * Constructs a JSONException with an explanatory message. - * - * @param message Detail about the reason for the exception. - */ - public JSONException(String message) { - super(message); - } - - public JSONException(Throwable cause) { - super(cause.getMessage()); - initCause(cause); - } -} diff --git a/server/java/org/json/JSONObject.java b/server/java/org/json/JSONObject.java deleted file mode 100644 index d3fe1ccdd9..0000000000 --- a/server/java/org/json/JSONObject.java +++ /dev/null @@ -1,1590 +0,0 @@ -package org.json; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.ResourceBundle; - - -/** - * A JSONObject is an unordered collection of name/value pairs. Its external - * form is a string wrapped in curly braces with colons between the names and - * values, and commas between the values and names. The internal form is an - * object having get and opt methods for accessing the - * values by name, and put methods for adding or replacing values - * by name. The values can be any of these types: Boolean, - * JSONArray, JSONObject, Number, - * String, or the JSONObject.NULL object. A JSONObject - * constructor can be used to convert an external form JSON text into an - * internal form whose values can be retrieved with the get and - * opt methods, or to convert values into a JSON text using the - * put and toString methods. A get method - * returns a value if one can be found, and throws an exception if one cannot be - * found. An opt method returns a default value instead of throwing - * an exception, and so is useful for obtaining optional values. - *

- * The generic get() and opt() methods return an - * object, which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. The opt methods differ from the get methods in that they do - * not throw. Instead, they return a specified value, such as null. - *

- * The put methods add or replace values in an object. For example, - * - *

- * myString = new JSONObject().put("JSON", "Hello, World!").toString();
- * 
- * - * produces the string {"JSON": "Hello, World"}. - *

- * The texts produced by the toString methods strictly conform to - * the JSON syntax rules. The constructors are more forgiving in the texts they - * will accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing brace.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
  • Keys can be followed by = or => as well as by - * :.
  • - *
  • Values can be followed by ; (semicolon) as - * well as by , (comma).
  • - *
- * - * @author JSON.org - * @version 2012-04-20 - */ -public class JSONObject { - - /** - * JSONObject.NULL is equivalent to the value that JavaScript calls null, - * whilst Java's null is equivalent to the value that JavaScript calls - * undefined. - */ - private static final class Null { - - /** - * There is only intended to be a single instance of the NULL object, so - * the clone method returns itself. - * - * @return NULL. - */ - @Override - protected final Object clone() { - return this; - } - - /** - * A Null object is equal to the null value and to itself. - * - * @param object An object to test for nullness. - * @return true if the object parameter is the JSONObject.NULL object or - * null. - */ - @Override - public boolean equals(Object object) { - return object == null || object == this; - } - - /** - * Get the "null" string value. - * - * @return The string "null". - */ - @Override - public String toString() { - return "null"; - } - - @Override - public int hashCode() { - return 0; - } - } - - /** - * The map where the JSONObject's properties are kept. - */ - private final Map map; - - /** - * It is sometimes more convenient and less ambiguous to have a - * NULL object than to use Java's null value. - * JSONObject.NULL.equals(null) returns true. - * JSONObject.NULL.toString() returns "null". - */ - public static final Object NULL = new Null(); - - /** - * Construct an empty JSONObject. - */ - public JSONObject() { - this.map = new HashMap(); - } - - /** - * Construct a JSONObject from a subset of another JSONObject. An array of - * strings is used to identify the keys that should be copied. Missing keys - * are ignored. - * - * @param jo A JSONObject. - * @param names An array of strings. - * @throws JSONException - * @exception JSONException If a value is a non-finite number or if a name - * is duplicated. - */ - public JSONObject(JSONObject jo, String[] names) { - this(); - for (int i = 0; i < names.length; i += 1) { - try { - this.putOnce(names[i], jo.opt(names[i])); - } catch (Exception ignore) {} - } - } - - public JSONObject(String key, Object value) { - this(); - put(key, value); - } - - /** - * Construct a JSONObject from a JSONTokener. - * - * @param x A JSONTokener object containing the source string. - * @throws JSONException If there is a syntax error in the source string or - * a duplicated key. - */ - public JSONObject(JSONTokener x) throws JSONException { - this(); - char c; - String key; - - if (x.nextClean() != '{') { - throw x.syntaxError("A JSONObject text must begin with '{'"); - } - for (;;) { - c = x.nextClean(); - switch (c) { - case 0: - throw x.syntaxError("A JSONObject text must end with '}'"); - case '}': - return; - default: - x.back(); - key = x.nextValue().toString(); - } - - // The key is followed by ':'. We will also tolerate '=' or '=>'. - - c = x.nextClean(); - if (c == '=') { - if (x.next() != '>') { - x.back(); - } - } else if (c != ':') { - throw x.syntaxError("Expected a ':' after a key"); - } - this.putOnce(key, x.nextValue()); - - // Pairs are separated by ','. We will also tolerate ';'. - - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == '}') { - return; - } - x.back(); - break; - case '}': - return; - default: - throw x.syntaxError("Expected a ',' or '}'"); - } - } - } - - /** - * Construct a JSONObject from a Map. - * - * @param map A map object that can be used to initialize the contents of - * the JSONObject. - * @throws JSONException - */ - public JSONObject(Map map) { - this.map = new HashMap(); - if (map != null) { - Iterator> i = map.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry e = i.next(); - Object value = e.getValue(); - if (value != null) { - this.map.put(e.getKey(), wrap(value)); - } - } - } - } - - /** - * Construct a JSONObject from an Object using bean getters. It reflects on - * all of the public methods of the object. For each of the methods with no - * parameters and a name starting with "get" or - * "is" followed by an uppercase letter, the method is invoked, - * and a key and the value returned from the getter method are put into the - * new JSONObject. - * - * The key is formed by removing the "get" or "is" - * prefix. If the second remaining character is not upper case, then the - * first character is converted to lower case. - * - * For example, if an object has a method named "getName", and - * if the result of calling object.getName() is - * "Larry Fine", then the JSONObject will contain - * "name": "Larry Fine". - * - * @param bean An object that has getter methods that should be used to make - * a JSONObject. - */ - public JSONObject(Object bean) { - this(); - this.populateMap(bean); - } - - /** - * Construct a JSONObject from an Object, using reflection to find the - * public members. The resulting JSONObject's keys will be the strings from - * the names array, and the values will be the field values associated with - * those keys in the object. If a key is not found or not visible, then it - * will not be copied into the new JSONObject. - * - * @param object An object that has fields that should be used to make a - * JSONObject. - * @param names An array of strings, the names of the fields to be obtained - * from the object. - */ - public JSONObject(Object object, String names[]) { - this(); - Class c = object.getClass(); - for (int i = 0; i < names.length; i += 1) { - String name = names[i]; - try { - this.putOpt(name, c.getField(name).get(object)); - } catch (Exception ignore) {} - } - } - - /** - * Construct a JSONObject from a source JSON text string. This is the most - * commonly used JSONObject constructor. - * - * @param source A string beginning with { (left - * brace) and ending with }  (right - * brace). - * @exception JSONException If there is a syntax error in the source string - * or a duplicated key. - */ - public JSONObject(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONObject from a ResourceBundle. - * - * @param baseName The ResourceBundle base name. - * @param locale The Locale to load the ResourceBundle for. - * @throws JSONException If any JSONExceptions are detected. - */ - public JSONObject(String baseName, Locale locale) throws JSONException { - this(); - ResourceBundle bundle = ResourceBundle - .getBundle(baseName, locale, Thread.currentThread().getContextClassLoader()); - - // Iterate through the keys in the bundle. - - Enumeration keys = bundle.getKeys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - if (key instanceof String) { - - // Go through the path, ensuring that there is a nested - // JSONObject for each - // segment except the last. Add the value using the last - // segment's name into - // the deepest nested JSONObject. - - String[] path = ((String) key).split("\\."); - int last = path.length - 1; - JSONObject target = this; - for (int i = 0; i < last; i += 1) { - String segment = path[i]; - JSONObject nextTarget = target.optJSONObject(segment); - if (nextTarget == null) { - nextTarget = new JSONObject(); - target.put(segment, nextTarget); - } - target = nextTarget; - } - target.put(path[last], bundle.getString((String) key)); - } - } - } - - /** - * Accumulate values under a key. It is similar to the put method except - * that if there is already an object stored under the key then a JSONArray - * is stored under the key to hold all of the accumulated values. If there - * is already a JSONArray, then the new value is appended to it. In - * contrast, the put method replaces the previous value. - * - * If only one value is accumulated that is not a JSONArray, then the result - * will be the same as using put. But if multiple values are accumulated, - * then the result will be like append. - * - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the value is an invalid number or if the key is - * null. - */ - public JSONObject accumulate(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, value instanceof JSONArray ? new JSONArray().put(value) : value); - } else if (object instanceof JSONArray) { - ((JSONArray) object).put(value); - } else { - this.put(key, new JSONArray().put(object).put(value)); - } - return this; - } - - /** - * Append values to the array under a key. If the key does not exist in the - * JSONObject, then the key is put in the JSONObject with its value being a - * JSONArray containing the value parameter. If the key was already - * associated with a JSONArray, then the value parameter is appended to it. - * - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the key is null or if the current value - * associated with the key is not a JSONArray. - */ - public JSONObject append(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, new JSONArray().put(value)); - } else if (object instanceof JSONArray) { - this.put(key, ((JSONArray) object).put(value)); - } else { - throw new JSONException("JSONObject[" + key + "] is not a JSONArray."); - } - return this; - } - - public Map getMap() { - return map; - } - - /** - * Produce a string from a double. The string "null" will be returned if the - * number is not finite. - * - * @param d A double. - * @return A String. - */ - public static String doubleToString(double d) { - if (Double.isInfinite(d) || Double.isNaN(d)) { - return "null"; - } - - // Shave off trailing zeros and decimal point, if possible. - - String string = Double.toString(d); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - /** - * Get the value object associated with a key. - * - * @param key A key string. - * @return The object associated with the key. - * @throws JSONException if the key is not found. - */ - public Object get(String key) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - Object object = this.opt(key); - if (object == null) { - throw new JSONException("JSONObject[" + quote(key) + "] not found."); - } - return object; - } - - /** - * Get the boolean value associated with a key. - * - * @param key A key string. - * @return The truth. - * @throws JSONException if the value is not a Boolean or the String "true" - * or "false". - */ - public boolean getBoolean(String key) throws JSONException { - Object object = this.get(key); - if ( - object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object).equalsIgnoreCase("false")) - ) { - return false; - } else if ( - object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object).equalsIgnoreCase("true")) - ) { - return true; - } - throw new JSONException("JSONObject[" + quote(key) + "] is not a Boolean."); - } - - /** - * Get the double value associated with a key. - * - * @param key A key string. - * @return The numeric value. - * @throws JSONException if the key is not found or if the value is not a - * Number object and cannot be converted to a number. - */ - public double getDouble(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not a number."); - } - } - - public float getFloat(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).floatValue() - : Float.parseFloat((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not a number."); - } - } - - /** - * Get the int value associated with a key. - * - * @param key A key string. - * @return The integer value. - * @throws JSONException if the key is not found or if the value cannot be - * converted to an integer. - */ - public int getInt(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not an int."); - } - } - - /** - * Get the JSONArray value associated with a key. - * - * @param key A key string. - * @return A JSONArray which is the value. - * @throws JSONException if the key is not found or if the value is not a - * JSONArray. - */ - public JSONArray getJSONArray(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONArray."); - } - - /** - * Get the JSONObject value associated with a key. - * - * @param key A key string. - * @return A JSONObject which is the value. - * @throws JSONException if the key is not found or if the value is not a - * JSONObject. - */ - public JSONObject getJSONObject(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONObject."); - } - - /** - * Get the long value associated with a key. - * - * @param key A key string. - * @return The long value. - * @throws JSONException if the key is not found or if the value cannot be - * converted to a long. - */ - public long getLong(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not a long."); - } - } - - /** - * Get an array of field names from a JSONObject. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(JSONObject jo) { - int length = jo.length(); - if (length == 0) { - return null; - } - Iterator iterator = jo.keys(); - String[] names = new String[length]; - int i = 0; - while (iterator.hasNext()) { - names[i] = iterator.next(); - i += 1; - } - return names; - } - - /** - * Get an array of field names from an Object. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(Object object) { - if (object == null) { - return null; - } - Class klass = object.getClass(); - Field[] fields = klass.getFields(); - int length = fields.length; - if (length == 0) { - return null; - } - String[] names = new String[length]; - for (int i = 0; i < length; i += 1) { - names[i] = fields[i].getName(); - } - return names; - } - - /** - * Get the string associated with a key. - * - * @param key A key string. - * @return A string which is the value. - * @throws JSONException if there is no string value for the key. - */ - public String getString(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] not a string."); - } - - /** - * Determine if the JSONObject contains a specific key. - * - * @param key A key string. - * @return true if the key exists in the JSONObject. - */ - public boolean has(String key) { - return this.map.containsKey(key); - } - - /** - * Increment a property of a JSONObject. If there is no such property, - * create one with a value of 1. If there is such a property, and if it is - * an Integer, Long, Double, or Float, then add one to it. - * - * @param key A key string. - * @return this. - * @throws JSONException If there is already a property with this name that - * is not an Integer, Long, Double, or Float. - */ - public JSONObject increment(String key) throws JSONException { - Object value = this.opt(key); - if (value == null) { - this.put(key, 1); - } else if (value instanceof Integer) { - this.put(key, ((Integer) value).intValue() + 1); - } else if (value instanceof Long) { - this.put(key, ((Long) value).longValue() + 1); - } else if (value instanceof Double) { - this.put(key, ((Double) value).doubleValue() + 1); - } else if (value instanceof Float) { - this.put(key, ((Float) value).floatValue() + 1); - } else { - throw new JSONException("Unable to increment [" + quote(key) + "]."); - } - return this; - } - - /** - * Determine if the value associated with the key is null or if there is no - * value. - * - * @param key A key string. - * @return true if there is no value associated with the key or if the value - * is the JSONObject.NULL object. - */ - public boolean isNull(String key) { - return JSONObject.NULL.equals(this.opt(key)); - } - - /** - * Get an enumeration of the keys of the JSONObject. - * - * @return An iterator of the keys. - */ - public Iterator keys() { - return this.map.keySet().iterator(); - } - - /** - * Get the number of keys stored in the JSONObject. - * - * @return The number of keys in the JSONObject. - */ - public int length() { - return this.map.size(); - } - - /** - * Produce a JSONArray containing the names of the elements of this - * JSONObject. - * - * @return A JSONArray containing the key strings, or null if the JSONObject - * is empty. - */ - public JSONArray names() { - JSONArray ja = new JSONArray(); - Iterator keys = this.keys(); - while (keys.hasNext()) { - ja.put(keys.next()); - } - return ja.length() == 0 ? null : ja; - } - - /** - * Produce a string from a Number. - * - * @param number A Number - * @return A String. - * @throws JSONException If n is a non-finite number. - */ - public static String numberToString(Number number) throws JSONException { - if (number == null) { - throw new JSONException("Null pointer"); - } - testValidity(number); - - // Shave off trailing zeros and decimal point, if possible. - - String string = number.toString(); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - /** - * Get an optional value associated with a key. - * - * @param key A key string. - * @return An object which is the value, or null if there is no value. - */ - public Object opt(String key) { - return key == null ? null : this.map.get(key); - } - - /** - * Get an optional boolean associated with a key. It returns false if there - * is no such key, or if the value is not Boolean.TRUE or the String "true". - * - * @param key A key string. - * @return The truth. - */ - public boolean optBoolean(String key) { - return this.optBoolean(key, false); - } - - /** - * Get an optional boolean associated with a key. It returns the - * defaultValue if there is no such key, or if it is not a Boolean or the - * String "true" or "false" (case insensitive). - * - * @param key A key string. - * @param defaultValue The default. - * @return The truth. - */ - public boolean optBoolean(String key, boolean defaultValue) { - try { - return this.getBoolean(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional double associated with a key, or NaN if there is no such - * key or if its value is not a number. If the value is a string, an attempt - * will be made to evaluate it as a number. - * - * @param key A string which is the key. - * @return An object which is the value. - */ - public double optDouble(String key) { - return this.optDouble(key, Double.NaN); - } - - public float optFloat(String key) { - return this.optFloat(key, Float.NaN); - } - - /** - * Get an optional double associated with a key, or the defaultValue if - * there is no such key or if its value is not a number. If the value is a - * string, an attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public double optDouble(String key, double defaultValue) { - try { - return this.getDouble(key); - } catch (Exception e) { - return defaultValue; - } - } - - public float optFloat(String key, float defaultValue) { - try { - return this.getFloat(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional int value associated with a key, or zero if there is no - * such key or if the value is not a number. If the value is a string, an - * attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public int optInt(String key) { - return this.optInt(key, 0); - } - - /** - * Get an optional int value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public int optInt(String key, int defaultValue) { - try { - return this.getInt(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional JSONArray associated with a key. It returns null if there - * is no such key, or if its value is not a JSONArray. - * - * @param key A key string. - * @return A JSONArray which is the value. - */ - public JSONArray optJSONArray(String key) { - Object o = this.opt(key); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get an optional JSONObject associated with a key. It returns null if - * there is no such key, or if its value is not a JSONObject. - * - * @param key A key string. - * @return A JSONObject which is the value. - */ - public JSONObject optJSONObject(String key) { - Object object = this.opt(key); - return object instanceof JSONObject ? (JSONObject) object : null; - } - - /** - * Get an optional long value associated with a key, or zero if there is no - * such key or if the value is not a number. If the value is a string, an - * attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public long optLong(String key) { - return this.optLong(key, 0); - } - - /** - * Get an optional long value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public long optLong(String key, long defaultValue) { - try { - return this.getLong(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional string associated with a key. It returns an empty string - * if there is no such key. If the value is not a string and is not null, - * then it is converted to a string. - * - * @param key A key string. - * @return A string which is the value. - */ - public String optString(String key) { - return this.optString(key, ""); - } - - /** - * Get an optional string associated with a key. It returns the defaultValue - * if there is no such key. - * - * @param key A key string. - * @param defaultValue The default. - * @return A string which is the value. - */ - public String optString(String key, String defaultValue) { - Object object = this.opt(key); - return NULL.equals(object) ? defaultValue : object.toString(); - } - - private void populateMap(Object bean) { - Class klass = bean.getClass(); - - // If klass is a System class then set includeSuperClass to false. - - boolean includeSuperClass = klass.getClassLoader() != null; - - Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); - for (int i = 0; i < methods.length; i += 1) { - try { - Method method = methods[i]; - if (Modifier.isPublic(method.getModifiers())) { - String name = method.getName(); - String key = ""; - if (name.startsWith("get")) { - if ("getClass".equals(name) || "getDeclaringClass".equals(name)) { - key = ""; - } else { - key = name.substring(3); - } - } else if (name.startsWith("is")) { - key = name.substring(2); - } - if ( - key.length() > 0 - && Character.isUpperCase(key.charAt(0)) - && method.getParameterTypes().length == 0 - ) { - if (key.length() == 1) { - key = key.toLowerCase(); - } else if (!Character.isUpperCase(key.charAt(1))) { - key = key.substring(0, 1).toLowerCase() + key.substring(1); - } - - Object result = method.invoke(bean, (Object[]) null); - if (result != null) { - this.map.put(key, wrap(result)); - } - } - } - } catch (Exception ignore) {} - } - } - - /** - * Put a key/boolean pair in the JSONObject. - * - * @param key A key string. - * @param value A boolean which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, boolean value) { - this.put(key, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONArray which is produced from a Collection. - * - * @param key A key string. - * @param value A Collection value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Collection value) { - this.put(key, new JSONArray(value)); - return this; - } - - /** - * Put a key/double pair in the JSONObject. - * - * @param key A key string. - * @param value A double which is the value. - * @return this. - * @throws JSONException If the key is null or if the number is invalid. - */ - public JSONObject put(String key, double value) { - this.put(key, new Double(value)); - return this; - } - - /** - * Put a key/int pair in the JSONObject. - * - * @param key A key string. - * @param value An int which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, int value) { - this.put(key, new Integer(value)); - return this; - } - - /** - * Put a key/long pair in the JSONObject. - * - * @param key A key string. - * @param value A long which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, long value) { - this.put(key, new Long(value)); - return this; - } - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONObject which is produced from a Map. - * - * @param key A key string. - * @param value A Map value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Map value) { - this.put(key, new JSONObject(value)); - return this; - } - - /** - * Put a key/value pair in the JSONObject. If the value is null, then the - * key will be removed from the JSONObject if it is present. - * - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or - * the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is non-finite number or if the key is - * null. - */ - public JSONObject put(String key, Object value) { - Objects.requireNonNull(key); - if (value != null) { - testValidity(value); - this.map.put(key, value); - } else { - this.remove(key); - } - return this; - } - - /** - * Put a key/value pair in the JSONObject, but only if the key and the value - * are both non-null, and only if there is not already a member with that - * name. - * - * @param key - * @param value - * @return his. - * @throws JSONException if the key is a duplicate - */ - public JSONObject putOnce(String key, Object value) throws JSONException { - if (key != null && value != null) { - if (this.opt(key) != null) { - throw new JSONException("Duplicate key \"" + key + "\""); - } - this.put(key, value); - } - return this; - } - - /** - * Put a key/value pair in the JSONObject, but only if the key and the value - * are both non-null. - * - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or - * the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is a non-finite number. - */ - public JSONObject putOpt(String key, Object value) { - if (key != null && value != null) { - this.put(key, value); - } - return this; - } - - /** - * Produce a string in double quotes with backslash sequences in all the - * right places. A backslash will be inserted within = '\u0080' && c < '\u00a0') - || (c >= '\u2000' && c < '\u2100') - ) { - hhhh = "000" + Integer.toHexString(c); - w.write("\\u" + hhhh.substring(hhhh.length() - 4)); - } else { - w.write(c); - } - } - } - w.write('"'); - return w; - } - - /** - * Remove a name and its value, if present. - * - * @param key The name to be removed. - * @return The value that was associated with the name, or null if there was - * no value. - */ - public Object remove(String key) { - return this.map.remove(key); - } - - /** - * Try to convert a string into a number, boolean, or null. If the string - * can't be converted, return the string. - * - * @param string A String. - * @return A simple JSON value. - */ - public static Object stringToValue(String string) { - Double d; - if (string.equals("")) { - return string; - } - if (string.equalsIgnoreCase("true")) { - return Boolean.TRUE; - } - if (string.equalsIgnoreCase("false")) { - return Boolean.FALSE; - } - if (string.equalsIgnoreCase("null")) { - return JSONObject.NULL; - } - - /* - * If it might be a number, try converting it. If a number cannot be - * produced, then the value will just be a string. Note that the plus - * and implied string conventions are non-standard. A JSON parser may - * accept non-JSON forms as long as it accepts all correct JSON forms. - */ - - char b = string.charAt(0); - if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { - try { - if ( - string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1 - ) { - d = Double.valueOf(string); - if (!d.isInfinite() && !d.isNaN()) { - return d; - } - } else { - Long myLong = new Long(string); - if (myLong.longValue() == myLong.intValue()) { - return new Integer(myLong.intValue()); - } else { - return myLong; - } - } - } catch (Exception ignore) {} - } - return string; - } - - /** - * Throw an exception if the object is a NaN or infinite number. - * - * @param o The object to test. - * @throws JSONException If o is a non-finite number. - */ - public static void testValidity(Object o) { - if (o != null) { - if (o instanceof Double) { - if (((Double) o).isInfinite() || ((Double) o).isNaN()) { - throw new NumberFormatException("JSON does not allow non-finite numbers."); - } - } else if (o instanceof Float) { - if (((Float) o).isInfinite() || ((Float) o).isNaN()) { - throw new NumberFormatException("JSON does not allow non-finite numbers."); - } - } - } - } - - /** - * Produce a JSONArray containing the values of the members of this - * JSONObject. - * - * @param names A JSONArray containing a list of key strings. This - * determines the sequence of the values in the result. - * @return A JSONArray of values. - * @throws JSONException If any of the values are non-finite numbers. - */ - public JSONArray toJSONArray(JSONArray names) throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (int i = 0; i < names.length(); i += 1) { - ja.put(this.opt(names.getString(i))); - } - return ja; - } - - /** - * Make a JSON text of this JSONObject. For compactness, no whitespace is - * added. If this would not result in a syntactically correct JSON text, - * then null will be returned instead. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - */ - @Override - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Make a prettyprinted JSON text of this JSONObject. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - * @throws JSONException If the object contains an invalid number. - */ - public String toString(int indentFactor) throws JSONException { - StringWriter w = new StringWriter(); - synchronized (w.getBuffer()) { - return this.write(w, indentFactor, 0).toString(); - } - } - - /** - * Make a JSON text of an Object value. If the object has an - * value.toJSONString() method, then that method will be used to produce the - * JSON text. The method is required to produce a strictly conforming text. - * If the object does not contain a toJSONString method (which is the most - * common case), then a text will be produced by other means. If the value - * is an array or Collection, then a JSONArray will be made from it and its - * toJSONString method will be called. If the value is a MAP, then a - * JSONObject will be made from it and its toJSONString method will be - * called. Otherwise, the value's toString method will be called, and the - * result will be quoted. - * - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param value The value to be serialized. - * @return a printable, displayable, transmittable representation of the - * object, beginning with { (left brace) - * and ending with } (right brace). - * @throws JSONException If the value is or contains an invalid number. - */ - @SuppressWarnings("unchecked") - public static String valueToString(Object value) throws JSONException { - if (value == null || value.equals(null)) { - return "null"; - } - if (value instanceof JSONString) { - Object object; - try { - object = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - if (object instanceof String) { - return (String) object; - } - throw new JSONException("Bad value from toJSONString: " + object); - } - if (value instanceof Number) { - return numberToString((Number) value); - } - if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) { - return value.toString(); - } - if (value instanceof Map) { - return new JSONObject(value).toString(); - } - if (value instanceof Collection) { - return new JSONArray((Collection) value).toString(); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(); - } - return quote(value.toString()); - } - - /** - * Wrap an object, if necessary. If the object is null, return the NULL - * object. If it is an array or collection, wrap it in a JSONArray. If it is - * a map, wrap it in a JSONObject. If it is a standard property (Double, - * String, et al) then it is already wrapped. Otherwise, if it comes from - * one of the java packages, turn it into a string. And if it doesn't, try - * to wrap it in a JSONObject. If the wrapping fails, then null is returned. - * - * @param object The object to wrap - * @return The wrapped value - */ - @SuppressWarnings("unchecked") - public static Object wrap(Object object) { - try { - if (object == null) { - return NULL; - } - if ( - object instanceof JSONObject - || object instanceof JSONArray - || NULL.equals(object) - || object instanceof JSONString - || object instanceof Byte - || object instanceof Character - || object instanceof Short - || object instanceof Integer - || object instanceof Long - || object instanceof Boolean - || object instanceof Float - || object instanceof Double - || object instanceof String - ) { - return object; - } - - if (object instanceof Collection) { - return new JSONArray((Collection) object); - } - if (object.getClass().isArray()) { - return new JSONArray(object); - } - if (object instanceof Map) { - return new JSONObject(object); - } - Package objectPackage = object.getClass().getPackage(); - String objectPackageName = objectPackage != null ? objectPackage.getName() : ""; - if ( - objectPackageName.startsWith("java.") - || objectPackageName.startsWith("javax.") - || object.getClass().getClassLoader() == null - ) { - return object.toString(); - } - return new JSONObject(object); - } catch (Exception exception) { - return null; - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - public Writer writeWithIdent(Writer writer) throws JSONException { - return this.write(writer, 1, 0); - } - - @SuppressWarnings("unchecked") - static final Writer writeValue(Writer writer, Object value, int indentFactor, int indent) - throws JSONException, IOException { - if (value == null || value.equals(null)) { - writer.write("null"); - } else if (value instanceof JSONObject) { - ((JSONObject) value).write(writer, indentFactor, indent); - } else if (value instanceof JSONArray) { - ((JSONArray) value).write(writer, indentFactor, indent); - } else if (value instanceof Map) { - new JSONObject(value).write(writer, indentFactor, indent); - } else if (value instanceof Collection) { - new JSONArray((Collection) value).write(writer, indentFactor, indent); - } else if (value.getClass().isArray()) { - new JSONArray(value).write(writer, indentFactor, indent); - } else if (value instanceof Number) { - writer.write(numberToString((Number) value)); - } else if (value instanceof Boolean) { - writer.write(value.toString()); - } else if (value instanceof JSONString) { - Object o; - try { - o = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - writer.write(o != null ? o.toString() : quote(value.toString())); - } else { - quote(value.toString(), writer); - } - return writer; - } - - static final void indent(Writer writer, int indent) throws IOException { - for (int i = 0; i < indent; i += 1) { - writer.write('\t'); - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - Writer write(Writer writer, int indentFactor, int indent) throws JSONException { - try { - boolean commanate = false; - final int length = this.length(); - Iterator keys = this.keys(); - writer.write('{'); - - if (length == 1) { - Object key = keys.next(); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - while (keys.hasNext()) { - Object key = keys.next(); - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, newindent); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, indent); - } - writer.write('}'); - return writer; - } catch (IOException exception) { - throw new JSONException(exception); - } - } -} diff --git a/server/java/org/json/JSONString.java b/server/java/org/json/JSONString.java deleted file mode 100644 index 8b62ea3105..0000000000 --- a/server/java/org/json/JSONString.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.json; - -/** - * The JSONString interface allows a toJSONString() - * method so that a class can change the behavior of - * JSONObject.toString(), JSONArray.toString(), and - * JSONWriter.value(Object). The - * toJSONString method will be used instead of the default behavior - * of using the Object's toString() method and quoting the result. - */ -public interface JSONString { - /** - * The toJSONString method allows a class to produce its own - * JSON serialization. - * - * @return A strictly syntactically correct JSON text. - */ - public String toJSONString(); -} diff --git a/server/java/org/json/JSONTokener.java b/server/java/org/json/JSONTokener.java deleted file mode 100644 index 1d95bf5226..0000000000 --- a/server/java/org/json/JSONTokener.java +++ /dev/null @@ -1,434 +0,0 @@ -package org.json; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - - -/** - * A JSONTokener takes a source string and extracts characters and tokens from - * it. It is used by the JSONObject and JSONArray constructors to parse JSON - * source strings. - * - * @author JSON.org - * @version 2012-02-16 - */ -public class JSONTokener { - - private long character; - private boolean eof; - private long index; - private long line; - private char previous; - private Reader reader; - private boolean usePrevious; - - /** - * Construct a JSONTokener from a Reader. - * - * @param reader A reader. - */ - public JSONTokener(Reader reader) { - this.reader = reader.markSupported() ? reader : new BufferedReader(reader); - this.eof = false; - this.usePrevious = false; - this.previous = 0; - this.index = 0; - this.character = 1; - this.line = 1; - } - - /** - * Construct a JSONTokener from an InputStream. - */ - public JSONTokener(InputStream inputStream) throws JSONException { - this(new InputStreamReader(inputStream)); - } - - /** - * Construct a JSONTokener from a string. - * - * @param s A source string. - */ - public JSONTokener(String s) { - this(new StringReader(s)); - } - - /** - * Back up one character. This provides a sort of lookahead capability, so - * that you can test for a digit or letter before attempting to parse the - * next number or identifier. - */ - public void back() throws JSONException { - if (this.usePrevious || this.index <= 0) { - throw new JSONException("Stepping back two steps is not supported"); - } - this.index -= 1; - this.character -= 1; - this.usePrevious = true; - this.eof = false; - } - - /** - * Get the hex value of a character (base16). - * - * @param c A character between '0' and '9' or between 'A' and 'F' or - * between 'a' and 'f'. - * @return An int between 0 and 15, or -1 if c was not a hex digit. - */ - public static int dehexchar(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } - if (c >= 'A' && c <= 'F') { - return c - ('A' - 10); - } - if (c >= 'a' && c <= 'f') { - return c - ('a' - 10); - } - return -1; - } - - public boolean end() { - return this.eof && !this.usePrevious; - } - - /** - * Determine if the source string still contains characters that next() can - * consume. - * - * @return true if not yet at the end of the source. - */ - public boolean more() throws JSONException { - this.next(); - if (this.end()) { - return false; - } - this.back(); - return true; - } - - /** - * Get the next character in the source string. - * - * @return The next character, or 0 if past the end of the source string. - */ - public char next() throws JSONException { - int c; - if (this.usePrevious) { - this.usePrevious = false; - c = this.previous; - } else { - try { - c = this.reader.read(); - } catch (IOException exception) { - throw new JSONException(exception); - } - - if (c <= 0) { // End of stream - this.eof = true; - c = 0; - } - } - this.index += 1; - if (this.previous == '\r') { - this.line += 1; - this.character = c == '\n' ? 0 : 1; - } else if (c == '\n') { - this.line += 1; - this.character = 0; - } else { - this.character += 1; - } - this.previous = (char) c; - return this.previous; - } - - /** - * Consume the next character, and check that it matches a specified - * character. - * - * @param c The character to match. - * @return The character. - * @throws JSONException if the character does not match. - */ - public char next(char c) throws JSONException { - char n = this.next(); - if (n != c) { - throw this.syntaxError("Expected '" + c + "' and instead saw '" + n + "'"); - } - return n; - } - - /** - * Get the next n characters. - * - * @param n The number of characters to take. - * @return A string of n characters. - * @throws JSONException Substring bounds error if there are not n - * characters remaining in the source string. - */ - public String next(int n) throws JSONException { - if (n == 0) { - return ""; - } - - char[] chars = new char[n]; - int pos = 0; - - while (pos < n) { - chars[pos] = this.next(); - if (this.end()) { - throw this.syntaxError("Substring bounds error"); - } - pos += 1; - } - return new String(chars); - } - - /** - * Get the next char in the string, skipping whitespace. - * - * @throws JSONException - * @return A character, or 0 if there are no more characters. - */ - public char nextClean() throws JSONException { - for (;;) { - char c = this.next(); - if (c == 0 || c > ' ') { - return c; - } - } - } - - /** - * Return the characters up to the next close quote character. Backslash - * processing is done. The formal JSON format does not allow strings in - * single quotes, but an implementation is allowed to accept them. - * - * @param quote The quoting character, either " - *  (double quote) or ' - *  (single quote). - * @return A String. - * @throws JSONException Unterminated string. - */ - public String nextString(char quote) throws JSONException { - char c; - StringBuffer sb = new StringBuffer(); - for (;;) { - c = this.next(); - switch (c) { - case 0: - case '\n': - case '\r': - throw this.syntaxError("Unterminated string"); - case '\\': - c = this.next(); - switch (c) { - case 'b': - sb.append('\b'); - break; - case 't': - sb.append('\t'); - break; - case 'n': - sb.append('\n'); - break; - case 'f': - sb.append('\f'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - sb.append((char) Integer.parseInt(this.next(4), 16)); - break; - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - default: - throw this.syntaxError("Illegal escape."); - } - break; - default: - if (c == quote) { - return sb.toString(); - } - sb.append(c); - } - } - } - - /** - * Get the text up but not including the specified character or the end of - * line, whichever comes first. - * - * @param delimiter A delimiter character. - * @return A string. - */ - public String nextTo(char delimiter) throws JSONException { - StringBuffer sb = new StringBuffer(); - for (;;) { - char c = this.next(); - if (c == delimiter || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - /** - * Get the text up but not including one of the specified delimiter - * characters or the end of line, whichever comes first. - * - * @param delimiters A set of delimiter characters. - * @return A string, trimmed. - */ - public String nextTo(String delimiters) throws JSONException { - char c; - StringBuffer sb = new StringBuffer(); - for (;;) { - c = this.next(); - if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - /** - * Get the next value. The value can be a Boolean, Double, Integer, - * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. - * - * @throws JSONException If syntax error. - * - * @return An object. - */ - public Object nextValue() throws JSONException { - char c = this.nextClean(); - String string; - - switch (c) { - case '"': - case '\'': - return this.nextString(c); - case '{': - this.back(); - return new JSONObject(this); - case '[': - this.back(); - return new JSONArray(this); - } - - /* - * Handle unquoted text. This could be the values true, false, or null, - * or it can be a number. An implementation (such as this one) is - * allowed to also accept non-standard forms. - * - * Accumulate characters until we reach the end of the text or a - * formatting character. - */ - - StringBuffer sb = new StringBuffer(); - while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { - sb.append(c); - c = this.next(); - } - this.back(); - - string = sb.toString().trim(); - if ("".equals(string)) { - throw this.syntaxError("Missing value"); - } - return JSONObject.stringToValue(string); - } - - /** - * Skip characters until the next character is the requested character. If - * the requested character is not found, no characters are skipped. - * - * @param to A character to skip to. - * @return The requested character, or zero if the requested character is - * not found. - */ - public char skipTo(char to) throws JSONException { - char c; - try { - long startIndex = this.index; - long startCharacter = this.character; - long startLine = this.line; - this.reader.mark(1000000); - do { - c = this.next(); - if (c == 0) { - this.reader.reset(); - this.index = startIndex; - this.character = startCharacter; - this.line = startLine; - return c; - } - } while (c != to); - } catch (IOException exc) { - throw new JSONException(exc); - } - - this.back(); - return c; - } - - /** - * Make a JSONException to signal a syntax error. - * - * @param message The error message. - * @return A JSONException object, suitable for throwing - */ - public JSONException syntaxError(String message) { - return new JSONException(message + this.toString()); - } - - /** - * Make a printable string of this JSONTokener. - * - * @return " at {index} [character {character} line {line}]" - */ - @Override - public String toString() { - return " at " + this.index + " [character " + this.character + " line " + this.line + "]"; - } -} diff --git a/server/java/org/json/JSONUtil.java b/server/java/org/json/JSONUtil.java deleted file mode 100644 index b7d3cd115c..0000000000 --- a/server/java/org/json/JSONUtil.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.json; - -import java.util.Map.Entry; - - -public class JSONUtil { - - public static JSONObject toJSON(JSONEntry... entries) { - return o(entries); - } - - public static JSONObject o(JSONEntry... entries) { - JSONObject object = new JSONObject(); - for (int i = 0; i < entries.length; ++i) { - JSONEntry e = entries[i]; - object.put(e.getKey(), e.getValue()); - } - return object; - } - - public static JSONArray a(Object... values) { - return new JSONArray(values); - } - - public static JSONEntry e(String k, Object v) { - return new JSONEntry(k, v); - } - - public static class JSONEntry implements Entry { - - private String key; - private Object value; - - public JSONEntry(String key, Object value) { - this.key = key; - this.value = value; - } - - @Override - public String getKey() { - return this.key; - } - - @Override - public Object getValue() { - return this.value; - } - - @Override - public Object setValue(Object value) { - Object oldValue = this.value; - this.value = value; - return oldValue; - } - - } -} diff --git a/server/src/main/java/dev/slimevr/gui/Keybinding.java b/server/src/main/java/dev/slimevr/Keybinding.java similarity index 97% rename from server/src/main/java/dev/slimevr/gui/Keybinding.java rename to server/src/main/java/dev/slimevr/Keybinding.java index 85d0364b33..b30c5bb3fd 100644 --- a/server/src/main/java/dev/slimevr/gui/Keybinding.java +++ b/server/src/main/java/dev/slimevr/Keybinding.java @@ -1,75 +1,75 @@ -package dev.slimevr.gui; - -import com.melloware.jintellitype.HotkeyListener; -import com.melloware.jintellitype.JIntellitype; -import dev.slimevr.VRServer; -import dev.slimevr.config.KeybindingsConfig; -import io.eiren.util.OperatingSystem; -import io.eiren.util.ann.AWTThread; -import io.eiren.util.logging.LogManager; - - -public class Keybinding implements HotkeyListener { - private static final int RESET = 1; - private static final int QUICK_RESET = 2; - private static final int RESET_MOUNTING = 3; - public final VRServer server; - public final KeybindingsConfig config; - - @AWTThread - public Keybinding(VRServer server) { - this.server = server; - - this.config = server.getConfigManager().getVrConfig().getKeybindings(); - - if (OperatingSystem.getCurrentPlatform() != OperatingSystem.WINDOWS) { - LogManager - .info( - "[Keybinding] Currently only supported on Windows. Keybindings will be disabled." - ); - return; - } - - try { - if (JIntellitype.getInstance() instanceof JIntellitype) { - JIntellitype.getInstance().addHotKeyListener(this); - - String resetBinding = this.config.getResetBinding(); - JIntellitype.getInstance().registerHotKey(RESET, resetBinding); - LogManager.info("[Keybinding] Bound reset to " + resetBinding); - - String quickResetBinding = this.config.getQuickResetBinding(); - JIntellitype.getInstance().registerHotKey(QUICK_RESET, quickResetBinding); - LogManager.info("[Keybinding] Bound quick reset to " + quickResetBinding); - - String resetMountingBinding = this.config.getResetMountingBinding(); - JIntellitype.getInstance().registerHotKey(RESET_MOUNTING, resetMountingBinding); - LogManager.info("[Keybinding] Bound reset mounting to " + resetMountingBinding); - } - } catch (Throwable e) { - LogManager - .warning( - "[Keybinding] JIntellitype initialization failed. Keybindings will be disabled. Try restarting your computer." - ); - } - } - - @AWTThread - @Override - public void onHotKey(int identifier) { - switch (identifier) { - case RESET -> { - LogManager.info("[Keybinding] Reset pressed"); - server.scheduleResetTrackers(this.config.getResetDelay()); - } - case QUICK_RESET -> { - LogManager.info("[Keybinding] Quick reset pressed"); - server.scheduleResetTrackersYaw(this.config.getQuickResetDelay()); - } - case RESET_MOUNTING -> { - LogManager.info("[Keybinding] Reset mounting pressed"); - server.scheduleResetTrackersMounting(this.config.getResetMountingDelay()); - } - } - } -} +package dev.slimevr.gui; + +import com.melloware.jintellitype.HotkeyListener; +import com.melloware.jintellitype.JIntellitype; +import dev.slimevr.VRServer; +import dev.slimevr.config.KeybindingsConfig; +import io.eiren.util.OperatingSystem; +import io.eiren.util.ann.AWTThread; +import io.eiren.util.logging.LogManager; + + +public class Keybinding implements HotkeyListener { + private static final int RESET = 1; + private static final int QUICK_RESET = 2; + private static final int RESET_MOUNTING = 3; + public final VRServer server; + public final KeybindingsConfig config; + + @AWTThread + public Keybinding(VRServer server) { + this.server = server; + + this.config = server.getConfigManager().getVrConfig().getKeybindings(); + + if (OperatingSystem.getCurrentPlatform() != OperatingSystem.WINDOWS) { + LogManager + .info( + "[Keybinding] Currently only supported on Windows. Keybindings will be disabled." + ); + return; + } + + try { + if (JIntellitype.getInstance() instanceof JIntellitype) { + JIntellitype.getInstance().addHotKeyListener(this); + + String resetBinding = this.config.getResetBinding(); + JIntellitype.getInstance().registerHotKey(RESET, resetBinding); + LogManager.info("[Keybinding] Bound reset to " + resetBinding); + + String quickResetBinding = this.config.getQuickResetBinding(); + JIntellitype.getInstance().registerHotKey(QUICK_RESET, quickResetBinding); + LogManager.info("[Keybinding] Bound quick reset to " + quickResetBinding); + + String resetMountingBinding = this.config.getResetMountingBinding(); + JIntellitype.getInstance().registerHotKey(RESET_MOUNTING, resetMountingBinding); + LogManager.info("[Keybinding] Bound reset mounting to " + resetMountingBinding); + } + } catch (Throwable e) { + LogManager + .warning( + "[Keybinding] JIntellitype initialization failed. Keybindings will be disabled. Try restarting your computer." + ); + } + } + + @AWTThread + @Override + public void onHotKey(int identifier) { + switch (identifier) { + case RESET -> { + LogManager.info("[Keybinding] Reset pressed"); + server.scheduleResetTrackers(this.config.getResetDelay()); + } + case QUICK_RESET -> { + LogManager.info("[Keybinding] Quick reset pressed"); + server.scheduleResetTrackersYaw(this.config.getQuickResetDelay()); + } + case RESET_MOUNTING -> { + LogManager.info("[Keybinding] Reset mounting pressed"); + server.scheduleResetTrackersMounting(this.config.getResetMountingDelay()); + } + } + } +} diff --git a/server/src/main/java/dev/slimevr/Main.java b/server/src/main/java/dev/slimevr/Main.java index 6f99432a6b..c10b6e0256 100644 --- a/server/src/main/java/dev/slimevr/Main.java +++ b/server/src/main/java/dev/slimevr/Main.java @@ -1,7 +1,6 @@ package dev.slimevr; -import dev.slimevr.gui.Keybinding; -import dev.slimevr.gui.VRServerGUI; +import dev.slimevr.Keybinding; import io.eiren.util.logging.LogManager; import org.apache.commons.cli.*; import org.apache.commons.lang3.JavaVersion; @@ -15,7 +14,7 @@ public class Main { - public static String VERSION = "0.3.0"; + public static String VERSION = "0.3.1"; public static VRServer vrServer; @@ -29,15 +28,8 @@ public static void main(String[] args) { Options options = new Options(); - Option noGui = new Option( - "g", - "no-gui", - false, - "disable swing gui (allow for other gui to be used)" - ); Option help = new Option("h", "help", false, "Show help"); - options.addOption(noGui); options.addOption(help); try { cmd = parser.parse(options, args); @@ -94,8 +86,6 @@ public static void main(String[] args) { vrServer = new VRServer(); vrServer.start(); new Keybinding(vrServer); - if (!cmd.hasOption("no-gui")) - new VRServerGUI(vrServer); } catch (Throwable e) { e.printStackTrace(); try { diff --git a/server/src/main/java/dev/slimevr/gui/AbstractComponentListener.java b/server/src/main/java/dev/slimevr/gui/AbstractComponentListener.java deleted file mode 100644 index b682fb3462..0000000000 --- a/server/src/main/java/dev/slimevr/gui/AbstractComponentListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package dev.slimevr.gui; - -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; - - -public abstract class AbstractComponentListener implements ComponentListener { - - @Override - public void componentResized(ComponentEvent e) { - } - - @Override - public void componentMoved(ComponentEvent e) { - } - - @Override - public void componentShown(ComponentEvent e) { - } - - @Override - public void componentHidden(ComponentEvent e) { - } -} diff --git a/server/src/main/java/dev/slimevr/gui/AbstractWindowListener.java b/server/src/main/java/dev/slimevr/gui/AbstractWindowListener.java deleted file mode 100644 index b6dd41fac2..0000000000 --- a/server/src/main/java/dev/slimevr/gui/AbstractWindowListener.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.slimevr.gui; - -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; - - -public abstract class AbstractWindowListener implements WindowListener { - - @Override - public void windowOpened(WindowEvent e) { - } - - @Override - public void windowClosing(WindowEvent e) { - } - - @Override - public void windowClosed(WindowEvent e) { - } - - @Override - public void windowIconified(WindowEvent e) { - } - - @Override - public void windowDeiconified(WindowEvent e) { - } - - @Override - public void windowActivated(WindowEvent e) { - } - - @Override - public void windowDeactivated(WindowEvent e) { - } -} diff --git a/server/src/main/java/dev/slimevr/gui/AutoBoneWindow.java b/server/src/main/java/dev/slimevr/gui/AutoBoneWindow.java deleted file mode 100644 index ebade5a225..0000000000 --- a/server/src/main/java/dev/slimevr/gui/AutoBoneWindow.java +++ /dev/null @@ -1,220 +0,0 @@ -package dev.slimevr.gui; - -import javax.swing.BoxLayout; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JScrollPane; -import javax.swing.ScrollPaneConstants; -import javax.swing.JButton; -import javax.swing.border.EmptyBorder; -import java.awt.event.MouseEvent; -import java.util.EnumMap; - -import io.eiren.util.ann.AWTThread; - -import javax.swing.event.MouseInputAdapter; - -import dev.slimevr.VRServer; -import dev.slimevr.autobone.AutoBoneListener; -import dev.slimevr.autobone.AutoBoneProcessType; -import dev.slimevr.autobone.AutoBone.Epoch; -import dev.slimevr.gui.swing.EJBox; -import dev.slimevr.poserecorder.PoseFrames; -import dev.slimevr.vr.processor.skeleton.SkeletonConfigOffsets; - - -public class AutoBoneWindow extends JFrame implements AutoBoneListener { - - private EJBox pane; - - private final transient VRServer server; - private final transient SkeletonConfigGUI skeletonConfig; - - private JButton saveRecordingButton; - private JButton applyButton; - - private JLabel processLabel; - private JLabel lengthsLabel; - - public AutoBoneWindow(VRServer server, SkeletonConfigGUI skeletonConfig) { - super("Skeleton Auto-Configuration"); - - this.server = server; - this.skeletonConfig = skeletonConfig; - - getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)); - add( - new JScrollPane( - pane = new EJBox(BoxLayout.PAGE_AXIS), - ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED - ) - ); - - server.getAutoBoneHandler().addListener(this); - - build(); - } - - - @AWTThread - private void build() { - pane.add(new EJBox(BoxLayout.LINE_AXIS) { - { - setBorder(new EmptyBorder(i(5))); - add(new JButton("Start Recording") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (!isEnabled()) { - return; - } - - server.getAutoBoneHandler().startRecording(); - } - }); - } - }); - - add(saveRecordingButton = new JButton("Save Recording") { - { - setEnabled(false); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (!isEnabled()) { - return; - } - - server.getAutoBoneHandler().saveRecording(); - } - }); - } - }); - - add(new JButton("Auto-Adjust") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (!isEnabled()) { - return; - } - - server.getAutoBoneHandler().processRecording(); - } - }); - } - }); - - add(applyButton = new JButton("Apply Values") { - { - setEnabled(false); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (!isEnabled()) { - return; - } - - server.getAutoBoneHandler().applyValues(); - // Update GUI values after applying - skeletonConfig.refreshAll(); - } - }); - } - }); - } - }); - - pane.add(new EJBox(BoxLayout.LINE_AXIS) { - { - setBorder(new EmptyBorder(i(5))); - add(processLabel = new JLabel("Processing has not been started...")); - } - }); - - pane.add(new EJBox(BoxLayout.LINE_AXIS) { - { - setBorder(new EmptyBorder(i(5))); - add(lengthsLabel = new JLabel("No config changes")); - } - }); - - // Pack and display - pack(); - setLocationRelativeTo(null); - setVisible(false); - } - - @Override - public void onAutoBoneProcessStatus( - AutoBoneProcessType processType, - String message, - long current, - long total, - boolean completed, - boolean success - ) { - if (message != null) { - if (total == 0) { - processLabel.setText(String.format("%s: %s", processType.name(), message)); - } else { - processLabel - .setText( - String - .format( - "%s (%d/%d) [%.2f%%]: %s", - processType.name(), - current, - total, - (current / (double) total) * 100.0, - message - ) - ); - } - } else { - if (total != 0) { - processLabel - .setText( - String - .format( - "%s (%d/%d) [%.2f%%]", - processType.name(), - current, - total, - (current / (double) total) * 100.0 - ) - ); - } - } - } - - @Override - public void onAutoBoneRecordingEnd(PoseFrames recording) { - saveRecordingButton.setEnabled(true); - } - - @Override - public void onAutoBoneEpoch(Epoch epoch) { - processLabel - .setText( - String - .format( - "PROCESS: Epoch %d/%d (%.2f%%) Error: %.4f (SD %.4f)", - epoch.epoch, - epoch.totalEpochs, - (epoch.epoch / (double) epoch.totalEpochs) * 100.0, - epoch.epochError.getMean(), - epoch.epochError.getStandardDeviation() - ) - ); - lengthsLabel.setText(server.getAutoBoneHandler().getLengthsString()); - } - - @Override - public void onAutoBoneEnd(EnumMap configValues) { - applyButton.setEnabled(true); - } -} diff --git a/server/src/main/java/dev/slimevr/gui/CalibrationWindow.java b/server/src/main/java/dev/slimevr/gui/CalibrationWindow.java deleted file mode 100644 index 8af0012de6..0000000000 --- a/server/src/main/java/dev/slimevr/gui/CalibrationWindow.java +++ /dev/null @@ -1,89 +0,0 @@ -package dev.slimevr.gui; - -import dev.slimevr.gui.swing.EJBox; -import dev.slimevr.vr.trackers.CalibratingTracker; -import dev.slimevr.vr.trackers.Tracker; -import io.eiren.util.ann.AWTThread; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import javax.swing.event.MouseInputAdapter; -import java.awt.*; -import java.awt.event.MouseEvent; - - -public class CalibrationWindow extends JFrame { - - public final Tracker tracker; - private JTextArea currentCalibration; - private JTextArea newCalibration; - private JButton calibrateButton; - - public CalibrationWindow(Tracker t) { - super(t.getName() + " calibration"); - this.tracker = t; - getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.LINE_AXIS)); - - build(); - } - - public void currentCalibrationReceived(String str) { - java.awt.EventQueue.invokeLater(() -> { - currentCalibration.setText(str); - pack(); - }); - } - - public void newCalibrationReceived(String str) { - java.awt.EventQueue.invokeLater(() -> { - calibrateButton.setText("Calibrate"); - newCalibration.setText(str); - pack(); - }); - } - - @AWTThread - private void build() { - Container pane = getContentPane(); - - pane.add(calibrateButton = new JButton("Calibrate") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - calibrateButton.setText("Calibrating..."); - ((CalibratingTracker) tracker) - .startCalibration(CalibrationWindow.this::newCalibrationReceived); - } - }); - } - }); - - pane.add(new EJBox(BoxLayout.PAGE_AXIS) { - { - setBorder(new EmptyBorder(i(5))); - add(new JLabel("Current calibration")); - add(currentCalibration = new JTextArea(10, 25)); - - ((CalibratingTracker) tracker) - .requestCalibrationData(CalibrationWindow.this::currentCalibrationReceived); - } - }); - pane.add(new EJBox(BoxLayout.PAGE_AXIS) { - { - setBorder(new EmptyBorder(i(5))); - add(new JLabel("New calibration")); - add(newCalibration = new JTextArea(10, 25)); - } - }); - - // Pack and display - pack(); - setLocationRelativeTo(null); - setVisible(true); - java.awt.EventQueue.invokeLater(() -> { - toFront(); - repaint(); - }); - } -} diff --git a/server/src/main/java/dev/slimevr/gui/ScalableFont.java b/server/src/main/java/dev/slimevr/gui/ScalableFont.java deleted file mode 100644 index 78f20699d4..0000000000 --- a/server/src/main/java/dev/slimevr/gui/ScalableFont.java +++ /dev/null @@ -1,89 +0,0 @@ -package dev.slimevr.gui; - -import java.awt.*; -import java.text.AttributedCharacterIterator.Attribute; -import java.util.Map; - - -public class ScalableFont extends Font { - - protected float scale = 1.0f; - - protected int initSize; - protected float initPointSize; - - public ScalableFont(Map attributes) { - super(attributes); - - this.initSize = this.size; - this.initPointSize = this.pointSize; - } - - public ScalableFont(Font font) { - super(font); - - if (font instanceof ScalableFont sourceFont) { - - this.initSize = sourceFont.getInitSize(); - this.initPointSize = sourceFont.getInitSize2D(); - - this.size = this.initSize; - this.pointSize = this.initPointSize; - } else { - this.initSize = this.size; - this.initPointSize = this.pointSize; - } - } - - public ScalableFont(Font font, float scale) { - super(font); - - if (font instanceof ScalableFont sourceFont) { - - this.initSize = sourceFont.getInitSize(); - this.initPointSize = sourceFont.getInitSize2D(); - } else { - this.initSize = this.size; - this.initPointSize = this.pointSize; - } - - setScale(scale); - } - - public ScalableFont(String name, int style, int size) { - super(name, style, size); - - this.initSize = this.size; - this.initPointSize = this.pointSize; - } - - public ScalableFont(String name, int style, int size, float scale) { - super(name, style, size); - - this.initSize = this.size; - this.initPointSize = this.pointSize; - - setScale(scale); - } - - public int getInitSize() { - return initSize; - } - - public float getInitSize2D() { - return initPointSize; - } - - public float getScale() { - return scale; - } - - private void setScale(float scale) { - this.scale = scale; - - float newPointSize = initPointSize * scale; - - this.size = (int) (newPointSize + 0.5); - this.pointSize = newPointSize; - } -} diff --git a/server/src/main/java/dev/slimevr/gui/SkeletonConfigGUI.java b/server/src/main/java/dev/slimevr/gui/SkeletonConfigGUI.java deleted file mode 100644 index 67d046aa09..0000000000 --- a/server/src/main/java/dev/slimevr/gui/SkeletonConfigGUI.java +++ /dev/null @@ -1,200 +0,0 @@ -package dev.slimevr.gui; - -import dev.slimevr.VRServer; -import dev.slimevr.gui.swing.ButtonTimer; -import dev.slimevr.gui.swing.EJBagNoStretch; -import dev.slimevr.vr.processor.skeleton.Skeleton; -import dev.slimevr.vr.processor.skeleton.SkeletonConfigOffsets; -import io.eiren.util.StringUtils; -import io.eiren.util.ann.ThreadSafe; - -import javax.swing.*; -import javax.swing.event.MouseInputAdapter; -import java.awt.event.MouseEvent; -import java.util.HashMap; -import java.util.Map; - - -public class SkeletonConfigGUI extends EJBagNoStretch { - - private final VRServer server; - private final VRServerGUI gui; - private final AutoBoneWindow autoBone; - private final Map labels = new HashMap<>(); - private JCheckBox precisionCb; - - public SkeletonConfigGUI(VRServer server, VRServerGUI gui) { - super(false, true); - this.server = server; - this.gui = gui; - this.autoBone = new AutoBoneWindow(server, this); - - setAlignmentY(TOP_ALIGNMENT); - server.humanPoseProcessor.addSkeletonUpdatedCallback(this::skeletonUpdated); - skeletonUpdated(null); - } - - @ThreadSafe - public void skeletonUpdated(Skeleton newSkeleton) { - java.awt.EventQueue.invokeLater(() -> { - removeAll(); - - int row = 0; - - add(new TimedResetButton("Reset All"), s(c(1, row, 2), 3, 1)); - add(new JButton("Auto") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - autoBone.setVisible(true); - autoBone.toFront(); - } - }); - } - }, s(c(4, row, 2), 3, 1)); - - add(precisionCb = new JCheckBox("Precision adjust"), c(0, row, 2)); - precisionCb.setSelected(false); - - row++; - - for (SkeletonConfigOffsets config : SkeletonConfigOffsets.values) { - add(new JLabel(config.label), c(0, row, 2)); - add(new AdjButton("+", config, false), c(1, row, 2)); - add(new SkeletonLabel(config), c(2, row, 2)); - add(new AdjButton("-", config, true), c(3, row, 2)); - - // Only use a timer on configs that need time to get into - // position for - switch (config) { - case TORSO, LEGS_LENGTH -> add( - new TimedResetButton("Reset", config), - c(4, row, 2) - ); - default -> add(new ResetButton("Reset", config), c(4, row, 2)); - } - - row++; - } - - gui.refresh(); - }); - } - - float proportionsIncrement(Boolean negative) { - float increment = 0.01f; - if (negative) - increment = -0.01f; - if (precisionCb.isSelected()) - increment /= 2f; - return increment; - } - - String getBoneLengthString(SkeletonConfigOffsets joint) { // Rounded to - // the - // nearest 0.5 - return (StringUtils - .prettyNumber( - Math.round(server.humanPoseProcessor.getSkeletonConfig(joint) * 200) / 2.0f, - 1 - )); - } - - @ThreadSafe - public void refreshAll() { - java.awt.EventQueue - .invokeLater( - () -> labels.forEach((joint, label) -> label.setText(getBoneLengthString(joint))) - ); - } - - private void change(SkeletonConfigOffsets joint, float diff) { - // Update config value - float current = server.humanPoseProcessor.getSkeletonConfig(joint); - server.humanPoseProcessor.setSkeletonConfig(joint, current + diff); - server.humanPoseProcessor.getSkeletonConfig().save(); - server.getConfigManager().saveConfig(); - - // Update GUI - labels.get(joint).setText(getBoneLengthString(joint)); - } - - private void reset(SkeletonConfigOffsets joint) { - // Update config value - server.humanPoseProcessor.resetSkeletonConfig(joint); - server.humanPoseProcessor.getSkeletonConfig().save(); - server.getConfigManager().saveConfig(); - - // Update GUI - labels.get(joint).setText(getBoneLengthString(joint)); - } - - private void resetAll() { - // Update config value - server.humanPoseProcessor.resetAllSkeletonConfigs(); - server.humanPoseProcessor.getSkeletonConfig().save(); - server.getConfigManager().saveConfig(); - - // Update GUI - refreshAll(); - } - - private class SkeletonLabel extends JLabel { - - public SkeletonLabel(SkeletonConfigOffsets joint) { - super(getBoneLengthString(joint)); - labels.put(joint, this); - } - } - - private class AdjButton extends JButton { - - public AdjButton(String text, SkeletonConfigOffsets joint, boolean negative) { - super(text); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - change(joint, proportionsIncrement(negative)); - } - }); - } - } - - private class ResetButton extends JButton { - - public ResetButton(String text, SkeletonConfigOffsets joint) { - super(text); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - reset(joint); - } - }); - } - } - - private class TimedResetButton extends JButton { - - public TimedResetButton(String text, SkeletonConfigOffsets joint) { - super(text); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - ButtonTimer.runTimer(TimedResetButton.this, 3, text, () -> reset(joint)); - } - }); - } - - public TimedResetButton(String text) { - super(text); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - ButtonTimer - .runTimer(TimedResetButton.this, 3, text, SkeletonConfigGUI.this::resetAll); - } - }); - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/SkeletonList.java b/server/src/main/java/dev/slimevr/gui/SkeletonList.java deleted file mode 100644 index 9604d7d81c..0000000000 --- a/server/src/main/java/dev/slimevr/gui/SkeletonList.java +++ /dev/null @@ -1,108 +0,0 @@ -package dev.slimevr.gui; - -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import dev.slimevr.VRServer; -import dev.slimevr.gui.swing.EJBagNoStretch; -import dev.slimevr.util.ann.VRServerThread; -import dev.slimevr.vr.processor.TransformNode; -import dev.slimevr.vr.processor.skeleton.Skeleton; -import io.eiren.util.StringUtils; -import io.eiren.util.ann.ThreadSafe; -import io.eiren.util.collections.FastList; - -import javax.swing.*; -import java.awt.*; -import java.util.List; - - -public class SkeletonList extends EJBagNoStretch { - - private static final long UPDATE_DELAY = 50; - private final VRServerGUI gui; - private final List nodes = new FastList<>(); - Quaternion q = new Quaternion(); - Vector3f v = new Vector3f(); - float[] angles = new float[3]; - private long lastUpdate = 0; - - public SkeletonList(VRServer server, VRServerGUI gui) { - super(false, true); - this.gui = gui; - - setAlignmentY(TOP_ALIGNMENT); - server.addSkeletonUpdatedCallback(this::skeletonUpdated); - } - - @ThreadSafe - public void skeletonUpdated(Skeleton newSkeleton) { - java.awt.EventQueue.invokeLater(() -> { - removeAll(); - nodes.clear(); - - add(new JLabel("Joint"), c(0, 0, 2)); - add(new JLabel("X"), c(1, 0, 2)); - add(new JLabel("Y"), c(2, 0, 2)); - add(new JLabel("Z"), c(3, 0, 2)); - add(new JLabel("Pitch"), c(4, 0, 2)); - add(new JLabel("Yaw"), c(5, 0, 2)); - add(new JLabel("Roll"), c(6, 0, 2)); - - TransformNode[] allNodes = newSkeleton.getAllNodes(); - - for (int i = 0; i < allNodes.length; i++) { - nodes.add(new NodeStatus(allNodes[i], i + 1)); - } - - gui.refresh(); - }); - } - - @VRServerThread - public void updateBones() { - if (lastUpdate + UPDATE_DELAY > System.currentTimeMillis()) - return; - lastUpdate = System.currentTimeMillis(); - java.awt.EventQueue.invokeLater(() -> { - for (NodeStatus node : nodes) { - node.update(); - } - }); - } - - private class NodeStatus { - - TransformNode n; - JLabel x; - JLabel y; - JLabel z; - JLabel a1; - JLabel a2; - JLabel a3; - - public NodeStatus(TransformNode node, int n) { - this.n = node; - add(new JLabel(node.getName()), c(0, n, 2, GridBagConstraints.FIRST_LINE_START)); - add(x = new JLabel("0"), c(1, n, 2, GridBagConstraints.FIRST_LINE_START)); - add(y = new JLabel("0"), c(2, n, 2, GridBagConstraints.FIRST_LINE_START)); - add(z = new JLabel("0"), c(3, n, 2, GridBagConstraints.FIRST_LINE_START)); - add(a1 = new JLabel("0"), c(4, n, 2, GridBagConstraints.FIRST_LINE_START)); - add(a2 = new JLabel("0"), c(5, n, 2, GridBagConstraints.FIRST_LINE_START)); - add(a3 = new JLabel("0"), c(6, n, 2, GridBagConstraints.FIRST_LINE_START)); - } - - public void update() { - n.worldTransform.getTranslation(v); - n.worldTransform.getRotation(q); - q.toAngles(angles); - - x.setText(StringUtils.prettyNumber(v.x, 2)); - y.setText(StringUtils.prettyNumber(v.y, 2)); - z.setText(StringUtils.prettyNumber(v.z, 2)); - a1.setText(StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0)); - a2.setText(StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0)); - a3.setText(StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0)); - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/TrackersFiltersGUI.java b/server/src/main/java/dev/slimevr/gui/TrackersFiltersGUI.java deleted file mode 100644 index 45bbf3043d..0000000000 --- a/server/src/main/java/dev/slimevr/gui/TrackersFiltersGUI.java +++ /dev/null @@ -1,104 +0,0 @@ -package dev.slimevr.gui; - -import com.jme3.math.FastMath; -import dev.slimevr.VRServer; -import dev.slimevr.config.FiltersConfig; -import dev.slimevr.filtering.TrackerFilters; -import dev.slimevr.gui.swing.EJBagNoStretch; -import io.eiren.util.StringUtils; - -import javax.swing.*; -import javax.swing.event.MouseInputAdapter; -import java.awt.event.MouseEvent; - - -public class TrackersFiltersGUI extends EJBagNoStretch { - - private final VRServer server; - private final JLabel amountLabel; - TrackerFilters filterType; - float filterAmount; - FiltersConfig filtersConfig; - - public TrackersFiltersGUI(VRServer server, VRServerGUI gui) { - - super(false, true); - this.server = server; - filtersConfig = server - .getConfigManager() - .getVrConfig() - .getFilters(); - - int row = 0; - - setAlignmentY(TOP_ALIGNMENT); - add(Box.createVerticalStrut(10)); - filterType = server.getConfigManager().getVrConfig().getFilters().enumGetType(); - - JComboBox filterSelect; - add(filterSelect = new JComboBox<>(), s(c(0, row, 2), 4, 1)); - - for (TrackerFilters f : TrackerFilters.values()) { - filterSelect.addItem(f.name()); - } - if (filterType != null) { - filterSelect.setSelectedItem(filterType.toString()); - } - - filterSelect.addActionListener((e) -> { - filterType = TrackerFilters - .getByConfigkey(filterSelect.getSelectedItem().toString()); - filtersConfig - .enumSetType(filterType); - filtersConfig - .updateTrackersFilters(); - server.getConfigManager().saveConfig(); - }); - add(Box.createVerticalStrut(40)); - row++; - - filterAmount = FastMath - .clamp( - server.getConfigManager().getVrConfig().getFilters().getAmount(), - 0.1f, - 1 - ); - - add(new JLabel("Amount"), c(0, row, 2)); - add(new AdjButton("+", false), c(1, row, 2)); - add( - amountLabel = new JLabel(StringUtils.prettyNumber(filterAmount * 100f) + "%"), - c(2, row, 2) - ); - add(new AdjButton("-", true), c(3, row, 2)); - } - - void adjustAmount(boolean neg) { - if (neg) { - filterAmount = FastMath.clamp(filterAmount - 0.1f, 0.1f, 1); - } else { - filterAmount = FastMath.clamp(filterAmount + 0.1f, 0.1f, 1); - } - amountLabel.setText((StringUtils.prettyNumber(filterAmount * 100f)) + "%"); - - filtersConfig - .setAmount(filterAmount); - filtersConfig - .updateTrackersFilters(); - - server.getConfigManager().saveConfig(); - } - - private class AdjButton extends JButton { - - public AdjButton(String text, boolean neg) { - super(text); - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - adjustAmount(neg); - } - }); - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/TrackersList.java b/server/src/main/java/dev/slimevr/gui/TrackersList.java deleted file mode 100644 index 6f84e74708..0000000000 --- a/server/src/main/java/dev/slimevr/gui/TrackersList.java +++ /dev/null @@ -1,568 +0,0 @@ -package dev.slimevr.gui; - -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import dev.slimevr.VRServer; -import dev.slimevr.config.TrackerConfig; -import dev.slimevr.gui.swing.EJBagNoStretch; -import dev.slimevr.gui.swing.EJBoxNoStretch; -import dev.slimevr.vr.trackers.*; -import io.eiren.util.StringUtils; -import io.eiren.util.ann.AWTThread; -import io.eiren.util.ann.ThreadSafe; -import io.eiren.util.collections.FastList; - -import javax.swing.*; -import java.awt.*; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; - - -public class TrackersList extends EJBoxNoStretch { - - private static final long UPDATE_DELAY = 50; - private final VRServer server; - private final VRServerGUI gui; - private final List trackers = new FastList<>(); - Quaternion q = new Quaternion(); - Vector3f v = new Vector3f(); - float[] angles = new float[3]; - private long lastUpdate = 0; - private boolean debug = false; - - public TrackersList(VRServer server, VRServerGUI gui) { - super(BoxLayout.PAGE_AXIS, false, true); - this.server = server; - this.gui = gui; - - setAlignmentY(TOP_ALIGNMENT); - - server.addNewTrackerConsumer(this::newTrackerAdded); - } - - private static int getTrackerSort(Tracker t) { - Tracker tracker = t.get(); - if (tracker instanceof IMUTracker) - return 0; - if (tracker instanceof HMDTracker) - return 100; - if (tracker instanceof ComputedTracker) - return 200; - return 1000; - } - - @AWTThread - public void setDebug(boolean debug) { - this.debug = debug; - build(); - } - - @AWTThread - private void build() { - removeAll(); - - trackers.sort(Comparator.comparingInt(tr -> getTrackerSort(tr.t))); - - Class currentClass = null; - - EJBoxNoStretch line = null; - boolean first = true; - - for (TrackerPanel tr : trackers) { - Tracker t = tr.t.get(); - if (currentClass != t.getClass()) { - currentClass = t.getClass(); - if (line != null) - line.add(Box.createHorizontalGlue()); - line = null; - line = new EJBoxNoStretch(BoxLayout.LINE_AXIS, false, true); - line.add(Box.createHorizontalGlue()); - JLabel nameLabel; - line.add(nameLabel = new JLabel(currentClass.getSimpleName())); - nameLabel.setFont(nameLabel.getFont().deriveFont(Font.BOLD)); - line.add(Box.createHorizontalGlue()); - add(line); - line = null; - } - - if (line == null) { - line = new EJBoxNoStretch(BoxLayout.LINE_AXIS, false, true); - add(Box.createVerticalStrut(3)); - add(line); - first = true; - } else { - line.add(Box.createHorizontalStrut(3)); - first = false; - } - tr.build(); - line.add(tr); - if (!first) - line = null; - } - validate(); - gui.refresh(); - } - - @ThreadSafe - public void updateTrackers() { - if (lastUpdate + UPDATE_DELAY > System.currentTimeMillis()) - return; - lastUpdate = System.currentTimeMillis(); - java.awt.EventQueue.invokeLater(() -> { - for (TrackerPanel tr : trackers) { - tr.update(); - } - }); - } - - @ThreadSafe - public void newTrackerAdded(Tracker t) { - java.awt.EventQueue.invokeLater(() -> { - trackers.add(new TrackerPanel(t)); - build(); - }); - } - - private class TrackerPanel extends EJBagNoStretch { - - final Tracker t; - JLabel position; - JLabel rotation; - JLabel status; - JLabel url; - JLabel tps; - JLabel bat; - JLabel ping; - JLabel raw; - JLabel rawMag; - JLabel calibration; - JLabel magAccuracy; - JLabel adj; - JLabel adjYaw; - JLabel adjGyro; - JLabel adjMounting; - JLabel correction; - JLabel signalStrength; - JLabel rotQuat; - JLabel rotAdj; - JLabel temperature; - JLabel accel; - - @AWTThread - public TrackerPanel(Tracker t) { - super(false, true); - - this.t = t; - } - - @SuppressWarnings("unchecked") - @AWTThread - public TrackerPanel build() { - int row = 0; - - Tracker tracker = t.get(); - removeAll(); - JLabel nameLabel; - add( - nameLabel = new JLabel( - t.getCustomName() != null ? t.getCustomName() : t.getDisplayName() - ), - s(c(0, row, 2, GridBagConstraints.FIRST_LINE_START), 4, 1) - ); - nameLabel.setFont(nameLabel.getFont().deriveFont(Font.BOLD)); - row++; - - if (t.userEditable()) { - TrackerConfig cfg = server.getConfigManager().getVrConfig().getTracker(t); - JComboBox desSelect; - add( - desSelect = new JComboBox<>(), - s(c(0, row, 2, GridBagConstraints.FIRST_LINE_START), 2, 1) - ); - desSelect.addItem("NONE"); - for (TrackerPosition p : TrackerPosition.values) { - desSelect.addItem(p.name()); - } - if (cfg.getDesignation() != null) { - TrackerPosition - .getByDesignation(cfg.getDesignation()) - .ifPresentOrElse( - trackerPosition -> desSelect.setSelectedItem(trackerPosition.name()), - () -> desSelect.setSelectedItem("NONE") - ); - } - desSelect.addActionListener(e -> { - if (desSelect.getSelectedItem() == "NONE") { - t.setBodyPosition(null); - } else { - TrackerPosition p = TrackerPosition - .valueOf(String.valueOf(desSelect.getSelectedItem())); - t.setBodyPosition(p); - } - server.trackerUpdated(t); - }); - if (tracker instanceof IMUTracker imu) { - JComboBox mountSelect; - add( - mountSelect = new JComboBox<>(), - s(c(2, row, 2, GridBagConstraints.FIRST_LINE_START), 2, 1) - ); - for (TrackerMountingRotation p : TrackerMountingRotation.values) { - mountSelect.addItem(p.name()); - } - - TrackerMountingRotation selected = TrackerMountingRotation - .fromQuaternion(imu.getMountingRotation()); - mountSelect - .setSelectedItem( - Objects - .requireNonNullElse(selected, TrackerMountingRotation.BACK) - .name() - ); - mountSelect.addActionListener(e -> { - TrackerMountingRotation tr = TrackerMountingRotation - .valueOf(String.valueOf(mountSelect.getSelectedItem())); - imu.setMountingRotation(tr.quaternion); - server.trackerUpdated(t); - }); - } - row++; - } - - if (t.getDevice() != null && t.getDevice().getIpAddress() != null) { - add(new JLabel("URL:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - url = new JLabel(""), - c(1, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - row++; - } - - if (t.hasRotation()) - add(new JLabel("Rotation"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - if (t.hasPosition()) - add(new JLabel("Position"), c(1, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(new JLabel("TPS"), c(3, row, 2, GridBagConstraints.FIRST_LINE_START)); - if (tracker instanceof TrackerWithWireless) { - add(new JLabel("Ping"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(new JLabel("Signal"), c(4, row, 2, GridBagConstraints.FIRST_LINE_START)); - } - row++; - if (t.hasRotation()) - add( - rotation = new JLabel("0 0 0"), - c(0, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - if (t.hasPosition()) - add( - position = new JLabel("0 0 0"), - c(1, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - if (tracker instanceof TrackerWithWireless) { - add(ping = new JLabel(""), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - signalStrength = new JLabel(""), - c(4, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - } - if (tracker instanceof TrackerWithTPS) { - add(tps = new JLabel("0"), c(3, row, 2, GridBagConstraints.FIRST_LINE_START)); - } else { - add(new JLabel(""), c(3, row, 2, GridBagConstraints.FIRST_LINE_START)); - } - row++; - add(new JLabel("Status:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - status = new JLabel(t.getStatus().toString().toLowerCase()), - c(1, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - if (tracker instanceof TrackerWithBattery) { - add(new JLabel("Battery:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(bat = new JLabel("0"), c(3, row, 2, GridBagConstraints.FIRST_LINE_START)); - } - row++; - add(new JLabel("Raw:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - raw = new JLabel("0 0 0"), - s(c(1, row, 2, GridBagConstraints.FIRST_LINE_START), 3, 1) - ); - - if (debug && tracker instanceof IMUTracker) { - add(new JLabel("Quat:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(rotQuat = new JLabel("0"), c(3, row, 2, GridBagConstraints.FIRST_LINE_START)); - } - row++; - - if (debug && tracker instanceof IMUTracker) { - add(new JLabel("Raw mag:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - rawMag = new JLabel("0 0 0"), - s(c(1, row, 2, GridBagConstraints.FIRST_LINE_START), 3, 1) - ); - add(new JLabel("Gyro fix:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - new JLabel(String.format("0x%8x", tracker.hashCode())), - s(c(3, row, 2, GridBagConstraints.FIRST_LINE_START), 3, 1) - ); - row++; - add(new JLabel("Cal:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - calibration = new JLabel("0"), - c(1, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - add(new JLabel("Mag acc:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - magAccuracy = new JLabel("0°"), - c(3, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - row++; - add(new JLabel("Correction:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - correction = new JLabel("0 0 0"), - s(c(1, row, 2, GridBagConstraints.FIRST_LINE_START), 3, 1) - ); - add(new JLabel("RotAdj:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(rotAdj = new JLabel("0"), c(3, row, 2, GridBagConstraints.FIRST_LINE_START)); - row++; - - add(new JLabel("Accel:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(accel = new JLabel("0 0 0"), c(1, row, 2, GridBagConstraints.FIRST_LINE_START)); - row++; - } - - if (debug && t instanceof ReferenceAdjustedTracker) { - add(new JLabel("Att fix:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(adj = new JLabel("0 0 0 0"), c(1, row, 2, GridBagConstraints.FIRST_LINE_START)); - add(new JLabel("Yaw Fix:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - adjYaw = new JLabel("0 0 0 0"), - c(3, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - row++; - add(new JLabel("Gyro Fix:"), c(0, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - adjGyro = new JLabel("0 0 0 0"), - c(1, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - add(new JLabel("Mount Fix:"), c(2, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - adjMounting = new JLabel("0 0 0 0"), - c(3, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - add(new JLabel("Temp:"), c(4, row, 2, GridBagConstraints.FIRST_LINE_START)); - add( - temperature = new JLabel("?"), - c(5, row, 2, GridBagConstraints.FIRST_LINE_START) - ); - } - - setBorder(BorderFactory.createLineBorder(new Color(0x663399), 2, false)); - TrackersList.this.add(this); - return this; - } - - @SuppressWarnings("unchecked") - @AWTThread - public void update() { - if (position == null && rotation == null) - return; - Tracker tracker = t.get(); - t.getRotation(q); - t.getPosition(v); - q.toAngles(angles); - - if (position != null) - position - .setText( - StringUtils.prettyNumber(v.x, 1) - + " " - + StringUtils.prettyNumber(v.y, 1) - + " " - + StringUtils.prettyNumber(v.z, 1) - ); - if (rotation != null) - rotation - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - status.setText(t.getStatus().toString().toLowerCase()); - if (t.getDevice() != null && t.getDevice().getIpAddress() != null) - url.setText("udp:/" + t.getDevice().getIpAddress()); - - if (tracker instanceof TrackerWithTPS) { - tps.setText(StringUtils.prettyNumber(((TrackerWithTPS) tracker).getTPS(), 1)); - } - if (tracker instanceof TrackerWithBattery twb) { - float level = twb.getBatteryLevel(); - float voltage = twb.getBatteryVoltage(); - if (level == 0.0f) { - bat.setText(String.format("%sV", StringUtils.prettyNumber(voltage, 2))); - } else if (voltage == 0.0f) { - bat.setText(String.format("%d%%", Math.round(level))); - } else { - bat - .setText( - String - .format( - "%d%% (%sV)", - Math.round(level), - StringUtils.prettyNumber(voltage, 2) - ) - ); - } - } - if (t instanceof ReferenceAdjustedTracker) { - ReferenceAdjustedTracker rat = (ReferenceAdjustedTracker) t; - if (adj != null) { - rat.attachmentFix.toAngles(angles); - adj - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (adjYaw != null) { - rat.yawFix.toAngles(angles); - adjYaw - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (adjGyro != null) { - rat.gyroFix.toAngles(angles); - adjGyro - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (adjMounting != null) { - rat.mountRotFix.toAngles(angles); - adjMounting - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - } - - if (tracker instanceof TrackerWithWireless) { - ping.setText(String.valueOf(((TrackerWithWireless) tracker).getPing())); - int signal = ((TrackerWithWireless) tracker).getSignalStrength(); - - if (signal == -1) { - signalStrength.setText("N/A"); - } else { - // -40 dBm is excellent, -95 dBm is very poor - int percentage = (signal - -95) * (100 - 0) / (-40 - -95) + 0; - percentage = Math.max(Math.min(percentage, 100), 0); - signalStrength.setText(percentage + "% " + "(" + signal + " dBm" + ")"); - } - } - - tracker.getRotation(q); - q.toAngles(angles); - raw - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - if (tracker instanceof IMUTracker imu) { - if (rawMag != null) { - imu.rotMagQuaternion.toAngles(angles); - rawMag - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (calibration != null) - calibration.setText(imu.calibrationStatus + " / " + imu.magCalibrationStatus); - if (magAccuracy != null) - magAccuracy - .setText( - StringUtils - .prettyNumber(imu.magnetometerAccuracy * FastMath.RAD_TO_DEG, 1) - + "°" - ); - if (correction != null) { - imu.getCorrection(q); - q.toAngles(angles); - correction - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (rotQuat != null) { - imu.rotQuaternion.toAngles(angles); - rotQuat - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (rotAdj != null) { - imu.rotAdjust.toAngles(angles); - rotAdj - .setText( - StringUtils.prettyNumber(angles[0] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[1] * FastMath.RAD_TO_DEG, 0) - + " " - + StringUtils.prettyNumber(angles[2] * FastMath.RAD_TO_DEG, 0) - ); - } - if (temperature != null) { - if (imu.temperature == 0.0f) { - // Can't be exact 0, so no info received - temperature.setText("?"); - } else { - temperature.setText(StringUtils.prettyNumber(imu.temperature, 1) + "∘C"); - } - } - if (accel != null) { - accel - .setText( - StringUtils.prettyNumber(imu.accelVector.x, 1) - + " " - + StringUtils.prettyNumber(imu.accelVector.y, 1) - + " " - + StringUtils.prettyNumber(imu.accelVector.z, 1) - ); - } - } - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/VRServerGUI.java b/server/src/main/java/dev/slimevr/gui/VRServerGUI.java deleted file mode 100644 index ca51565ced..0000000000 --- a/server/src/main/java/dev/slimevr/gui/VRServerGUI.java +++ /dev/null @@ -1,589 +0,0 @@ -package dev.slimevr.gui; - -import dev.slimevr.Main; -import dev.slimevr.VRServer; -import dev.slimevr.config.WindowConfig; -import dev.slimevr.gui.swing.ButtonTimer; -import dev.slimevr.gui.swing.EJBagNoStretch; -import dev.slimevr.gui.swing.EJBox; -import dev.slimevr.gui.swing.EJBoxNoStretch; -import dev.slimevr.platform.windows.WindowsNamedPipeBridge; -import dev.slimevr.vr.processor.skeleton.SkeletonConfigToggles; -import dev.slimevr.vr.trackers.TrackerRole; -import io.eiren.util.MacOSX; -import io.eiren.util.OperatingSystem; -import io.eiren.util.StringUtils; -import io.eiren.util.ann.AWTThread; - -import javax.imageio.ImageIO; -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import javax.swing.event.MouseInputAdapter; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ComponentEvent; -import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static javax.swing.BoxLayout.LINE_AXIS; -import static javax.swing.BoxLayout.PAGE_AXIS; - - -public class VRServerGUI extends JFrame { - - public static final String TITLE = "SlimeVR Server (" + Main.VERSION + ")"; - - public final VRServer server; - private final TrackersList trackersList; - private final TrackersFiltersGUI trackersFiltersGUI; - private final SkeletonList skeletonList; - private final EJBox pane; - private JButton resetButton; - private JButton resetMountingButton; - private JButton floorClipButton; - private JButton skatingCorrectionButton; - - private WindowConfig config; - - @AWTThread - public VRServerGUI(VRServer server) { - super(TITLE); - - this.config = server.getConfigManager().getVrConfig().getWindow(); - - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } - if (OperatingSystem.getCurrentPlatform() == OperatingSystem.OSX) - MacOSX.setTitle(TITLE); - try { - List images = new ArrayList<>(6); - images.add(ImageIO.read(VRServerGUI.class.getResource("/icon16.png"))); - images.add(ImageIO.read(VRServerGUI.class.getResource("/icon32.png"))); - images.add(ImageIO.read(VRServerGUI.class.getResource("/icon48.png"))); - images.add(ImageIO.read(VRServerGUI.class.getResource("/icon64.png"))); - images.add(ImageIO.read(VRServerGUI.class.getResource("/icon128.png"))); - images.add(ImageIO.read(VRServerGUI.class.getResource("/icon256.png"))); - setIconImages(images); - if (OperatingSystem.getCurrentPlatform() == OperatingSystem.OSX) { - MacOSX.setIcons(images); - } - } catch (IOException e1) { - e1.printStackTrace(); - } - - this.server = server; - - setDefaultFontSize(config.getZoom()); - // All components should be constructed to the current zoom level by - // default - - setDefaultCloseOperation(EXIT_ON_CLOSE); - getContentPane().setLayout(new BoxLayout(getContentPane(), PAGE_AXIS)); - - this.trackersList = new TrackersList(server, this); - trackersFiltersGUI = new TrackersFiltersGUI(server, this); - this.skeletonList = new SkeletonList(server, this); - - JScrollPane scrollPane = (JScrollPane) add( - new JScrollPane( - pane = new EJBox(PAGE_AXIS), - ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED - ) - ); - scrollPane.getVerticalScrollBar().setUnitIncrement(16); - - GraphicsConfiguration gc = getGraphicsConfiguration(); - Rectangle screenBounds = gc.getBounds(); - setMinimumSize(new Dimension(100, 100)); - setSize( - Math.min(config.getWidth(), screenBounds.width), - Math.min(config.getHeight(), screenBounds.height) - ); - - int posx = config.getPosx(); - if (posx == -1) { - posx = screenBounds.x + (screenBounds.width - getSize().width) / 2; - config.setPosx(posx); - } - - int posy = config.getPosy(); - if (posy == -1) { - posy = (screenBounds.height - getSize().height) / 2; - config.setPosy(posy); - } - - setLocation(posx, posy); - - // Resize and close listeners to save position and size betwen launcher - // starts - addComponentListener(new AbstractComponentListener() { - @Override - public void componentResized(ComponentEvent e) { - saveFrameInfo(); - } - - @Override - public void componentMoved(ComponentEvent e) { - saveFrameInfo(); - } - }); - - build(); - } - - private static void processNewZoom(float zoom, Component comp) { - if (comp.isFontSet()) { - Font newFont = new ScalableFont(comp.getFont(), zoom); - comp.setFont(newFont); - } - if (comp instanceof Container cont) { - for (Component child : cont.getComponents()) - processNewZoom(zoom, child); - } - } - - private static void setDefaultFontSize(float zoom) { - java.util.Enumeration keys = UIManager.getDefaults().keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - Object value = UIManager.get(key); - if (value instanceof javax.swing.plaf.FontUIResource f) { - javax.swing.plaf.FontUIResource f2 = new javax.swing.plaf.FontUIResource( - f.deriveFont(f.getSize() * zoom) - ); - UIManager.put(key, f2); - } - } - } - - protected void saveFrameInfo() { - Rectangle b = getBounds(); - config.setWidth(b.width); - config.setHeight(b.height); - config.setPosx(b.x); - config.setPosy(b.y); - server.getConfigManager().saveConfig(); - } - - public void refresh() { - // Pack and display - // pack(); - setVisible(true); - java.awt.EventQueue.invokeLater(this::repaint); - } - - @AWTThread - private void build() { - pane.removeAll(); - - pane.add(new EJBoxNoStretch(LINE_AXIS, false, true) { - { - setBorder(new EmptyBorder(i(5))); - - add(Box.createHorizontalGlue()); - add(resetButton = new JButton("RESET") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - reset(); - } - }); - } - }); - add(Box.createHorizontalStrut(10)); - add(resetMountingButton = new JButton("Reset Mounting") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - resetMounting(); - } - }); - } - }); - add(Box.createHorizontalStrut(10)); - add(new JButton("Fast Reset") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - resetFast(); - } - }); - } - }); - add(Box.createHorizontalStrut(10)); - add(floorClipButton = new JButton("Toggle Floor Clip") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - boolean[] state = server.humanPoseProcessor.getLegTweaksState(); - setFloorClipEnabled(!state[0]); - } - }); - } - }); - - setFloorClipEnabled( - server - .getConfigManager() - .getVrConfig() - .getSkeleton() - .getToggles() - .get(SkeletonConfigToggles.FLOOR_CLIP.configKey) - ); - - add(Box.createHorizontalStrut(10)); - add(skatingCorrectionButton = new JButton("Toggle Skating Correction") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - boolean[] state = server.humanPoseProcessor.getLegTweaksState(); - setSkatingReductionEnabled(!state[1]); - } - }); - } - }); - - setSkatingReductionEnabled( - server - .getConfigManager() - .getVrConfig() - .getSkeleton() - .getToggles() - .get(SkeletonConfigToggles.SKATING_CORRECTION.configKey) - ); - - add(Box.createHorizontalGlue()); - add(new JButton("Record BVH") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (!server.getBvhRecorder().isRecording()) { - setText("Stop Recording BVH..."); - server.getBvhRecorder().startRecording(); - } else { - server.getBvhRecorder().endRecording(); - setText("Record BVH"); - } - } - }); - } - }); - add(Box.createHorizontalGlue()); - add( - new JButton( - "GUI Zoom (x" + StringUtils.prettyNumber(config.getZoom(), 2) + ")" - ) { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - guiZoom(); - setText( - "GUI Zoom (x" - + StringUtils.prettyNumber(config.getZoom(), 2) - + ")" - ); - } - }); - } - } - ); - add(Box.createHorizontalStrut(10)); - add(new JButton("WiFi") { - { - addMouseListener(new MouseInputAdapter() { - @SuppressWarnings("unused") - @Override - public void mouseClicked(MouseEvent e) { - new WiFiWindow(VRServerGUI.this); - } - }); - } - }); - add(Box.createHorizontalStrut(10)); - } - }); - - pane.add(new EJBox(LINE_AXIS) { - { - setBorder(new EmptyBorder(i(5))); - add(new EJBoxNoStretch(PAGE_AXIS, false, true) { - { - setAlignmentY(TOP_ALIGNMENT); - JLabel l; - add(l = new JLabel("Trackers list")); - l.setFont(l.getFont().deriveFont(Font.BOLD)); - l.setAlignmentX(0.5f); - add(trackersList); - add(Box.createVerticalGlue()); - } - }); - - add(new EJBoxNoStretch(PAGE_AXIS, false, true) { - { - setAlignmentY(TOP_ALIGNMENT); - - JCheckBox debugCb; - add(debugCb = new JCheckBox("Show debug information")); - debugCb.setSelected(false); - debugCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - trackersList.setDebug(debugCb.isSelected()); - } - }); - - JLabel l; - add(l = new JLabel("Body proportions")); - l.setFont(l.getFont().deriveFont(Font.BOLD)); - l.setAlignmentX(0.5f); - add(new SkeletonConfigGUI(server, VRServerGUI.this)); - add(Box.createVerticalStrut(10)); - if (server.hasBridge(WindowsNamedPipeBridge.class)) { - WindowsNamedPipeBridge br = server - .getVRBridge(WindowsNamedPipeBridge.class); - add(l = new JLabel("SteamVR Trackers")); - l.setFont(l.getFont().deriveFont(Font.BOLD)); - l.setAlignmentX(0.5f); - add(l = new JLabel("Changes may require restart of SteamVR")); - l.setFont(l.getFont().deriveFont(Font.ITALIC)); - l.setAlignmentX(0.5f); - - add(new EJBagNoStretch(false, true) { - { - JCheckBox waistCb; - add(waistCb = new JCheckBox("Waist"), c(1, 1)); - waistCb.setSelected(br.getShareSetting(TrackerRole.WAIST)); - waistCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - server - .queueTask( - () -> br - .changeShareSettings( - TrackerRole.WAIST, - waistCb.isSelected() - ) - ); - } - }); - - JCheckBox legsCb; - add(legsCb = new JCheckBox("Feet"), c(2, 1)); - legsCb - .setSelected( - br.getShareSetting(TrackerRole.LEFT_FOOT) - && br.getShareSetting(TrackerRole.RIGHT_FOOT) - ); - legsCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - server.queueTask(() -> { - br - .changeShareSettings( - TrackerRole.LEFT_FOOT, - legsCb.isSelected() - ); - br - .changeShareSettings( - TrackerRole.RIGHT_FOOT, - legsCb.isSelected() - ); - }); - } - }); - - JCheckBox chestCb; - add(chestCb = new JCheckBox("Chest"), c(1, 2)); - chestCb.setSelected(br.getShareSetting(TrackerRole.CHEST)); - chestCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - server - .queueTask( - () -> br - .changeShareSettings( - TrackerRole.CHEST, - chestCb.isSelected() - ) - ); - } - }); - - JCheckBox kneesCb; - add(kneesCb = new JCheckBox("Knees"), c(2, 2)); - kneesCb - .setSelected( - br.getShareSetting(TrackerRole.LEFT_KNEE) - && br.getShareSetting(TrackerRole.RIGHT_KNEE) - ); - kneesCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - server.queueTask(() -> { - br - .changeShareSettings( - TrackerRole.LEFT_KNEE, - kneesCb.isSelected() - ); - br - .changeShareSettings( - TrackerRole.RIGHT_KNEE, - kneesCb.isSelected() - ); - }); - } - }); - - JCheckBox elbowsCb; - add(elbowsCb = new JCheckBox("Elbows"), c(1, 3)); - elbowsCb - .setSelected( - br.getShareSetting(TrackerRole.LEFT_ELBOW) - && br.getShareSetting(TrackerRole.RIGHT_ELBOW) - ); - elbowsCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - server.queueTask(() -> { - br - .changeShareSettings( - TrackerRole.LEFT_ELBOW, - elbowsCb.isSelected() - ); - br - .changeShareSettings( - TrackerRole.RIGHT_ELBOW, - elbowsCb.isSelected() - ); - }); - } - }); - - JCheckBox handsCb; - add(handsCb = new JCheckBox("Hands"), c(2, 3)); - handsCb - .setSelected( - br.getShareSetting(TrackerRole.LEFT_HAND) - && br.getShareSetting(TrackerRole.RIGHT_HAND) - ); - handsCb.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - server.queueTask(() -> { - br - .changeShareSettings( - TrackerRole.LEFT_HAND, - handsCb.isSelected() - ); - br - .changeShareSettings( - TrackerRole.RIGHT_HAND, - handsCb.isSelected() - ); - }); - } - }); - } - }); - - add(Box.createVerticalStrut(10)); - } - - add(l = new JLabel("Trackers filtering")); - l.setFont(l.getFont().deriveFont(Font.BOLD)); - l.setAlignmentX(0.5f); - add(trackersFiltersGUI); - - add(Box.createVerticalStrut(10)); - - add(new JLabel("Skeleton data")); - add(skeletonList); - add(Box.createVerticalGlue()); - } - }); - } - }); - pane.add(Box.createVerticalGlue()); - - refresh(); - - server.addOnTick(trackersList::updateTrackers); - server.addOnTick(skeletonList::updateBones); - } - - // For now only changes font size, but should change fixed components size - // in - // the future too - private void guiZoom() { - if (config.getZoom() <= 1.0f) { - config.setZoom(1.5f); - } else if (config.getZoom() <= 1.5f) { - config.setZoom(1.75f); - } else if (config.getZoom() <= 1.75f) { - config.setZoom(2f); - } else if (config.getZoom() <= 2.0f) { - config.setZoom(2.5f); - } else { - config.setZoom(1f); - } - processNewZoom(config.getZoom() / WindowConfig.INITAL_ZOOM, pane); - refresh(); - server.getConfigManager().saveConfig(); - } - - @AWTThread - private void resetFast() { - server.resetTrackersYaw(); - } - - @AWTThread - private void reset() { - ButtonTimer.runTimer(resetButton, 3, "RESET", server::resetTrackers); - } - - @AWTThread - private void resetMounting() { - ButtonTimer - .runTimer(resetMountingButton, 3, "Reset Mounting", server::resetTrackersMounting); - } - - @AWTThread - private void setSkatingReductionEnabled(Boolean value) { - if (value == null) - value = false; - - skatingCorrectionButton.setBackground(value ? Color.GREEN : Color.RED); - - skatingCorrectionButton - .setText("Skating Correction: " + (value ? "ON" : "OFF")); - - server.setSkatingReductionEnabled(value); - } - - @AWTThread - private void setFloorClipEnabled(Boolean value) { - if (value == null) - value = false; - - floorClipButton.setBackground(value ? Color.GREEN : Color.RED); - - // update the button - floorClipButton.setText("Floor clip: " + (value ? "ON" : "OFF")); - server.setFloorClipEnabled(value); - } -} diff --git a/server/src/main/java/dev/slimevr/gui/WiFiWindow.java b/server/src/main/java/dev/slimevr/gui/WiFiWindow.java deleted file mode 100644 index 7094eb111f..0000000000 --- a/server/src/main/java/dev/slimevr/gui/WiFiWindow.java +++ /dev/null @@ -1,194 +0,0 @@ -package dev.slimevr.gui; - -import com.fazecast.jSerialComm.SerialPort; -import dev.slimevr.gui.swing.EJBox; -import dev.slimevr.serial.SerialListener; -import io.eiren.util.ann.AWTThread; - -import javax.swing.*; -import javax.swing.event.MouseInputAdapter; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - - -public class WiFiWindow extends JFrame implements SerialListener { - - private static String savedSSID = ""; - private static String savedPassword = ""; - private final VRServerGUI gui; - private JScrollPane scroll; - JTextField ssidField; - JPasswordField passwdField; - JTextArea log; - - public WiFiWindow(VRServerGUI gui) { - super("WiFi Settings"); - this.gui = gui; - - getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.LINE_AXIS)); - - this.gui.server.getSerialHandler().addListener(this); - - build(); - } - - @AWTThread - private void build() { - if (!this.gui.server.getSerialHandler().openSerial()) { - JOptionPane - .showMessageDialog( - null, - "Unable to open a serial connection. Check that your drivers are installed and nothing is using the serial port already (like Cura or VScode or another slimeVR server)", - "SlimeVR: Serial connection error", - JOptionPane.ERROR_MESSAGE - ); - } - } - - @Override - @AWTThread - public void onSerialConnected(SerialPort port) { - Container pane = getContentPane(); - pane.add(new EJBox(BoxLayout.PAGE_AXIS) { - { - add( - new JLabel( - "Tracker connected to " - + port.getSystemPortName() - + " (" - + port.getDescriptivePortName() - + ")" - ) - ); - add(new EJBox(BoxLayout.LINE_AXIS) { - { - add(new JButton("Reboot Tracker") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - gui.server.getSerialHandler().rebootRequest(); - } - }); - } - }); - add(new JButton("INFO") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - gui.server.getSerialHandler().infoRequest(); - } - }); - } - }); - add(new JButton("Factory Reset") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - gui.server.getSerialHandler().factoryResetRequest(); - } - }); - } - }); - } - }); - - add( - scroll = new JScrollPane( - log = new JTextArea(10, 20), - ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER - ) - ); - log.setLineWrap(true); - scroll.setAutoscrolls(true); - add(new JLabel("Enter WiFi credentials:")); - add(new EJBox(BoxLayout.LINE_AXIS) { - { - add(new JLabel("Network name:")); - add(ssidField = new JTextField(savedSSID)); - } - }); - add(new EJBox(BoxLayout.LINE_AXIS) { - { - add(new JLabel("Network password:")); - passwdField = new JPasswordField(savedPassword); - passwdField.setEchoChar('\u25cf'); - add(passwdField); - add(new JCheckBox("Show Password") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (isSelected()) - passwdField.setEchoChar((char) 0); - else - passwdField.setEchoChar('\u25cf'); - } - }); - } - }); - } - }); - add(new JButton("Send") { - { - addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - savedSSID = ssidField.getText(); - savedPassword = new String(passwdField.getPassword()); - gui.server.getSerialHandler().setWifi(savedSSID, savedPassword); - } - }); - } - }); - } - }); - - pack(); - setLocationRelativeTo(null); - setVisible(true); - java.awt.EventQueue.invokeLater(() -> { - toFront(); - repaint(); - }); - setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - final WiFiWindow window = this; - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent windowEvent) { - gui.server.getSerialHandler().closeSerial(); - dispose(); - gui.server.getSerialHandler().removeListener(window); - } - }); - } - - @Override - @AWTThread - public void onSerialDisconnected() { - if (this.log == null) - return; - log.append("[SERVER] Serial port disconnected\n"); - } - - @Override - @AWTThread - public void onSerialLog(String str) { - if (this.log == null) - return; - log.append(str); - // log.setAutoscrolls(true); - if (scroll != null) { - JScrollBar vertical = scroll.getVerticalScrollBar(); - if ((vertical.getValue() + str.length() + 200) > vertical.getMaximum()) { - vertical.setValue(vertical.getMaximum()); - } - } - - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/ButtonTimer.java b/server/src/main/java/dev/slimevr/gui/swing/ButtonTimer.java deleted file mode 100644 index 79da63a184..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/ButtonTimer.java +++ /dev/null @@ -1,51 +0,0 @@ -package dev.slimevr.gui.swing; - -import javax.swing.*; -import java.util.Timer; -import java.util.TimerTask; - - -public class ButtonTimer { - - private static final Timer timer = new Timer(); - - public static void runTimer( - AbstractButton button, - int seconds, - String defaultText, - Runnable runnable - ) { - if (seconds <= 0) { - button.setText(defaultText); - runnable.run(); - } else { - button.setText(String.valueOf(seconds)); - timer.schedule(new ButtonTimerTask(button, seconds - 1, defaultText, runnable), 1000); - } - } - - private static class ButtonTimerTask extends TimerTask { - - private final AbstractButton button; - private final int seconds; - private final String defaultText; - private final Runnable runnable; - - private ButtonTimerTask( - AbstractButton button, - int seconds, - String defaultText, - Runnable runnable - ) { - this.button = button; - this.seconds = seconds; - this.defaultText = defaultText; - this.runnable = runnable; - } - - @Override - public void run() { - runTimer(button, seconds, defaultText, runnable); - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/EJBag.java b/server/src/main/java/dev/slimevr/gui/swing/EJBag.java deleted file mode 100644 index 38697e58c8..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/EJBag.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.slimevr.gui.swing; - -import java.awt.*; - - -public class EJBag extends EJPanel { - - public EJBag() { - super(new GridBagLayout()); - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/EJBagNoStretch.java b/server/src/main/java/dev/slimevr/gui/swing/EJBagNoStretch.java deleted file mode 100644 index f5db19e066..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/EJBagNoStretch.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.slimevr.gui.swing; - -import java.awt.*; - - -public class EJBagNoStretch extends EJPanel { - - public EJBagNoStretch(boolean stretchVertical, boolean stretchHorizontal) { - super(new EGridBagLayoutNoStretch(stretchVertical, stretchHorizontal)); - } - - private static class EGridBagLayoutNoStretch extends GridBagLayout { - - private final boolean stretchVertical; - private final boolean stretchHorizontal; - - public EGridBagLayoutNoStretch(boolean stretchVertical, boolean stretchHorizontal) { - this.stretchVertical = stretchVertical; - this.stretchHorizontal = stretchHorizontal; - } - - @Override - public Dimension maximumLayoutSize(Container target) { - Dimension pref = preferredLayoutSize(target); - if (stretchVertical) - pref.height = Integer.MAX_VALUE; - if (stretchHorizontal) - pref.width = Integer.MAX_VALUE; - return pref; - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/EJBox.java b/server/src/main/java/dev/slimevr/gui/swing/EJBox.java deleted file mode 100644 index a2788ee8ff..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/EJBox.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.slimevr.gui.swing; - -import javax.swing.*; - - -public class EJBox extends EJPanel { - - public EJBox(int layout) { - super(); - setLayout(new BoxLayout(this, layout)); - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/EJBoxNoStretch.java b/server/src/main/java/dev/slimevr/gui/swing/EJBoxNoStretch.java deleted file mode 100644 index b5cab4c1e3..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/EJBoxNoStretch.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.slimevr.gui.swing; - -import javax.swing.*; -import java.awt.*; - - -public class EJBoxNoStretch extends EJPanel { - - public EJBoxNoStretch(int layout, boolean stretchVertical, boolean stretchHorizontal) { - super(); - setLayout(new BoxLayoutNoStretch(this, layout, stretchVertical, stretchHorizontal)); - } - - private static class BoxLayoutNoStretch extends BoxLayout { - - private final boolean stretchVertical; - private final boolean stretchHorizontal; - - public BoxLayoutNoStretch( - Container target, - int axis, - boolean stretchVertical, - boolean stretchHorizontal - ) { - super(target, axis); - this.stretchVertical = stretchVertical; - this.stretchHorizontal = stretchHorizontal; - } - - @Override - public Dimension maximumLayoutSize(Container target) { - Dimension pref = preferredLayoutSize(target); - if (stretchVertical) - pref.height = Integer.MAX_VALUE; - if (stretchHorizontal) - pref.width = Integer.MAX_VALUE; - return pref; - } - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/EJPanel.java b/server/src/main/java/dev/slimevr/gui/swing/EJPanel.java deleted file mode 100644 index d10484f037..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/EJPanel.java +++ /dev/null @@ -1,105 +0,0 @@ -package dev.slimevr.gui.swing; - -import javax.swing.*; -import java.awt.*; - - -public abstract class EJPanel extends JPanel { - - public static boolean NEEDS_DOWNSCALE = false; - public static float DOWNSCALE_FACTOR = 0.75f; - - public EJPanel() { - super(); - } - - public EJPanel(LayoutManager manager) { - super(manager); - } - - public static void s(Component c, int width, int height) { - if (NEEDS_DOWNSCALE) { - width = (int) Math.ceil(width * DOWNSCALE_FACTOR); - height = (int) Math.ceil(height * DOWNSCALE_FACTOR); - } - c.setSize(width, height); - Dimension d = new Dimension(width, height); - c.setPreferredSize(d); - c.setMaximumSize(d); - c.setMinimumSize(d); - } - - public static void minWidth(Component c, int width, int height) { - if (NEEDS_DOWNSCALE) { - height = (int) Math.ceil(height * DOWNSCALE_FACTOR); - width = (int) Math.ceil(width * DOWNSCALE_FACTOR); - } - c.setPreferredSize(new Dimension(Short.MAX_VALUE, height)); - c.setMaximumSize(new Dimension(Short.MAX_VALUE, height)); - c.setMinimumSize(new Dimension(width, height)); - } - - public static void minHeight(Component c, int width, int height) { - if (NEEDS_DOWNSCALE) { - height = (int) Math.ceil(height * DOWNSCALE_FACTOR); - width = (int) Math.ceil(width * DOWNSCALE_FACTOR); - } - c.setPreferredSize(new Dimension(width, Short.MAX_VALUE)); - c.setMaximumSize(new Dimension(width, Short.MAX_VALUE)); - c.setMinimumSize(new Dimension(width, height)); - } - - public static GridBagConstraints c(int x, int y) { - GridBagConstraints c = new GridBagConstraints(); - c.gridx = x; - c.gridy = y; - return c; - } - - public static GridBagConstraints c(int x, int y, int padding) { - GridBagConstraints c = new GridBagConstraints(); - c.gridx = x; - c.gridy = y; - c.insets = new Insets(padding, padding, padding, padding); - return c; - } - - public static GridBagConstraints c(int x, int y, int padding, int anchor) { - GridBagConstraints c = new GridBagConstraints(); - c.gridx = x; - c.gridy = y; - c.insets = new Insets(padding, padding, padding, padding); - c.anchor = anchor; - return c; - } - - public static GridBagConstraints c(int x, int y, Insets insets) { - GridBagConstraints c = new GridBagConstraints(); - c.gridx = x; - c.gridy = y; - c.insets = insets; - return c; - } - - public static GridBagConstraints s(GridBagConstraints c, int gridwidth, int gridheight) { - c.gridwidth = gridwidth; - c.gridheight = gridheight; - return c; - } - - public static Insets i(int s) { - return new Insets(s, s, s, s); - } - - public static Insets i(int h, int v) { - return new Insets(v, h, v, h); - } - - public static Component padding(int width, int height) { - return Box.createRigidArea(new Dimension(width, height)); - } - - public static int fontSize(int baseSize) { - return NEEDS_DOWNSCALE ? (int) Math.ceil(baseSize * DOWNSCALE_FACTOR) : baseSize; - } -} diff --git a/server/src/main/java/dev/slimevr/gui/swing/EJlabel.java b/server/src/main/java/dev/slimevr/gui/swing/EJlabel.java deleted file mode 100644 index a219d2c4d5..0000000000 --- a/server/src/main/java/dev/slimevr/gui/swing/EJlabel.java +++ /dev/null @@ -1,8 +0,0 @@ -package dev.slimevr.gui.swing; - -import javax.swing.*; - - -public class EJlabel extends JLabel { - -} diff --git a/server/src/main/java/org/json/JSONArray.java b/server/src/main/java/org/json/JSONArray.java deleted file mode 100644 index e64fa74f3b..0000000000 --- a/server/src/main/java/org/json/JSONArray.java +++ /dev/null @@ -1,878 +0,0 @@ -package org.json; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - - -/** - * A JSONArray is an ordered sequence of values. Its external text form is a - * string wrapped in square brackets with commas separating the values. The - * internal form is an object having get and opt - * methods for accessing the values by index, and put methods for - * adding or replacing values. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the - * JSONObject.NULL object. - *

- * The constructor can convert a JSON text into a Java object. The - * toString method converts to JSON text. - *

- * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. - *

- * The texts produced by the toString methods strictly conform to - * JSON syntax rules. The constructors are more forgiving in the texts they will - * accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing bracket.
  • - *
  • The null value will be inserted when there is , - *  (comma) elision.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
  • Values can be separated by ; (semicolon) as - * well as by , (comma).
  • - *
- * - * @author JSON.org - * @version 2012-04-20 - */ -public class JSONArray { - - /** - * The arrayList where the JSONArray's properties are kept. - */ - private final ArrayList myArrayList; - - /** - * Construct an empty JSONArray. - */ - public JSONArray() { - this.myArrayList = new ArrayList<>(); - } - - public JSONArray(int initialLength) { - this.myArrayList = new ArrayList<>(initialLength); - } - - /** - * Construct a JSONArray from a JSONTokener. - * - * @param x A JSONTokener - * @throws JSONException If there is a syntax error. - */ - public JSONArray(JSONTokener x) throws JSONException { - this(); - if (x.nextClean() != '[') { - throw x.syntaxError("A JSONArray text must start with '['"); - } - if (x.nextClean() != ']') { - x.back(); - for (;;) { - if (x.nextClean() == ',') { - x.back(); - this.myArrayList.add(JSONObject.NULL); - } else { - x.back(); - this.myArrayList.add(x.nextValue()); - } - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == ']') { - return; - } - x.back(); - break; - case ']': - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); - } - } - } - } - - /** - * Construct a JSONArray from a source JSON text. - * - * @param source A string that begins with [ (left - * bracket) and ends with ]  (right - * bracket). - * @throws JSONException If there is a syntax error. - */ - public JSONArray(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONArray from a Collection. - * - * @param collection A Collection. - */ - public JSONArray(Collection collection) { - this.myArrayList = new ArrayList<>(); - if (collection != null) { - for (Object o : collection) { - this.myArrayList.add(JSONObject.wrap(o)); - } - } - } - - /** - * Construct a JSONArray from an array - * - * @throws JSONException If not an array. - */ - public JSONArray(Object array) { - this(); - if (array.getClass().isArray()) { - int length = Array.getLength(array); - for (int i = 0; i < length; i += 1) { - this.put(JSONObject.wrap(Array.get(array, i))); - } - } else { - throw new IllegalArgumentException( - "JSONArray initial value should be a string or collection or array." - ); - } - } - - /** - * Get the object value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return An object value. - * @throws JSONException If there is no value for the index. - */ - public Object get(int index) throws JSONException { - Object object = this.opt(index); - if (object == null) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - return object; - } - - /** - * Get the boolean value associated with an index. The string values "true" - * and "false" are converted to boolean. - * - * @param index The index must be between 0 and length() - 1. - * @return The truth. - * @throws JSONException If there is no value for the index or if the value - * is not convertible to boolean. - */ - public boolean getBoolean(int index) throws JSONException { - Object object = this.get(index); - if ( - object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object).equalsIgnoreCase("false")) - ) { - return false; - } else if ( - object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object).equalsIgnoreCase("true")) - ) { - return true; - } - throw new JSONException("JSONArray[" + index + "] is not a boolean."); - } - - /** - * Get the double value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException If the key is not found or if the value cannot be - * converted to a number. - */ - public double getDouble(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the int value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException If the key is not found or if the value is not a - * number. - */ - public int getInt(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the JSONArray associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return A JSONArray value. - * @throws JSONException If there is no value for the index. or if the value - * is not a JSONArray - */ - public JSONArray getJSONArray(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); - } - - /** - * Get the JSONObject associated with an index. - * - * @param index subscript - * @return A JSONObject value. - * @throws JSONException If there is no value for the index or if the value - * is not a JSONObject - */ - public JSONObject getJSONObject(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); - } - - /** - * Get the long value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException If the key is not found or if the value cannot be - * converted to a number. - */ - public long getLong(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the string associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return A string value. - * @throws JSONException If there is no string value for the index. - */ - public String getString(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONArray[" + index + "] not a string."); - } - - /** - * Determine if the value is null. - * - * @param index The index must be between 0 and length() - 1. - * @return true if the value at the index is null, or if there is no value. - */ - public boolean isNull(int index) { - return JSONObject.NULL.equals(this.opt(index)); - } - - /** - * Make a string from the contents of this JSONArray. The - * separator string is inserted between each element. Warning: - * This method assumes that the data structure is acyclical. - * - * @param separator A string that will be inserted between the elements. - * @return a string. - * @throws JSONException If the array contains an invalid number. - */ - public String join(String separator) throws JSONException { - int len = this.length(); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < len; i += 1) { - if (i > 0) { - sb.append(separator); - } - sb.append(JSONObject.valueToString(this.myArrayList.get(i))); - } - return sb.toString(); - } - - /** - * Get the number of elements in the JSONArray, included nulls. - * - * @return The length (or size). - */ - public int length() { - return this.myArrayList.size(); - } - - /** - * Get the optional object value associated with an index. - * - * @param index The index must be between 0 and length() - 1. - * @return An object value, or null if there is no object at that index. - */ - public Object opt(int index) { - return (index < 0 || index >= this.length()) ? null : this.myArrayList.get(index); - } - - /** - * Get the optional boolean value associated with an index. It returns false - * if there is no value at that index, or if the value is not Boolean.TRUE - * or the String "true". - * - * @param index The index must be between 0 and length() - 1. - * @return The truth. - */ - public boolean optBoolean(int index) { - return this.optBoolean(index, false); - } - - /** - * Get the optional boolean value associated with an index. It returns the - * defaultValue if there is no value at that index or if it is not a Boolean - * or the String "true" or "false" (case insensitive). - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue A boolean default. - * @return The truth. - */ - public boolean optBoolean(int index, boolean defaultValue) { - try { - return this.getBoolean(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional double value associated with an index. NaN is returned - * if there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - */ - public double optDouble(int index) { - return this.optDouble(index, Double.NaN); - } - - /** - * Get the optional double value associated with an index. The defaultValue - * is returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index subscript - * @param defaultValue The default value. - * @return The value. - */ - public double optDouble(int index, double defaultValue) { - try { - return this.getDouble(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional int value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - */ - public int optInt(int index) { - return this.optInt(index, 0); - } - - /** - * Get the optional int value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue The default value. - * @return The value. - */ - public int optInt(int index, int defaultValue) { - try { - return this.getInt(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional JSONArray associated with an index. - * - * @param index subscript - * @return A JSONArray value, or null if the index has no value, or if the - * value is not a JSONArray. - */ - public JSONArray optJSONArray(int index) { - Object o = this.opt(index); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get the optional JSONObject associated with an index. Null is returned if - * the key is not found, or null if the index has no value, or if the value - * is not a JSONObject. - * - * @param index The index must be between 0 and length() - 1. - * @return A JSONObject value. - */ - public JSONObject optJSONObject(int index) { - Object o = this.opt(index); - return o instanceof JSONObject ? (JSONObject) o : null; - } - - /** - * Get the optional long value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @return The value. - */ - public long optLong(int index) { - return this.optLong(index, 0); - } - - /** - * Get the optional long value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue The default value. - * @return The value. - */ - public long optLong(int index, long defaultValue) { - try { - return this.getLong(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional string value associated with an index. It returns an - * empty string if there is no value at that index. If the value is not a - * string and is not null, then it is coverted to a string. - * - * @param index The index must be between 0 and length() - 1. - * @return A String value. - */ - public String optString(int index) { - return this.optString(index, ""); - } - - /** - * Get the optional string associated with an index. The defaultValue is - * returned if the key is not found. - * - * @param index The index must be between 0 and length() - 1. - * @param defaultValue The default value. - * @return A String value. - */ - public String optString(int index, String defaultValue) { - Object object = this.opt(index); - return JSONObject.NULL.equals(object) ? defaultValue : object.toString(); - } - - /** - * Append a boolean value. This increases the array's length by one. - * - * @param value A boolean value. - * @return this. - */ - public JSONArray put(boolean value) { - this.put(value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param value A Collection value. - * @return this. - */ - public JSONArray put(Collection value) { - this.put(new JSONArray(value)); - return this; - } - - /** - * Append a double value. This increases the array's length by one. - * - * @param value A double value. - * @throws JSONException if the value is not finite. - * @return this. - */ - public JSONArray put(double value) throws JSONException { - Double d = value; - JSONObject.testValidity(d); - this.put(d); - return this; - } - - /** - * Append an int value. This increases the array's length by one. - * - * @param value An int value. - * @return this. - */ - public JSONArray put(int value) { - this.put(Integer.valueOf(value)); - return this; - } - - /** - * Append an long value. This increases the array's length by one. - * - * @param value A long value. - * @return this. - */ - public JSONArray put(long value) { - this.put(Long.valueOf(value)); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject which - * is produced from a Map. - * - * @param value A Map value. - * @return this. - */ - public JSONArray put(Map value) { - this.put(new JSONObject(value)); - return this; - } - - /** - * Append an object value. This increases the array's length by one. - * - * @param value An object value. The value should be a Boolean, Double, - * Integer, JSONArray, JSONObject, Long, or String, or the JSONObject.NULL - * object. - * @return this. - */ - public JSONArray put(Object value) { - this.myArrayList.add(value); - return this; - } - - /** - * Put or replace a boolean value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index The subscript. - * @param value A boolean value. - * @return this. - * @throws JSONException If the index is negative. - */ - public JSONArray put(int index, boolean value) throws JSONException { - this.put(index, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param index The subscript. - * @param value A Collection value. - * @return this. - * @throws JSONException If the index is negative or if the value is not - * finite. - */ - public JSONArray put(int index, Collection value) throws JSONException { - this.put(index, new JSONArray(value)); - return this; - } - - /** - * Put or replace a double value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index The subscript. - * @param value A double value. - * @return this. - * @throws JSONException If the index is negative or if the value is not - * finite. - */ - public JSONArray put(int index, double value) throws JSONException { - this.put(index, Double.valueOf(value)); - return this; - } - - /** - * Put or replace an int value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index The subscript. - * @param value An int value. - * @return this. - * @throws JSONException If the index is negative. - */ - public JSONArray put(int index, int value) throws JSONException { - this.put(index, Integer.valueOf(value)); - return this; - } - - /** - * Put or replace a long value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index The subscript. - * @param value A long value. - * @return this. - * @throws JSONException If the index is negative. - */ - public JSONArray put(int index, long value) throws JSONException { - this.put(index, Long.valueOf(value)); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject that - * is produced from a Map. - * - * @param index The subscript. - * @param value The Map value. - * @return this. - * @throws JSONException If the index is negative or if the the value is an - * invalid number. - */ - public JSONArray put(int index, Map value) throws JSONException { - this.put(index, new JSONObject(value)); - return this; - } - - /** - * Put or replace an object value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index The subscript. - * @param value The value to put into the array. The value should be a - * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the - * JSONObject.NULL object. - * @return this. - * @throws JSONException If the index is negative or if the the value is an - * invalid number. - */ - public JSONArray put(int index, Object value) throws JSONException { - JSONObject.testValidity(value); - if (index < 0) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - if (index < this.length()) { - this.myArrayList.set(index, value); - } else { - while (index != this.length()) { - this.put(JSONObject.NULL); - } - this.put(value); - } - return this; - } - - /** - * Remove an index and close the hole. - * - * @param index The index of the element to be removed. - * @return The value that was associated with the index, or null if there - * was no value. - */ - public Object remove(int index) { - Object o = this.opt(index); - this.myArrayList.remove(index); - return o; - } - - /** - * Produce a JSONObject by combining a JSONArray of names with the values of - * this JSONArray. - * - * @param names A JSONArray containing a list of key strings. These will be - * paired with the values. - * @return A JSONObject, or null if there are no names or if this JSONArray - * has no values. - * @throws JSONException If any of the names are null. - */ - public JSONObject toJSONObject(JSONArray names) throws JSONException { - if (names == null || names.length() == 0 || this.length() == 0) { - return null; - } - JSONObject jo = new JSONObject(); - for (int i = 0; i < names.length(); i += 1) { - jo.put(names.getString(i), this.opt(i)); - } - return jo; - } - - /** - * Make a JSON text of this JSONArray. For compactness, no unnecessary - * whitespace is added. If it is not possible to produce a syntactically - * correct JSON text then null will be returned instead. This could occur if - * the array contains an invalid number. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, transmittable representation of the - * array. - */ - @Override - public String toString() { - try { - return '[' + this.join(",") + ']'; - } catch (Exception e) { - return null; - } - } - - /** - * Make a prettyprinted JSON text of this JSONArray. Warning: This method - * assumes that the data structure is acyclical. - * - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @return a printable, displayable, transmittable representation of the - * object, beginning with [ (left bracket) - * and ending with ]  (right bracket). - * @throws JSONException - */ - public String toString(int indentFactor) throws JSONException { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - return this.write(sw, indentFactor, 0).toString(); - } - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @param indent The indention of the top level. - * @return The writer. - * @throws JSONException - */ - Writer write(Writer writer, int indentFactor, int indent) throws JSONException { - try { - boolean commanate = false; - int length = this.length(); - writer.write('['); - - if (length == 1) { - JSONObject.writeValue(writer, this.myArrayList.get(0), indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - - for (int i = 0; i < length; i += 1) { - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, newindent); - JSONObject.writeValue(writer, this.myArrayList.get(i), indentFactor, newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, indent); - } - writer.write(']'); - return writer; - } catch (IOException e) { - throw new JSONException(e); - } - } -} diff --git a/server/src/main/java/org/json/JSONException.java b/server/src/main/java/org/json/JSONException.java deleted file mode 100644 index 64ae077a93..0000000000 --- a/server/src/main/java/org/json/JSONException.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.json; - -/** - * The JSONException is thrown by the JSON.org classes when things are amiss. - * - * @author JSON.org - * @version 2010-12-24 - */ -public class JSONException extends RuntimeException { - - private static final long serialVersionUID = 0; - - /** - * Constructs a JSONException with an explanatory message. - * - * @param message Detail about the reason for the exception. - */ - public JSONException(String message) { - super(message); - } - - public JSONException(Throwable cause) { - super(cause.getMessage()); - initCause(cause); - } -} diff --git a/server/src/main/java/org/json/JSONObject.java b/server/src/main/java/org/json/JSONObject.java deleted file mode 100644 index 9a0e0154f0..0000000000 --- a/server/src/main/java/org/json/JSONObject.java +++ /dev/null @@ -1,1586 +0,0 @@ -package org.json; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.ResourceBundle; - - -/** - * A JSONObject is an unordered collection of name/value pairs. Its external - * form is a string wrapped in curly braces with colons between the names and - * values, and commas between the values and names. The internal form is an - * object having get and opt methods for accessing the - * values by name, and put methods for adding or replacing values - * by name. The values can be any of these types: Boolean, - * JSONArray, JSONObject, Number, - * String, or the JSONObject.NULL object. A JSONObject - * constructor can be used to convert an external form JSON text into an - * internal form whose values can be retrieved with the get and - * opt methods, or to convert values into a JSON text using the - * put and toString methods. A get method - * returns a value if one can be found, and throws an exception if one cannot be - * found. An opt method returns a default value instead of throwing - * an exception, and so is useful for obtaining optional values. - *

- * The generic get() and opt() methods return an - * object, which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. The opt methods differ from the get methods in that they do - * not throw. Instead, they return a specified value, such as null. - *

- * The put methods add or replace values in an object. For example, - * - *

- * myString = new JSONObject().put("JSON", "Hello, World!").toString();
- * 
- * - * produces the string {"JSON": "Hello, World"}. - *

- * The texts produced by the toString methods strictly conform to - * the JSON syntax rules. The constructors are more forgiving in the texts they - * will accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing brace.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
  • Keys can be followed by = or => as well as by - * :.
  • - *
  • Values can be followed by ; (semicolon) as - * well as by , (comma).
  • - *
- * - * @author JSON.org - * @version 2012-04-20 - */ -public class JSONObject { - - /** - * JSONObject.NULL is equivalent to the value that JavaScript calls null, - * whilst Java's null is equivalent to the value that JavaScript calls - * undefined. - */ - private static final class Null { - - /** - * There is only intended to be a single instance of the NULL object, so - * the clone method returns itself. - * - * @return NULL. - */ - @Override - protected Object clone() { - return this; - } - - /** - * A Null object is equal to the null value and to itself. - * - * @param object An object to test for nullness. - * @return true if the object parameter is the JSONObject.NULL object or - * null. - */ - @Override - public boolean equals(Object object) { - return object == null || object == this; - } - - /** - * Get the "null" string value. - * - * @return The string "null". - */ - @Override - public String toString() { - return "null"; - } - - @Override - public int hashCode() { - return 0; - } - } - - /** - * The map where the JSONObject's properties are kept. - */ - private final Map map; - - /** - * It is sometimes more convenient and less ambiguous to have a - * NULL object than to use Java's null value. - * JSONObject.NULL.equals(null) returns true. - * JSONObject.NULL.toString() returns "null". - */ - public static final Object NULL = new Null(); - - /** - * Construct an empty JSONObject. - */ - public JSONObject() { - this.map = new HashMap<>(); - } - - /** - * Construct a JSONObject from a subset of another JSONObject. An array of - * strings is used to identify the keys that should be copied. Missing keys - * are ignored. - * - * @param jo A JSONObject. - * @param names An array of strings. - * @throws JSONException - * @exception JSONException If a value is a non-finite number or if a name - * is duplicated. - */ - public JSONObject(JSONObject jo, String[] names) { - this(); - for (String name : names) { - try { - this.putOnce(name, jo.opt(name)); - } catch (Exception ignore) {} - } - } - - public JSONObject(String key, Object value) { - this(); - put(key, value); - } - - /** - * Construct a JSONObject from a JSONTokener. - * - * @param x A JSONTokener object containing the source string. - * @throws JSONException If there is a syntax error in the source string or - * a duplicated key. - */ - public JSONObject(JSONTokener x) throws JSONException { - this(); - char c; - String key; - - if (x.nextClean() != '{') { - throw x.syntaxError("A JSONObject text must begin with '{'"); - } - for (;;) { - c = x.nextClean(); - switch (c) { - case 0: - throw x.syntaxError("A JSONObject text must end with '}'"); - case '}': - return; - default: - x.back(); - key = x.nextValue().toString(); - } - - // The key is followed by ':'. We will also tolerate '=' or '=>'. - - c = x.nextClean(); - if (c == '=') { - if (x.next() != '>') { - x.back(); - } - } else if (c != ':') { - throw x.syntaxError("Expected a ':' after a key"); - } - this.putOnce(key, x.nextValue()); - - // Pairs are separated by ','. We will also tolerate ';'. - - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == '}') { - return; - } - x.back(); - break; - case '}': - return; - default: - throw x.syntaxError("Expected a ',' or '}'"); - } - } - } - - /** - * Construct a JSONObject from a Map. - * - * @param map A map object that can be used to initialize the contents of - * the JSONObject. - * @throws JSONException - */ - public JSONObject(Map map) { - this.map = new HashMap<>(); - if (map != null) { - for (Entry e : map.entrySet()) { - Object value = e.getValue(); - if (value != null) { - this.map.put(e.getKey(), wrap(value)); - } - } - } - } - - /** - * Construct a JSONObject from an Object using bean getters. It reflects on - * all of the public methods of the object. For each of the methods with no - * parameters and a name starting with "get" or - * "is" followed by an uppercase letter, the method is invoked, - * and a key and the value returned from the getter method are put into the - * new JSONObject. - * - * The key is formed by removing the "get" or "is" - * prefix. If the second remaining character is not upper case, then the - * first character is converted to lower case. - * - * For example, if an object has a method named "getName", and - * if the result of calling object.getName() is - * "Larry Fine", then the JSONObject will contain - * "name": "Larry Fine". - * - * @param bean An object that has getter methods that should be used to make - * a JSONObject. - */ - public JSONObject(Object bean) { - this(); - this.populateMap(bean); - } - - /** - * Construct a JSONObject from an Object, using reflection to find the - * public members. The resulting JSONObject's keys will be the strings from - * the names array, and the values will be the field values associated with - * those keys in the object. If a key is not found or not visible, then it - * will not be copied into the new JSONObject. - * - * @param object An object that has fields that should be used to make a - * JSONObject. - * @param names An array of strings, the names of the fields to be obtained - * from the object. - */ - public JSONObject(Object object, String[] names) { - this(); - Class c = object.getClass(); - for (String name : names) { - try { - this.putOpt(name, c.getField(name).get(object)); - } catch (Exception ignore) {} - } - } - - /** - * Construct a JSONObject from a source JSON text string. This is the most - * commonly used JSONObject constructor. - * - * @param source A string beginning with { (left - * brace) and ending with }  (right - * brace). - * @exception JSONException If there is a syntax error in the source string - * or a duplicated key. - */ - public JSONObject(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONObject from a ResourceBundle. - * - * @param baseName The ResourceBundle base name. - * @param locale The Locale to load the ResourceBundle for. - * @throws JSONException If any JSONExceptions are detected. - */ - public JSONObject(String baseName, Locale locale) throws JSONException { - this(); - ResourceBundle bundle = ResourceBundle - .getBundle(baseName, locale, Thread.currentThread().getContextClassLoader()); - - // Iterate through the keys in the bundle. - - Enumeration keys = bundle.getKeys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - if (key != null) { - - // Go through the path, ensuring that there is a nested - // JSONObject for each - // segment except the last. Add the value using the last - // segment's name into - // the deepest nested JSONObject. - - String[] path = key.split("\\."); - int last = path.length - 1; - JSONObject target = this; - for (int i = 0; i < last; i += 1) { - String segment = path[i]; - JSONObject nextTarget = target.optJSONObject(segment); - if (nextTarget == null) { - nextTarget = new JSONObject(); - target.put(segment, nextTarget); - } - target = nextTarget; - } - target.put(path[last], bundle.getString(key)); - } - } - } - - /** - * Accumulate values under a key. It is similar to the put method except - * that if there is already an object stored under the key then a JSONArray - * is stored under the key to hold all of the accumulated values. If there - * is already a JSONArray, then the new value is appended to it. In - * contrast, the put method replaces the previous value. - * - * If only one value is accumulated that is not a JSONArray, then the result - * will be the same as using put. But if multiple values are accumulated, - * then the result will be like append. - * - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the value is an invalid number or if the key is - * null. - */ - public JSONObject accumulate(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, value instanceof JSONArray ? new JSONArray().put(value) : value); - } else if (object instanceof JSONArray) { - ((JSONArray) object).put(value); - } else { - this.put(key, new JSONArray().put(object).put(value)); - } - return this; - } - - /** - * Append values to the array under a key. If the key does not exist in the - * JSONObject, then the key is put in the JSONObject with its value being a - * JSONArray containing the value parameter. If the key was already - * associated with a JSONArray, then the value parameter is appended to it. - * - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the key is null or if the current value - * associated with the key is not a JSONArray. - */ - public JSONObject append(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, new JSONArray().put(value)); - } else if (object instanceof JSONArray) { - this.put(key, ((JSONArray) object).put(value)); - } else { - throw new JSONException("JSONObject[" + key + "] is not a JSONArray."); - } - return this; - } - - public Map getMap() { - return map; - } - - /** - * Produce a string from a double. The string "null" will be returned if the - * number is not finite. - * - * @param d A double. - * @return A String. - */ - public static String doubleToString(double d) { - if (Double.isInfinite(d) || Double.isNaN(d)) { - return "null"; - } - - // Shave off trailing zeros and decimal point, if possible. - - String string = Double.toString(d); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - /** - * Get the value object associated with a key. - * - * @param key A key string. - * @return The object associated with the key. - * @throws JSONException if the key is not found. - */ - public Object get(String key) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - Object object = this.opt(key); - if (object == null) { - throw new JSONException("JSONObject[" + quote(key) + "] not found."); - } - return object; - } - - /** - * Get the boolean value associated with a key. - * - * @param key A key string. - * @return The truth. - * @throws JSONException if the value is not a Boolean or the String "true" - * or "false". - */ - public boolean getBoolean(String key) throws JSONException { - Object object = this.get(key); - if ( - object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object).equalsIgnoreCase("false")) - ) { - return false; - } else if ( - object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object).equalsIgnoreCase("true")) - ) { - return true; - } - throw new JSONException("JSONObject[" + quote(key) + "] is not a Boolean."); - } - - /** - * Get the double value associated with a key. - * - * @param key A key string. - * @return The numeric value. - * @throws JSONException if the key is not found or if the value is not a - * Number object and cannot be converted to a number. - */ - public double getDouble(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not a number."); - } - } - - public float getFloat(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).floatValue() - : Float.parseFloat((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not a number."); - } - } - - /** - * Get the int value associated with a key. - * - * @param key A key string. - * @return The integer value. - * @throws JSONException if the key is not found or if the value cannot be - * converted to an integer. - */ - public int getInt(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not an int."); - } - } - - /** - * Get the JSONArray value associated with a key. - * - * @param key A key string. - * @return A JSONArray which is the value. - * @throws JSONException if the key is not found or if the value is not a - * JSONArray. - */ - public JSONArray getJSONArray(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONArray."); - } - - /** - * Get the JSONObject value associated with a key. - * - * @param key A key string. - * @return A JSONObject which is the value. - * @throws JSONException if the key is not found or if the value is not a - * JSONObject. - */ - public JSONObject getJSONObject(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONObject."); - } - - /** - * Get the long value associated with a key. - * - * @param key A key string. - * @return The long value. - * @throws JSONException if the key is not found or if the value cannot be - * converted to a long. - */ - public long getLong(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + "] is not a long."); - } - } - - /** - * Get an array of field names from a JSONObject. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(JSONObject jo) { - int length = jo.length(); - if (length == 0) { - return null; - } - Iterator iterator = jo.keys(); - String[] names = new String[length]; - int i = 0; - while (iterator.hasNext()) { - names[i] = iterator.next(); - i += 1; - } - return names; - } - - /** - * Get an array of field names from an Object. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(Object object) { - if (object == null) { - return null; - } - Class klass = object.getClass(); - Field[] fields = klass.getFields(); - int length = fields.length; - if (length == 0) { - return null; - } - String[] names = new String[length]; - for (int i = 0; i < length; i += 1) { - names[i] = fields[i].getName(); - } - return names; - } - - /** - * Get the string associated with a key. - * - * @param key A key string. - * @return A string which is the value. - * @throws JSONException if there is no string value for the key. - */ - public String getString(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] not a string."); - } - - /** - * Determine if the JSONObject contains a specific key. - * - * @param key A key string. - * @return true if the key exists in the JSONObject. - */ - public boolean has(String key) { - return this.map.containsKey(key); - } - - /** - * Increment a property of a JSONObject. If there is no such property, - * create one with a value of 1. If there is such a property, and if it is - * an Integer, Long, Double, or Float, then add one to it. - * - * @param key A key string. - * @return this. - * @throws JSONException If there is already a property with this name that - * is not an Integer, Long, Double, or Float. - */ - public JSONObject increment(String key) throws JSONException { - Object value = this.opt(key); - if (value == null) { - this.put(key, 1); - } else if (value instanceof Integer) { - this.put(key, (Integer) value + 1); - } else if (value instanceof Long) { - this.put(key, (Long) value + 1); - } else if (value instanceof Double) { - this.put(key, (Double) value + 1); - } else if (value instanceof Float) { - this.put(key, (Float) value + 1); - } else { - throw new JSONException("Unable to increment [" + quote(key) + "]."); - } - return this; - } - - /** - * Determine if the value associated with the key is null or if there is no - * value. - * - * @param key A key string. - * @return true if there is no value associated with the key or if the value - * is the JSONObject.NULL object. - */ - public boolean isNull(String key) { - return JSONObject.NULL.equals(this.opt(key)); - } - - /** - * Get an enumeration of the keys of the JSONObject. - * - * @return An iterator of the keys. - */ - public Iterator keys() { - return this.map.keySet().iterator(); - } - - /** - * Get the number of keys stored in the JSONObject. - * - * @return The number of keys in the JSONObject. - */ - public int length() { - return this.map.size(); - } - - /** - * Produce a JSONArray containing the names of the elements of this - * JSONObject. - * - * @return A JSONArray containing the key strings, or null if the JSONObject - * is empty. - */ - public JSONArray names() { - JSONArray ja = new JSONArray(); - Iterator keys = this.keys(); - while (keys.hasNext()) { - ja.put(keys.next()); - } - return ja.length() == 0 ? null : ja; - } - - /** - * Produce a string from a Number. - * - * @param number A Number - * @return A String. - * @throws JSONException If n is a non-finite number. - */ - public static String numberToString(Number number) throws JSONException { - if (number == null) { - throw new JSONException("Null pointer"); - } - testValidity(number); - - // Shave off trailing zeros and decimal point, if possible. - - String string = number.toString(); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - /** - * Get an optional value associated with a key. - * - * @param key A key string. - * @return An object which is the value, or null if there is no value. - */ - public Object opt(String key) { - return key == null ? null : this.map.get(key); - } - - /** - * Get an optional boolean associated with a key. It returns false if there - * is no such key, or if the value is not Boolean.TRUE or the String "true". - * - * @param key A key string. - * @return The truth. - */ - public boolean optBoolean(String key) { - return this.optBoolean(key, false); - } - - /** - * Get an optional boolean associated with a key. It returns the - * defaultValue if there is no such key, or if it is not a Boolean or the - * String "true" or "false" (case insensitive). - * - * @param key A key string. - * @param defaultValue The default. - * @return The truth. - */ - public boolean optBoolean(String key, boolean defaultValue) { - try { - return this.getBoolean(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional double associated with a key, or NaN if there is no such - * key or if its value is not a number. If the value is a string, an attempt - * will be made to evaluate it as a number. - * - * @param key A string which is the key. - * @return An object which is the value. - */ - public double optDouble(String key) { - return this.optDouble(key, Double.NaN); - } - - public float optFloat(String key) { - return this.optFloat(key, Float.NaN); - } - - /** - * Get an optional double associated with a key, or the defaultValue if - * there is no such key or if its value is not a number. If the value is a - * string, an attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public double optDouble(String key, double defaultValue) { - try { - return this.getDouble(key); - } catch (Exception e) { - return defaultValue; - } - } - - public float optFloat(String key, float defaultValue) { - try { - return this.getFloat(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional int value associated with a key, or zero if there is no - * such key or if the value is not a number. If the value is a string, an - * attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public int optInt(String key) { - return this.optInt(key, 0); - } - - /** - * Get an optional int value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public int optInt(String key, int defaultValue) { - try { - return this.getInt(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional JSONArray associated with a key. It returns null if there - * is no such key, or if its value is not a JSONArray. - * - * @param key A key string. - * @return A JSONArray which is the value. - */ - public JSONArray optJSONArray(String key) { - Object o = this.opt(key); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get an optional JSONObject associated with a key. It returns null if - * there is no such key, or if its value is not a JSONObject. - * - * @param key A key string. - * @return A JSONObject which is the value. - */ - public JSONObject optJSONObject(String key) { - Object object = this.opt(key); - return object instanceof JSONObject ? (JSONObject) object : null; - } - - /** - * Get an optional long value associated with a key, or zero if there is no - * such key or if the value is not a number. If the value is a string, an - * attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public long optLong(String key) { - return this.optLong(key, 0); - } - - /** - * Get an optional long value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public long optLong(String key, long defaultValue) { - try { - return this.getLong(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional string associated with a key. It returns an empty string - * if there is no such key. If the value is not a string and is not null, - * then it is converted to a string. - * - * @param key A key string. - * @return A string which is the value. - */ - public String optString(String key) { - return this.optString(key, ""); - } - - /** - * Get an optional string associated with a key. It returns the defaultValue - * if there is no such key. - * - * @param key A key string. - * @param defaultValue The default. - * @return A string which is the value. - */ - public String optString(String key, String defaultValue) { - Object object = this.opt(key); - return NULL.equals(object) ? defaultValue : object.toString(); - } - - private void populateMap(Object bean) { - Class klass = bean.getClass(); - - // If klass is a System class then set includeSuperClass to false. - - boolean includeSuperClass = klass.getClassLoader() != null; - - Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); - for (Method method : methods) { - try { - if (Modifier.isPublic(method.getModifiers())) { - String name = method.getName(); - String key = ""; - if (name.startsWith("get")) { - if ("getClass".equals(name) || "getDeclaringClass".equals(name)) { - key = ""; - } else { - key = name.substring(3); - } - } else if (name.startsWith("is")) { - key = name.substring(2); - } - if ( - key.length() > 0 - && Character.isUpperCase(key.charAt(0)) - && method.getParameterTypes().length == 0 - ) { - if (key.length() == 1) { - key = key.toLowerCase(); - } else if (!Character.isUpperCase(key.charAt(1))) { - key = key.substring(0, 1).toLowerCase() + key.substring(1); - } - - Object result = method.invoke(bean, (Object[]) null); - if (result != null) { - this.map.put(key, wrap(result)); - } - } - } - } catch (Exception ignore) {} - } - } - - /** - * Put a key/boolean pair in the JSONObject. - * - * @param key A key string. - * @param value A boolean which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, boolean value) { - this.put(key, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONArray which is produced from a Collection. - * - * @param key A key string. - * @param value A Collection value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Collection value) { - this.put(key, new JSONArray(value)); - return this; - } - - /** - * Put a key/double pair in the JSONObject. - * - * @param key A key string. - * @param value A double which is the value. - * @return this. - * @throws JSONException If the key is null or if the number is invalid. - */ - public JSONObject put(String key, double value) { - this.put(key, Double.valueOf(value)); - return this; - } - - /** - * Put a key/int pair in the JSONObject. - * - * @param key A key string. - * @param value An int which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, int value) { - this.put(key, Integer.valueOf(value)); - return this; - } - - /** - * Put a key/long pair in the JSONObject. - * - * @param key A key string. - * @param value A long which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, long value) { - this.put(key, Long.valueOf(value)); - return this; - } - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONObject which is produced from a Map. - * - * @param key A key string. - * @param value A Map value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Map value) { - this.put(key, new JSONObject(value)); - return this; - } - - /** - * Put a key/value pair in the JSONObject. If the value is null, then the - * key will be removed from the JSONObject if it is present. - * - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or - * the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is non-finite number or if the key is - * null. - */ - public JSONObject put(String key, Object value) { - Objects.requireNonNull(key); - if (value != null) { - testValidity(value); - this.map.put(key, value); - } else { - this.remove(key); - } - return this; - } - - /** - * Put a key/value pair in the JSONObject, but only if the key and the value - * are both non-null, and only if there is not already a member with that - * name. - * - * @param key - * @param value - * @return his. - * @throws JSONException if the key is a duplicate - */ - public JSONObject putOnce(String key, Object value) throws JSONException { - if (key != null && value != null) { - if (this.opt(key) != null) { - throw new JSONException("Duplicate key \"" + key + "\""); - } - this.put(key, value); - } - return this; - } - - /** - * Put a key/value pair in the JSONObject, but only if the key and the value - * are both non-null. - * - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or - * the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is a non-finite number. - */ - public JSONObject putOpt(String key, Object value) { - if (key != null && value != null) { - this.put(key, value); - } - return this; - } - - /** - * Produce a string in double quotes with backslash sequences in all the - * right places. A backslash will be inserted within = '\u0080' && c < '\u00a0') - || (c >= '\u2000' && c < '\u2100') - ) { - hhhh = "000" + Integer.toHexString(c); - w.write("\\u" + hhhh.substring(hhhh.length() - 4)); - } else { - w.write(c); - } - } - } - w.write('"'); - return w; - } - - /** - * Remove a name and its value, if present. - * - * @param key The name to be removed. - * @return The value that was associated with the name, or null if there was - * no value. - */ - public Object remove(String key) { - return this.map.remove(key); - } - - /** - * Try to convert a string into a number, boolean, or null. If the string - * can't be converted, return the string. - * - * @param string A String. - * @return A simple JSON value. - */ - public static Object stringToValue(String string) { - double d; - if (string.equals("")) { - return string; - } - if (string.equalsIgnoreCase("true")) { - return Boolean.TRUE; - } - if (string.equalsIgnoreCase("false")) { - return Boolean.FALSE; - } - if (string.equalsIgnoreCase("null")) { - return JSONObject.NULL; - } - - /* - * If it might be a number, try converting it. If a number cannot be - * produced, then the value will just be a string. Note that the plus - * and implied string conventions are non-standard. A JSON parser may - * accept non-JSON forms as long as it accepts all correct JSON forms. - */ - - char b = string.charAt(0); - if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { - try { - if ( - string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1 - ) { - d = Double.parseDouble(string); - if (!Double.isInfinite(d) && !Double.isNaN(d)) { - return d; - } - } else { - long myLong = Long.parseLong(string); - if (myLong == (int) myLong) { - return (int) myLong; - } else { - return myLong; - } - } - } catch (Exception ignore) {} - } - return string; - } - - /** - * Throw an exception if the object is a NaN or infinite number. - * - * @param o The object to test. - * @throws JSONException If o is a non-finite number. - */ - public static void testValidity(Object o) { - if (o != null) { - if (o instanceof Double) { - if (((Double) o).isInfinite() || ((Double) o).isNaN()) { - throw new NumberFormatException("JSON does not allow non-finite numbers."); - } - } else if (o instanceof Float) { - if (((Float) o).isInfinite() || ((Float) o).isNaN()) { - throw new NumberFormatException("JSON does not allow non-finite numbers."); - } - } - } - } - - /** - * Produce a JSONArray containing the values of the members of this - * JSONObject. - * - * @param names A JSONArray containing a list of key strings. This - * determines the sequence of the values in the result. - * @return A JSONArray of values. - * @throws JSONException If any of the values are non-finite numbers. - */ - public JSONArray toJSONArray(JSONArray names) throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (int i = 0; i < names.length(); i += 1) { - ja.put(this.opt(names.getString(i))); - } - return ja; - } - - /** - * Make a JSON text of this JSONObject. For compactness, no whitespace is - * added. If this would not result in a syntactically correct JSON text, - * then null will be returned instead. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - */ - @Override - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Make a prettyprinted JSON text of this JSONObject. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - * @throws JSONException If the object contains an invalid number. - */ - public String toString(int indentFactor) throws JSONException { - StringWriter w = new StringWriter(); - synchronized (w.getBuffer()) { - return this.write(w, indentFactor, 0).toString(); - } - } - - /** - * Make a JSON text of an Object value. If the object has an - * value.toJSONString() method, then that method will be used to produce the - * JSON text. The method is required to produce a strictly conforming text. - * If the object does not contain a toJSONString method (which is the most - * common case), then a text will be produced by other means. If the value - * is an array or Collection, then a JSONArray will be made from it and its - * toJSONString method will be called. If the value is a MAP, then a - * JSONObject will be made from it and its toJSONString method will be - * called. Otherwise, the value's toString method will be called, and the - * result will be quoted. - * - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param value The value to be serialized. - * @return a printable, displayable, transmittable representation of the - * object, beginning with { (left brace) - * and ending with } (right brace). - * @throws JSONException If the value is or contains an invalid number. - */ - @SuppressWarnings("unchecked") - public static String valueToString(Object value) throws JSONException { - if (value == null || value.equals(null)) { - return "null"; - } - if (value instanceof JSONString) { - String object; - try { - object = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - if (object != null) { - return object; - } - throw new JSONException("Bad value from toJSONString: " + object); - } - if (value instanceof Number) { - return numberToString((Number) value); - } - if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) { - return value.toString(); - } - if (value instanceof Map) { - return new JSONObject(value).toString(); - } - if (value instanceof Collection) { - return new JSONArray((Collection) value).toString(); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(); - } - return quote(value.toString()); - } - - /** - * Wrap an object, if necessary. If the object is null, return the NULL - * object. If it is an array or collection, wrap it in a JSONArray. If it is - * a map, wrap it in a JSONObject. If it is a standard property (Double, - * String, et al) then it is already wrapped. Otherwise, if it comes from - * one of the java packages, turn it into a string. And if it doesn't, try - * to wrap it in a JSONObject. If the wrapping fails, then null is returned. - * - * @param object The object to wrap - * @return The wrapped value - */ - @SuppressWarnings("unchecked") - public static Object wrap(Object object) { - try { - if (object == null) { - return NULL; - } - if ( - object instanceof JSONObject - || object instanceof JSONArray - || NULL.equals(object) - || object instanceof JSONString - || object instanceof Byte - || object instanceof Character - || object instanceof Short - || object instanceof Integer - || object instanceof Long - || object instanceof Boolean - || object instanceof Float - || object instanceof Double - || object instanceof String - ) { - return object; - } - - if (object instanceof Collection) { - return new JSONArray((Collection) object); - } - if (object.getClass().isArray()) { - return new JSONArray(object); - } - if (object instanceof Map) { - return new JSONObject(object); - } - Package objectPackage = object.getClass().getPackage(); - String objectPackageName = objectPackage != null ? objectPackage.getName() : ""; - if ( - objectPackageName.startsWith("java.") - || objectPackageName.startsWith("javax.") - || object.getClass().getClassLoader() == null - ) { - return object.toString(); - } - return new JSONObject(object); - } catch (Exception exception) { - return null; - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - public Writer writeWithIdent(Writer writer) throws JSONException { - return this.write(writer, 1, 0); - } - - @SuppressWarnings("unchecked") - static final Writer writeValue(Writer writer, Object value, int indentFactor, int indent) - throws JSONException, IOException { - if (value == null || value.equals(null)) { - writer.write("null"); - } else if (value instanceof JSONObject) { - ((JSONObject) value).write(writer, indentFactor, indent); - } else if (value instanceof JSONArray) { - ((JSONArray) value).write(writer, indentFactor, indent); - } else if (value instanceof Map) { - new JSONObject(value).write(writer, indentFactor, indent); - } else if (value instanceof Collection) { - new JSONArray((Collection) value).write(writer, indentFactor, indent); - } else if (value.getClass().isArray()) { - new JSONArray(value).write(writer, indentFactor, indent); - } else if (value instanceof Number) { - writer.write(numberToString((Number) value)); - } else if (value instanceof Boolean) { - writer.write(value.toString()); - } else if (value instanceof JSONString) { - Object o; - try { - o = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - writer.write(o != null ? o.toString() : quote(value.toString())); - } else { - quote(value.toString(), writer); - } - return writer; - } - - static final void indent(Writer writer, int indent) throws IOException { - for (int i = 0; i < indent; i += 1) { - writer.write('\t'); - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - Writer write(Writer writer, int indentFactor, int indent) throws JSONException { - try { - boolean commanate = false; - final int length = this.length(); - Iterator keys = this.keys(); - writer.write('{'); - - if (length == 1) { - Object key = keys.next(); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - while (keys.hasNext()) { - Object key = keys.next(); - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, newindent); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, indent); - } - writer.write('}'); - return writer; - } catch (IOException exception) { - throw new JSONException(exception); - } - } -} diff --git a/server/src/main/java/org/json/JSONString.java b/server/src/main/java/org/json/JSONString.java deleted file mode 100644 index 33c884a4fd..0000000000 --- a/server/src/main/java/org/json/JSONString.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.json; - -/** - * The JSONString interface allows a toJSONString() - * method so that a class can change the behavior of - * JSONObject.toString(), JSONArray.toString(), and - * JSONWriter.value(Object). The - * toJSONString method will be used instead of the default behavior - * of using the Object's toString() method and quoting the result. - */ -public interface JSONString { - /** - * The toJSONString method allows a class to produce its own - * JSON serialization. - * - * @return A strictly syntactically correct JSON text. - */ - String toJSONString(); -} diff --git a/server/src/main/java/org/json/JSONTokener.java b/server/src/main/java/org/json/JSONTokener.java deleted file mode 100644 index 770833a8c0..0000000000 --- a/server/src/main/java/org/json/JSONTokener.java +++ /dev/null @@ -1,414 +0,0 @@ -package org.json; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - - -/** - * A JSONTokener takes a source string and extracts characters and tokens from - * it. It is used by the JSONObject and JSONArray constructors to parse JSON - * source strings. - * - * @author JSON.org - * @version 2012-02-16 - */ -public class JSONTokener { - - private long character; - private boolean eof; - private long index; - private long line; - private char previous; - private Reader reader; - private boolean usePrevious; - - /** - * Construct a JSONTokener from a Reader. - * - * @param reader A reader. - */ - public JSONTokener(Reader reader) { - this.reader = reader.markSupported() ? reader : new BufferedReader(reader); - this.eof = false; - this.usePrevious = false; - this.previous = 0; - this.index = 0; - this.character = 1; - this.line = 1; - } - - /** - * Construct a JSONTokener from an InputStream. - */ - public JSONTokener(InputStream inputStream) throws JSONException { - this(new InputStreamReader(inputStream)); - } - - /** - * Construct a JSONTokener from a string. - * - * @param s A source string. - */ - public JSONTokener(String s) { - this(new StringReader(s)); - } - - /** - * Back up one character. This provides a sort of lookahead capability, so - * that you can test for a digit or letter before attempting to parse the - * next number or identifier. - */ - public void back() throws JSONException { - if (this.usePrevious || this.index <= 0) { - throw new JSONException("Stepping back two steps is not supported"); - } - this.index -= 1; - this.character -= 1; - this.usePrevious = true; - this.eof = false; - } - - /** - * Get the hex value of a character (base16). - * - * @param c A character between '0' and '9' or between 'A' and 'F' or - * between 'a' and 'f'. - * @return An int between 0 and 15, or -1 if c was not a hex digit. - */ - public static int dehexchar(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } - if (c >= 'A' && c <= 'F') { - return c - ('A' - 10); - } - if (c >= 'a' && c <= 'f') { - return c - ('a' - 10); - } - return -1; - } - - public boolean end() { - return this.eof && !this.usePrevious; - } - - /** - * Determine if the source string still contains characters that next() can - * consume. - * - * @return true if not yet at the end of the source. - */ - public boolean more() throws JSONException { - this.next(); - if (this.end()) { - return false; - } - this.back(); - return true; - } - - /** - * Get the next character in the source string. - * - * @return The next character, or 0 if past the end of the source string. - */ - public char next() throws JSONException { - int c; - if (this.usePrevious) { - this.usePrevious = false; - c = this.previous; - } else { - try { - c = this.reader.read(); - } catch (IOException exception) { - throw new JSONException(exception); - } - - if (c <= 0) { // End of stream - this.eof = true; - c = 0; - } - } - this.index += 1; - if (this.previous == '\r') { - this.line += 1; - this.character = c == '\n' ? 0 : 1; - } else if (c == '\n') { - this.line += 1; - this.character = 0; - } else { - this.character += 1; - } - this.previous = (char) c; - return this.previous; - } - - /** - * Consume the next character, and check that it matches a specified - * character. - * - * @param c The character to match. - * @return The character. - * @throws JSONException if the character does not match. - */ - public char next(char c) throws JSONException { - char n = this.next(); - if (n != c) { - throw this.syntaxError("Expected '" + c + "' and instead saw '" + n + "'"); - } - return n; - } - - /** - * Get the next n characters. - * - * @param n The number of characters to take. - * @return A string of n characters. - * @throws JSONException Substring bounds error if there are not n - * characters remaining in the source string. - */ - public String next(int n) throws JSONException { - if (n == 0) { - return ""; - } - - char[] chars = new char[n]; - int pos = 0; - - while (pos < n) { - chars[pos] = this.next(); - if (this.end()) { - throw this.syntaxError("Substring bounds error"); - } - pos += 1; - } - return new String(chars); - } - - /** - * Get the next char in the string, skipping whitespace. - * - * @throws JSONException - * @return A character, or 0 if there are no more characters. - */ - public char nextClean() throws JSONException { - for (;;) { - char c = this.next(); - if (c == 0 || c > ' ') { - return c; - } - } - } - - /** - * Return the characters up to the next close quote character. Backslash - * processing is done. The formal JSON format does not allow strings in - * single quotes, but an implementation is allowed to accept them. - * - * @param quote The quoting character, either " - *  (double quote) or ' - *  (single quote). - * @return A String. - * @throws JSONException Unterminated string. - */ - public String nextString(char quote) throws JSONException { - char c; - StringBuilder sb = new StringBuilder(); - for (;;) { - c = this.next(); - switch (c) { - case 0, '\n', '\r' -> throw this.syntaxError("Unterminated string"); - case '\\' -> { - c = this.next(); - switch (c) { - case 'b' -> sb.append('\b'); - case 't' -> sb.append('\t'); - case 'n' -> sb.append('\n'); - case 'f' -> sb.append('\f'); - case 'r' -> sb.append('\r'); - case 'u' -> sb.append((char) Integer.parseInt(this.next(4), 16)); - case '"', '\'', '\\', '/' -> sb.append(c); - default -> throw this.syntaxError("Illegal escape."); - } - } - default -> { - if (c == quote) { - return sb.toString(); - } - sb.append(c); - } - } - } - } - - /** - * Get the text up but not including the specified character or the end of - * line, whichever comes first. - * - * @param delimiter A delimiter character. - * @return A string. - */ - public String nextTo(char delimiter) throws JSONException { - StringBuilder sb = new StringBuilder(); - for (;;) { - char c = this.next(); - if (c == delimiter || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - /** - * Get the text up but not including one of the specified delimiter - * characters or the end of line, whichever comes first. - * - * @param delimiters A set of delimiter characters. - * @return A string, trimmed. - */ - public String nextTo(String delimiters) throws JSONException { - char c; - StringBuilder sb = new StringBuilder(); - for (;;) { - c = this.next(); - if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - /** - * Get the next value. The value can be a Boolean, Double, Integer, - * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. - * - * @throws JSONException If syntax error. - * - * @return An object. - */ - public Object nextValue() throws JSONException { - char c = this.nextClean(); - String string; - - switch (c) { - case '"': - case '\'': - return this.nextString(c); - case '{': - this.back(); - return new JSONObject(this); - case '[': - this.back(); - return new JSONArray(this); - } - - /* - * Handle unquoted text. This could be the values true, false, or null, - * or it can be a number. An implementation (such as this one) is - * allowed to also accept non-standard forms. - * - * Accumulate characters until we reach the end of the text or a - * formatting character. - */ - - StringBuilder sb = new StringBuilder(); - while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { - sb.append(c); - c = this.next(); - } - this.back(); - - string = sb.toString().trim(); - if ("".equals(string)) { - throw this.syntaxError("Missing value"); - } - return JSONObject.stringToValue(string); - } - - /** - * Skip characters until the next character is the requested character. If - * the requested character is not found, no characters are skipped. - * - * @param to A character to skip to. - * @return The requested character, or zero if the requested character is - * not found. - */ - public char skipTo(char to) throws JSONException { - char c; - try { - long startIndex = this.index; - long startCharacter = this.character; - long startLine = this.line; - this.reader.mark(1000000); - do { - c = this.next(); - if (c == 0) { - this.reader.reset(); - this.index = startIndex; - this.character = startCharacter; - this.line = startLine; - return c; - } - } while (c != to); - } catch (IOException exc) { - throw new JSONException(exc); - } - - this.back(); - return c; - } - - /** - * Make a JSONException to signal a syntax error. - * - * @param message The error message. - * @return A JSONException object, suitable for throwing - */ - public JSONException syntaxError(String message) { - return new JSONException(message + this); - } - - /** - * Make a printable string of this JSONTokener. - * - * @return " at {index} [character {character} line {line}]" - */ - @Override - public String toString() { - return " at " + this.index + " [character " + this.character + " line " + this.line + "]"; - } -} diff --git a/server/src/main/java/org/json/JSONUtil.java b/server/src/main/java/org/json/JSONUtil.java deleted file mode 100644 index f7e629a31e..0000000000 --- a/server/src/main/java/org/json/JSONUtil.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.json; - -import java.util.Map.Entry; - - -public class JSONUtil { - - public static JSONObject toJSON(JSONEntry... entries) { - return o(entries); - } - - public static JSONObject o(JSONEntry... entries) { - JSONObject object = new JSONObject(); - for (JSONEntry e : entries) { - object.put(e.getKey(), e.getValue()); - } - return object; - } - - public static JSONArray a(Object... values) { - return new JSONArray(values); - } - - public static JSONEntry e(String k, Object v) { - return new JSONEntry(k, v); - } - - public static class JSONEntry implements Entry { - - private String key; - private Object value; - - public JSONEntry(String key, Object value) { - this.key = key; - this.value = value; - } - - @Override - public String getKey() { - return this.key; - } - - @Override - public Object getValue() { - return this.value; - } - - @Override - public Object setValue(Object value) { - Object oldValue = this.value; - this.value = value; - return oldValue; - } - - } -} From 1624ed3282d66011a2302ce457bec1b9c4469834 Mon Sep 17 00:00:00 2001 From: Eiren Rain Date: Tue, 22 Nov 2022 15:34:14 +0100 Subject: [PATCH 2/5] Update solarxr-protocol --- solarxr-protocol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solarxr-protocol b/solarxr-protocol index 682a7976f3..f7d697c3cf 160000 --- a/solarxr-protocol +++ b/solarxr-protocol @@ -1 +1 @@ -Subproject commit 682a7976f3761309f3e55992bec8b4b0db0afaf0 +Subproject commit f7d697c3cfe29acb827e19a25ca5e9c22399c992 From 32a3a010cf297bca4b5a13ad8877033e47465e01 Mon Sep 17 00:00:00 2001 From: Eiren Rain Date: Tue, 22 Nov 2022 15:50:21 +0100 Subject: [PATCH 3/5] Fix keybindings class --- server/src/main/java/dev/slimevr/Keybinding.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/dev/slimevr/Keybinding.java b/server/src/main/java/dev/slimevr/Keybinding.java index b30c5bb3fd..b1c7e95f14 100644 --- a/server/src/main/java/dev/slimevr/Keybinding.java +++ b/server/src/main/java/dev/slimevr/Keybinding.java @@ -1,4 +1,4 @@ -package dev.slimevr.gui; +package dev.slimevr; import com.melloware.jintellitype.HotkeyListener; import com.melloware.jintellitype.JIntellitype; From b959ac56af802e7d1150387a015948357198a951 Mon Sep 17 00:00:00 2001 From: Eiren Rain Date: Tue, 22 Nov 2022 16:01:49 +0100 Subject: [PATCH 4/5] Post-merge fixes --- server/src/main/java/dev/slimevr/Keybinding.java | 1 - server/src/main/java/dev/slimevr/Main.java | 1 - settings.gradle | 1 - 3 files changed, 3 deletions(-) diff --git a/server/src/main/java/dev/slimevr/Keybinding.java b/server/src/main/java/dev/slimevr/Keybinding.java index b1c7e95f14..fefcc203db 100644 --- a/server/src/main/java/dev/slimevr/Keybinding.java +++ b/server/src/main/java/dev/slimevr/Keybinding.java @@ -2,7 +2,6 @@ import com.melloware.jintellitype.HotkeyListener; import com.melloware.jintellitype.JIntellitype; -import dev.slimevr.VRServer; import dev.slimevr.config.KeybindingsConfig; import io.eiren.util.OperatingSystem; import io.eiren.util.ann.AWTThread; diff --git a/server/src/main/java/dev/slimevr/Main.java b/server/src/main/java/dev/slimevr/Main.java index c10b6e0256..8dd39758c0 100644 --- a/server/src/main/java/dev/slimevr/Main.java +++ b/server/src/main/java/dev/slimevr/Main.java @@ -1,6 +1,5 @@ package dev.slimevr; -import dev.slimevr.Keybinding; import io.eiren.util.logging.LogManager; import org.apache.commons.cli.*; import org.apache.commons.lang3.JavaVersion; diff --git a/settings.gradle b/settings.gradle index 88c2b1852b..f13b8a32f1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,7 +8,6 @@ */ rootProject.name = 'SlimeVR Server' -include ':slime-java-commons' include ':solarxr-protocol' From 584f3b6afe1c419e9a6f25e4f269627233a25d71 Mon Sep 17 00:00:00 2001 From: Eiren Rain Date: Tue, 22 Nov 2022 18:06:07 +0300 Subject: [PATCH 5/5] Fix line endings. Thanks github.dev! --- .../src/main/java/dev/slimevr/Keybinding.java | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/server/src/main/java/dev/slimevr/Keybinding.java b/server/src/main/java/dev/slimevr/Keybinding.java index fefcc203db..5a3f62d3d6 100644 --- a/server/src/main/java/dev/slimevr/Keybinding.java +++ b/server/src/main/java/dev/slimevr/Keybinding.java @@ -1,74 +1,74 @@ -package dev.slimevr; - -import com.melloware.jintellitype.HotkeyListener; -import com.melloware.jintellitype.JIntellitype; -import dev.slimevr.config.KeybindingsConfig; -import io.eiren.util.OperatingSystem; -import io.eiren.util.ann.AWTThread; -import io.eiren.util.logging.LogManager; - - -public class Keybinding implements HotkeyListener { - private static final int RESET = 1; - private static final int QUICK_RESET = 2; - private static final int RESET_MOUNTING = 3; - public final VRServer server; - public final KeybindingsConfig config; - - @AWTThread - public Keybinding(VRServer server) { - this.server = server; - - this.config = server.getConfigManager().getVrConfig().getKeybindings(); - - if (OperatingSystem.getCurrentPlatform() != OperatingSystem.WINDOWS) { - LogManager - .info( - "[Keybinding] Currently only supported on Windows. Keybindings will be disabled." - ); - return; - } - - try { - if (JIntellitype.getInstance() instanceof JIntellitype) { - JIntellitype.getInstance().addHotKeyListener(this); - - String resetBinding = this.config.getResetBinding(); - JIntellitype.getInstance().registerHotKey(RESET, resetBinding); - LogManager.info("[Keybinding] Bound reset to " + resetBinding); - - String quickResetBinding = this.config.getQuickResetBinding(); - JIntellitype.getInstance().registerHotKey(QUICK_RESET, quickResetBinding); - LogManager.info("[Keybinding] Bound quick reset to " + quickResetBinding); - - String resetMountingBinding = this.config.getResetMountingBinding(); - JIntellitype.getInstance().registerHotKey(RESET_MOUNTING, resetMountingBinding); - LogManager.info("[Keybinding] Bound reset mounting to " + resetMountingBinding); - } - } catch (Throwable e) { - LogManager - .warning( - "[Keybinding] JIntellitype initialization failed. Keybindings will be disabled. Try restarting your computer." - ); - } - } - - @AWTThread - @Override - public void onHotKey(int identifier) { - switch (identifier) { - case RESET -> { - LogManager.info("[Keybinding] Reset pressed"); - server.scheduleResetTrackers(this.config.getResetDelay()); - } - case QUICK_RESET -> { - LogManager.info("[Keybinding] Quick reset pressed"); - server.scheduleResetTrackersYaw(this.config.getQuickResetDelay()); - } - case RESET_MOUNTING -> { - LogManager.info("[Keybinding] Reset mounting pressed"); - server.scheduleResetTrackersMounting(this.config.getResetMountingDelay()); - } - } - } -} +package dev.slimevr; + +import com.melloware.jintellitype.HotkeyListener; +import com.melloware.jintellitype.JIntellitype; +import dev.slimevr.config.KeybindingsConfig; +import io.eiren.util.OperatingSystem; +import io.eiren.util.ann.AWTThread; +import io.eiren.util.logging.LogManager; + + +public class Keybinding implements HotkeyListener { + private static final int RESET = 1; + private static final int QUICK_RESET = 2; + private static final int RESET_MOUNTING = 3; + public final VRServer server; + public final KeybindingsConfig config; + + @AWTThread + public Keybinding(VRServer server) { + this.server = server; + + this.config = server.getConfigManager().getVrConfig().getKeybindings(); + + if (OperatingSystem.getCurrentPlatform() != OperatingSystem.WINDOWS) { + LogManager + .info( + "[Keybinding] Currently only supported on Windows. Keybindings will be disabled." + ); + return; + } + + try { + if (JIntellitype.getInstance() instanceof JIntellitype) { + JIntellitype.getInstance().addHotKeyListener(this); + + String resetBinding = this.config.getResetBinding(); + JIntellitype.getInstance().registerHotKey(RESET, resetBinding); + LogManager.info("[Keybinding] Bound reset to " + resetBinding); + + String quickResetBinding = this.config.getQuickResetBinding(); + JIntellitype.getInstance().registerHotKey(QUICK_RESET, quickResetBinding); + LogManager.info("[Keybinding] Bound quick reset to " + quickResetBinding); + + String resetMountingBinding = this.config.getResetMountingBinding(); + JIntellitype.getInstance().registerHotKey(RESET_MOUNTING, resetMountingBinding); + LogManager.info("[Keybinding] Bound reset mounting to " + resetMountingBinding); + } + } catch (Throwable e) { + LogManager + .warning( + "[Keybinding] JIntellitype initialization failed. Keybindings will be disabled. Try restarting your computer." + ); + } + } + + @AWTThread + @Override + public void onHotKey(int identifier) { + switch (identifier) { + case RESET -> { + LogManager.info("[Keybinding] Reset pressed"); + server.scheduleResetTrackers(this.config.getResetDelay()); + } + case QUICK_RESET -> { + LogManager.info("[Keybinding] Quick reset pressed"); + server.scheduleResetTrackersYaw(this.config.getQuickResetDelay()); + } + case RESET_MOUNTING -> { + LogManager.info("[Keybinding] Reset mounting pressed"); + server.scheduleResetTrackersMounting(this.config.getResetMountingDelay()); + } + } + } +}