Merge remote-tracking branch 'origin/master' into in-pass-shadows
This commit is contained in:
commit
6fb2d029d2
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
**/.classpath
|
||||
**/.settings
|
||||
**/.project
|
||||
**/out
|
||||
/.gradle/
|
||||
/.nb-gradle/
|
||||
/.idea/
|
||||
|
||||
@ -55,5 +55,5 @@ We generally abide by the standard Java Code Conventions. Besides that, just mak
|
||||
|
||||
## Documentation
|
||||
|
||||
- How to edit the wiki - WIP
|
||||
- How to edit the [wiki](https://github.com/jMonkeyEngine/wiki).
|
||||
- How to edit JavaDocs - WIP
|
||||
|
||||
@ -3,7 +3,7 @@ jMonkeyEngine
|
||||
|
||||
[](https://travis-ci.org/jMonkeyEngine/jmonkeyengine)
|
||||
|
||||
jMonkeyEngine is a 3D game engine for adventurous Java developers. It’s open-source, cross-platform, and cutting-edge. 3.1.0 is the latest stable version of the jMonkeyEngine 3 SDK, a complete game development suite. We'll release 3.1.x updates until the major 3.2 release arrives.
|
||||
jMonkeyEngine is a 3D game engine for adventurous Java developers. It’s open-source, cross-platform, and cutting-edge. 3.2.0 is the latest stable version of the jMonkeyEngine 3 SDK, a complete game development suite. We'll release 3.2.x updates until the major 3.3 release arrives.
|
||||
|
||||
The engine is used by several commercial game studios and computer-science courses. Here's a taste:
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ apply from: file('version.gradle')
|
||||
subprojects {
|
||||
if(!project.name.equals('jme3-android-examples')) {
|
||||
apply from: rootProject.file('common.gradle')
|
||||
if (!['jme3-testdata', 'sdk'].contains(project.name)) {
|
||||
if (!project.name.equals('jme3-testdata')) {
|
||||
apply from: rootProject.file('bintray.gradle')
|
||||
}
|
||||
} else {
|
||||
@ -116,7 +116,7 @@ task mergedSource(type: Copy){
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper, description: 'Creates and deploys the Gradle wrapper to the current directory.') {
|
||||
gradleVersion = '3.2.1'
|
||||
gradleVersion = '4.1'
|
||||
}
|
||||
|
||||
ext {
|
||||
|
||||
@ -16,6 +16,9 @@ repositories {
|
||||
maven {
|
||||
url "http://nifty-gui.sourceforge.net/nifty-maven-repo"
|
||||
}
|
||||
flatDir {
|
||||
dirs rootProject.file('lib')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Version number used for plugins, only 3 numbers (e.g. 3.1.3)
|
||||
jmeVersion = 3.2.0
|
||||
jmeVersion = 3.3.0
|
||||
# Version used for application and settings folder, no spaces!
|
||||
jmeMainVersion = 3.2
|
||||
jmeMainVersion = 3.3
|
||||
# Version addition pre-alpha-svn, Stable, Beta
|
||||
jmeVersionTag = SNAPSHOT
|
||||
# Increment this each time jmeVersionTag changes but jmeVersion stays the same
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Fri Nov 25 13:05:50 EST 2016
|
||||
#Sun Sep 17 22:55:30 EDT 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
|
||||
|
||||
22
gradlew
vendored
22
gradlew
vendored
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@ -154,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save ( ) {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
6
gradlew.bat
vendored
6
gradlew.bat
vendored
@ -49,7 +49,6 @@ goto fail
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@ -60,11 +59,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
@ -214,7 +214,7 @@ public class MainActivity extends AppCompatActivity implements OnItemClickListen
|
||||
|
||||
/**
|
||||
* User clicked a view on the screen. Check for the OK and Cancel buttons
|
||||
* and either start the applicaiton or exit.
|
||||
* and either start the application or exit.
|
||||
* @param view
|
||||
*/
|
||||
public void onClick(View view) {
|
||||
|
||||
@ -5,5 +5,5 @@ if (!hasProperty('mainClass')) {
|
||||
dependencies {
|
||||
compile project(':jme3-core')
|
||||
compile project(':jme3-plugins')
|
||||
compile files('../lib/android.jar')
|
||||
compileOnly 'android:android'
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -59,7 +59,7 @@ import java.util.logging.Logger;
|
||||
/**
|
||||
* AndroidSensorJoyInput converts the Android Sensor system into Joystick events.
|
||||
* A single joystick is configured and includes data for all configured sensors
|
||||
* as seperate axes of the joystick.
|
||||
* as separate axes of the joystick.
|
||||
*
|
||||
* Each axis is named according to the static strings in SensorJoystickAxis.
|
||||
* Refer to the strings defined in SensorJoystickAxis for a list of supported
|
||||
@ -285,8 +285,8 @@ public class AndroidSensorJoyInput implements SensorEventListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the device orientation based off the data recieved from the
|
||||
* Acceleration Sensor and Mangetic Field sensor
|
||||
* Calculates the device orientation based off the data received from the
|
||||
* Acceleration Sensor and Magnetic Field sensor
|
||||
* Values are returned relative to the Earth.
|
||||
*
|
||||
* From the Android Doc
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -136,7 +136,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
||||
// stops at the setFormat call without a crash.
|
||||
// We look at the user setting for alpha bits and set the surfaceview
|
||||
// PixelFormat to either Opaque, Transparent, or Translucent.
|
||||
// ConfigChooser will do it's best to honor the alpha requested by the user
|
||||
// ConfigChooser will do its best to honor the alpha requested by the user
|
||||
// For best rendering performance, use Opaque (alpha bits = 0).
|
||||
int curAlphaBits = settings.getAlphaBits();
|
||||
logger.log(Level.FINE, "curAlphaBits: {0}", curAlphaBits);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,7 +69,7 @@ public class BlenderKey extends ModelKey {
|
||||
*/
|
||||
protected String usedWorld;
|
||||
/**
|
||||
* User's default material that is set fo objects that have no material definition in blender. The default value is
|
||||
* User's default material that is set for objects that have no material definition in blender. The default value is
|
||||
* null. If the value is null the importer will use its own default material (gray color - like in blender).
|
||||
*/
|
||||
protected Material defaultMaterial;
|
||||
@ -476,9 +476,9 @@ public class BlenderKey extends ModelKey {
|
||||
}
|
||||
|
||||
/**
|
||||
* This mehtod sets the name of the WORLD data block taht should be used during file loading. By default the name is
|
||||
* This method sets the name of the WORLD data block that should be used during file loading. By default the name is
|
||||
* not set. If no name is set or the given name does not occur in the file - the first WORLD data block will be used
|
||||
* during loading (assumin any exists in the file).
|
||||
* during loading (assuming any exists in the file).
|
||||
* @param usedWorld
|
||||
* the name of the WORLD block used during loading
|
||||
*/
|
||||
@ -487,7 +487,7 @@ public class BlenderKey extends ModelKey {
|
||||
}
|
||||
|
||||
/**
|
||||
* This mehtod returns the name of the WORLD data block taht should be used during file loading.
|
||||
* This method returns the name of the WORLD data block that should be used during file loading.
|
||||
* @return the name of the WORLD block used during loading
|
||||
*/
|
||||
public String getUsedWorld() {
|
||||
|
||||
@ -237,7 +237,7 @@ public class SimulationNode {
|
||||
}
|
||||
}
|
||||
|
||||
// ... add virtual tracks if neccessary, for bones that were altered but had no tracks before ...
|
||||
// ... add virtual tracks if necessary, for bones that were altered but had no tracks before ...
|
||||
for (Long boneOMA : alteredOmas) {
|
||||
BoneContext boneContext = blenderContext.getBoneContext(boneOMA);
|
||||
int boneIndex = skeleton.getBoneIndex(boneContext.getBone());
|
||||
|
||||
@ -37,7 +37,7 @@ import com.jme3.util.BufferUtils;
|
||||
|
||||
/**
|
||||
* A temporal mesh for curves and surfaces. It works in similar way as TemporalMesh for meshes.
|
||||
* It prepares all neccessary lines and faces and allows to apply modifiers just like in regular temporal mesh.
|
||||
* It prepares all necessary lines and faces and allows to apply modifiers just like in regular temporal mesh.
|
||||
*
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
@ -210,7 +210,7 @@ public class CurvesTemporalMesh extends TemporalMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* The method computes the value of a point at the certain relational distance from its beggining.
|
||||
* The method computes the value of a point at the certain relational distance from its beginning.
|
||||
* @param alongRatio
|
||||
* the relative distance along the curve; should be a value between 0 and 1 inclusive;
|
||||
* if the value exceeds the boundaries it is truncated to them
|
||||
@ -369,7 +369,7 @@ public class CurvesTemporalMesh extends TemporalMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* The method loads the bevel object that sould be applied to curve. It can either be another curve or a generated one
|
||||
* The method loads the bevel object that should be applied to curve. It can either be another curve or a generated one
|
||||
* based on the bevel generating parameters in blender.
|
||||
* @param curveStructure
|
||||
* the structure with the curve's data (the curve being loaded, NOT the bevel curve)
|
||||
@ -707,7 +707,7 @@ public class CurvesTemporalMesh extends TemporalMesh {
|
||||
|
||||
/**
|
||||
* the method applies scale for the given bevel points. The points table is
|
||||
* being modified so expect ypur result there.
|
||||
* being modified so expect your result there.
|
||||
*
|
||||
* @param points
|
||||
* the bevel points
|
||||
@ -726,7 +726,7 @@ public class CurvesTemporalMesh extends TemporalMesh {
|
||||
|
||||
/**
|
||||
* A helper class that represents a single bezier line. It consists of Edge's and allows to
|
||||
* get a subline of a lentgh of the line.
|
||||
* get a subline of a length of the line.
|
||||
*
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
@ -776,7 +776,7 @@ public class CurvesTemporalMesh extends TemporalMesh {
|
||||
}
|
||||
if (cyclic) {
|
||||
// if the first vertex is repeated at the end the distance will be = 0 so it won't affect the result, and if it is not repeated
|
||||
// then it is neccessary to add the length between the last and the first vertex
|
||||
// then it is necessary to add the length between the last and the first vertex
|
||||
length += vertices[vertices.length - 1].distance(vertices[0]);
|
||||
}
|
||||
}
|
||||
@ -834,7 +834,7 @@ public class CurvesTemporalMesh extends TemporalMesh {
|
||||
}
|
||||
|
||||
/**
|
||||
* The method computes the value of a point at the certain relational distance from its beggining.
|
||||
* The method computes the value of a point at the certain relational distance from its beginning.
|
||||
* @param alongRatio
|
||||
* the relative distance along the curve; should be a value between 0 and 1 inclusive;
|
||||
* if the value exceeds the boundaries it is truncated to them
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -85,7 +85,7 @@ public class DnaBlockData {
|
||||
names[i] = inputStream.readString();
|
||||
}
|
||||
|
||||
// reding types
|
||||
// reading types
|
||||
inputStream.alignPosition(4);
|
||||
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||
if (identifier != TYPE_ID) {
|
||||
@ -181,7 +181,7 @@ public class DnaBlockData {
|
||||
/**
|
||||
* This method converts the given identifier code to string.
|
||||
* @param code
|
||||
* the code taht is to be converted
|
||||
* the code that is to be converted
|
||||
* @return the string value of the identifier
|
||||
*/
|
||||
private String toString(int code) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -32,7 +32,7 @@
|
||||
package com.jme3.scene.plugins.blender.file;
|
||||
|
||||
/**
|
||||
* An array that can be dynamically modified/
|
||||
* An array that can be dynamically modified
|
||||
* @author Marcin Roguski
|
||||
* @param <T>
|
||||
* the type of stored data in the array
|
||||
@ -42,7 +42,7 @@ public class DynamicArray<T> implements Cloneable {
|
||||
/** An array object that holds the required data. */
|
||||
private T[] array;
|
||||
/**
|
||||
* This table holds the sizes of dimetions of the dynamic table. It's length specifies the table dimension or a
|
||||
* This table holds the sizes of dimensions of the dynamic table. Its length specifies the table dimension or a
|
||||
* pointer level. For example: if tableSizes.length == 3 then it either specifies a dynamic table of fixed lengths:
|
||||
* dynTable[a][b][c], where a,b,c are stored in the tableSizes table.
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -169,7 +169,7 @@ public class Structure implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This methos should be used on structures that are of a 'ListBase' type. It creates a List of structures that are
|
||||
* This method should be used on structures that are of a 'ListBase' type. It creates a List of structures that are
|
||||
* held by this structure within the blend file.
|
||||
* @return a list of filled structures
|
||||
* @throws BlenderFileException
|
||||
@ -232,7 +232,7 @@ public class Structure implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the address of the structure. The strucutre should be filled with data otherwise an exception
|
||||
* This method returns the address of the structure. The structure should be filled with data otherwise an exception
|
||||
* is thrown.
|
||||
* @return the address of the feature stored in this structure
|
||||
*/
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.jme3.scene.plugins.blender.materials;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -106,7 +107,7 @@ public final class MaterialContext implements Savable {
|
||||
boolean transparent = false;
|
||||
if (diffuseColor != null) {
|
||||
transparent = diffuseColor.a < 1.0f;
|
||||
if (loadedTextures.size() > 0) {// texutre covers the material color
|
||||
if (loadedTextures.size() > 0) {// texture covers the material color
|
||||
diffuseColor.set(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
@ -164,6 +165,12 @@ public final class MaterialContext implements Savable {
|
||||
material.setColor("Ambient", new ColorRGBA(ambientFactor, ambientFactor, ambientFactor, 1f));
|
||||
}
|
||||
|
||||
// initializing unused "user-defined UV coords" to all available
|
||||
Map<String, List<Vector2f>> unusedUserDefinedUVCoords = Collections.emptyMap();
|
||||
if(userDefinedUVCoordinates != null && !userDefinedUVCoordinates.isEmpty()) {
|
||||
unusedUserDefinedUVCoords = new HashMap<>(userDefinedUVCoordinates);
|
||||
}
|
||||
|
||||
// applying textures
|
||||
int textureIndex = 0;
|
||||
if (loadedTextures != null && loadedTextures.size() > 0) {
|
||||
@ -175,6 +182,8 @@ public final class MaterialContext implements Savable {
|
||||
String usedUserUVSet = combinedTexture.flatten(geometry, geometriesOMA, userDefinedUVCoordinates, blenderContext);
|
||||
|
||||
this.setTexture(material, combinedTexture.getMappingType(), combinedTexture.getResultTexture());
|
||||
|
||||
if(usedUserUVSet == null || unusedUserDefinedUVCoords.containsKey(usedUserUVSet)) {
|
||||
List<Vector2f> uvs = combinedTexture.getResultUVS();
|
||||
if(uvs != null && uvs.size() > 0) {
|
||||
VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]);
|
||||
@ -182,9 +191,10 @@ public final class MaterialContext implements Savable {
|
||||
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
||||
}//uvs might be null if the user assigned non existing UV coordinates group name to the mesh (this should be fixed in blender file)
|
||||
|
||||
// Remove used "user-defined UV coords" from the unused collection
|
||||
if(usedUserUVSet != null) {
|
||||
userDefinedUVCoordinates = new HashMap<>(userDefinedUVCoordinates);
|
||||
userDefinedUVCoordinates.remove(usedUserUVSet);
|
||||
unusedUserDefinedUVCoords.remove(usedUserUVSet);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "The texture could not be applied because JME only supports up to {0} different UV's.", TextureHelper.TEXCOORD_TYPES.length);
|
||||
@ -192,12 +202,12 @@ public final class MaterialContext implements Savable {
|
||||
}
|
||||
}
|
||||
|
||||
if (userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
||||
if (unusedUserDefinedUVCoords != null && unusedUserDefinedUVCoords.size() > 0) {
|
||||
LOGGER.fine("Storing unused, user defined UV coordinates sets.");
|
||||
if (userDefinedUVCoordinates.size() > TextureHelper.TEXCOORD_TYPES.length) {
|
||||
if (unusedUserDefinedUVCoords.size() > TextureHelper.TEXCOORD_TYPES.length) {
|
||||
LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different UV coordinates for the mesh. JME supports only {0} UV coordinates buffers.", TextureHelper.TEXCOORD_TYPES.length);
|
||||
}
|
||||
for (Entry<String, List<Vector2f>> entry : userDefinedUVCoordinates.entrySet()) {
|
||||
for (Entry<String, List<Vector2f>> entry : unusedUserDefinedUVCoords.entrySet()) {
|
||||
if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) {
|
||||
List<Vector2f> uvs = entry.getValue();
|
||||
VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -324,7 +324,7 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
* 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.
|
||||
* @return result, after receiving the cross product vector.
|
||||
*/
|
||||
public Vector3d cross(Vector3d v, Vector3d result) {
|
||||
return this.cross(v.x, v.y, v.z, result);
|
||||
@ -342,7 +342,7 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
* 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.
|
||||
* @return result, after receiving the cross product vector.
|
||||
*/
|
||||
public Vector3d cross(double otherX, double otherY, double otherZ, Vector3d result) {
|
||||
if (result == null) {
|
||||
@ -485,12 +485,12 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>multLocal</code> multiplies a provided vector to this vector
|
||||
* <code>multLocal</code> multiplies a provided vector by 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.
|
||||
* the vector to multiply by this vector.
|
||||
* @return this
|
||||
*/
|
||||
public Vector3d multLocal(Vector3d vec) {
|
||||
@ -522,7 +522,7 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>multLocal</code> multiplies a provided vector to this vector
|
||||
* <code>multLocal</code> multiplies a provided vector by this vector
|
||||
* internally, and returns a handle to this vector for easy chaining of
|
||||
* calls. If the provided vector is null, null is returned.
|
||||
*
|
||||
@ -539,7 +539,7 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>multLocal</code> multiplies a provided vector to this vector
|
||||
* <code>multLocal</code> multiplies a provided vector by this vector
|
||||
* internally, and returns a handle to this vector for easy chaining of
|
||||
* calls. If the provided vector is null, null is returned.
|
||||
*
|
||||
@ -657,7 +657,7 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>subtractLocal</code> subtracts a provided vector to this vector
|
||||
* <code>subtractLocal</code> subtracts a provided vector from this vector
|
||||
* internally, and returns a handle to this vector for easy chaining of
|
||||
* calls. If the provided vector is null, null is returned.
|
||||
*
|
||||
@ -825,7 +825,7 @@ public final class Vector3d implements Savable, Cloneable, Serializable {
|
||||
|
||||
/**
|
||||
* <code>hashCode</code> returns a unique code for this vector object based
|
||||
* on it's values. If two vectors are logically equivalent, they will return
|
||||
* on its values. If two vectors are logically equivalent, they will return
|
||||
* the same hash code value.
|
||||
* @return the hash code value of this vector.
|
||||
*/
|
||||
|
||||
@ -291,6 +291,8 @@ public class MeshHelper extends AbstractBlenderHelper {
|
||||
Structure defbase = (Structure) parent.getFieldValue("defbase");
|
||||
List<String> groupNames = new ArrayList<String>();
|
||||
List<Structure> defs = defbase.evaluateListBase();
|
||||
|
||||
if(!defs.isEmpty()) {
|
||||
for (Structure def : defs) {
|
||||
groupNames.add(def.getFieldValue("name").toString());
|
||||
}
|
||||
@ -315,6 +317,7 @@ public class MeshHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ public class SubdivisionSurfaceModifier extends Modifier {
|
||||
private Set<Integer> verticesOnOriginalEdges = new HashSet<Integer>();
|
||||
|
||||
/**
|
||||
* Constructor loads all neccessary modifier data.
|
||||
* Constructor loads all necessary modifier data.
|
||||
* @param modifierStructure
|
||||
* the modifier structure
|
||||
* @param blenderContext
|
||||
@ -193,7 +193,7 @@ public class SubdivisionSurfaceModifier extends Modifier {
|
||||
// moving the vertex
|
||||
v.addLocal(t);
|
||||
|
||||
// applying crease weight if neccessary
|
||||
// applying crease weight if necessary
|
||||
CreasePoint creasePoint = creasePoints.get(i);
|
||||
if (creasePoint.getTarget() != null && creasePoint.getWeight() != 0) {
|
||||
t = creasePoint.getTarget().subtractLocal(v).multLocal(creasePoint.getWeight());
|
||||
|
||||
@ -31,12 +31,14 @@
|
||||
*/
|
||||
package com.jme3.scene.plugins.blender.textures;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.asset.TextureKey;
|
||||
import com.jme3.scene.plugins.blender.file.BlenderInputStream;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.plugins.AWTLoader;
|
||||
import com.jme3.texture.plugins.DDSLoader;
|
||||
import com.jme3.texture.plugins.TGALoader;
|
||||
import java.io.InputStream;
|
||||
import com.jme3.texture.plugins.HDRLoader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
@ -47,11 +49,29 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
/* package */class ImageLoader extends AWTLoader {
|
||||
private static final Logger LOGGER = Logger.getLogger(ImageLoader.class.getName());
|
||||
|
||||
protected DDSLoader ddsLoader = new DDSLoader(); // DirectX image loader
|
||||
private static final Logger hdrLogger = Logger.getLogger(HDRLoader.class.getName()); // Used to silence HDR Errors
|
||||
|
||||
/**
|
||||
* This method loads the image from the blender file itself. It tries each loader to load the image.
|
||||
* List of Blender-Supported Texture Extensions (we have to guess them, so
|
||||
* the AssetLoader can find them. Not good, but better than nothing.
|
||||
* Source: https://docs.blender.org/manual/en/dev/data_system/files/media/image_formats.html
|
||||
*/
|
||||
private static final String[] extensions = new String[]
|
||||
{ /* Windows Bitmap */".bmp",
|
||||
/* Iris */ ".sgi", ".rgb", ".bw",
|
||||
/* PNG */ ".png",
|
||||
/* JPEG */ ".jpg", ".jpeg",
|
||||
/* JPEG 2000 */ ".jp2", ".j2c",
|
||||
/* Targa */".tga",
|
||||
/* Cineon & DPX */".cin", ".dpx",
|
||||
/* OpenEXR */ ".exr",
|
||||
/* Radiance HDR */ ".hdr",
|
||||
/* TIFF */ ".tif", ".tiff",
|
||||
/* DDS (Direct X) */ ".dds" };
|
||||
|
||||
/**
|
||||
* This method loads a image which is packed into the blender file.
|
||||
* It makes use of all the registered AssetLoaders
|
||||
*
|
||||
* @param inputStream
|
||||
* blender input stream
|
||||
@ -60,76 +80,57 @@ import java.util.logging.Logger;
|
||||
* @param flipY
|
||||
* if the image should be flipped (does not work with DirectX image)
|
||||
* @return loaded image or null if it could not be loaded
|
||||
* @deprecated This method has only been left in for API compability.
|
||||
* Use loadTexture instead
|
||||
*/
|
||||
public Image loadImage(BlenderInputStream inputStream, int startPosition, boolean flipY) {
|
||||
// loading using AWT loader
|
||||
inputStream.setPosition(startPosition);
|
||||
Image result = this.loadImage(inputStream, ImageType.AWT, flipY);
|
||||
// loading using TGA loader
|
||||
if (result == null) {
|
||||
inputStream.setPosition(startPosition);
|
||||
result = this.loadImage(inputStream, ImageType.TGA, flipY);
|
||||
}
|
||||
// loading using DDS loader
|
||||
if (result == null) {
|
||||
inputStream.setPosition(startPosition);
|
||||
result = this.loadImage(inputStream, ImageType.DDS, flipY);
|
||||
}
|
||||
public Image loadImage(AssetManager assetManager, BlenderInputStream inputStream, int startPosition, boolean flipY) {
|
||||
Texture tex = loadTexture(assetManager, inputStream, startPosition, flipY);
|
||||
|
||||
if (result == null) {
|
||||
LOGGER.warning("Image could not be loaded by none of available loaders!");
|
||||
if (tex == null) {
|
||||
return null;
|
||||
} else {
|
||||
return tex.getImage();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method loads an image of a specified type from the given input stream.
|
||||
* This method loads a texture which is packed into the blender file.
|
||||
* It makes use of all the registered AssetLoaders
|
||||
*
|
||||
* @param inputStream
|
||||
* the input stream we read the image from
|
||||
* @param imageType
|
||||
* the type of the image {@link ImageType}
|
||||
* blender input stream
|
||||
* @param startPosition
|
||||
* position in the stream where the image data starts
|
||||
* @param flipY
|
||||
* if the image should be flipped (does not work with DirectX image)
|
||||
* @return loaded image or null if it could not be loaded
|
||||
* @return loaded texture or null if it could not be loaded
|
||||
*/
|
||||
public Image loadImage(InputStream inputStream, ImageType imageType, boolean flipY) {
|
||||
Image result = null;
|
||||
switch (imageType) {
|
||||
case AWT:
|
||||
public Texture loadTexture(AssetManager assetManager, BlenderInputStream inputStream, int startPosition, boolean flipY) {
|
||||
inputStream.setPosition(startPosition);
|
||||
TextureKey tKey;
|
||||
Texture result = null;
|
||||
|
||||
hdrLogger.setLevel(Level.SEVERE); // When we bruteforce try HDR on a non hdr file, it prints unreadable chars
|
||||
|
||||
for (String ext: extensions) {
|
||||
tKey = new TextureKey("dummy" + ext, flipY);
|
||||
try {
|
||||
result = this.load(inputStream, flipY);
|
||||
result = assetManager.loadAssetFromStream(tKey, inputStream);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warning("Unable to load image using AWT loader!");
|
||||
}
|
||||
break;
|
||||
case DDS:
|
||||
try {
|
||||
result = ddsLoader.load(inputStream);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warning("Unable to load image using DDS loader!");
|
||||
}
|
||||
break;
|
||||
case TGA:
|
||||
try {
|
||||
result = TGALoader.load(inputStream, flipY);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warning("Unable to load image using TGA loader!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown image type: " + imageType);
|
||||
}
|
||||
return result;
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image types that can be loaded. AWT: png, jpg, jped or bmp TGA: tga DDS: DirectX image files
|
||||
*
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
private static enum ImageType {
|
||||
AWT, TGA, DDS;
|
||||
if (result != null) {
|
||||
break; // Could locate a possible asset
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
LOGGER.warning("Texture could not be loaded by any of the available loaders!\n"
|
||||
+ "Since the file has been packed into the blender file, there is no"
|
||||
+ "way for us to tell you which texture it was.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ public final class ImageUtils {
|
||||
N.z = 1;
|
||||
N.divideLocal(den);
|
||||
|
||||
// setting thge pixel in the result image
|
||||
// setting the pixel in the result image
|
||||
bumpMap.setRGB(x, y, ImageUtils.vectorToColor(N.x, N.y, N.z));
|
||||
}
|
||||
}
|
||||
@ -422,7 +422,7 @@ public final class ImageUtils {
|
||||
* pixel's X coordinate
|
||||
* @param y
|
||||
* pixel's Y coordinate
|
||||
* @return height reprezented by the given texture in the specified location
|
||||
* @return height represented by the given texture in the specified location
|
||||
*/
|
||||
private static int getHeight(BufferedImage image, int x, int y) {
|
||||
if (x < 0) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -72,6 +72,7 @@ import com.jme3.texture.Texture.WrapMode;
|
||||
import com.jme3.texture.Texture2D;
|
||||
import com.jme3.texture.image.ColorSpace;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.PlaceholderAssets;
|
||||
|
||||
/**
|
||||
* A class that is used in texture calculations.
|
||||
@ -251,7 +252,11 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
blenderContext.getInputStream().setPosition(dataFileBlock.getBlockPosition());
|
||||
|
||||
// Should the texture be flipped? It works for sinbad ..
|
||||
result = new Texture2D(new ImageLoader().loadImage(blenderContext.getInputStream(), dataFileBlock.getBlockPosition(), true));
|
||||
result = new ImageLoader().loadTexture(blenderContext.getAssetManager(), blenderContext.getInputStream(), dataFileBlock.getBlockPosition(), true);
|
||||
if (result == null) {
|
||||
result = new Texture2D(PlaceholderAssets.getPlaceholderImage(blenderContext.getAssetManager()));
|
||||
LOGGER.fine("ImageLoader returned null. It probably failed to load the packed texture, using placeholder asset");
|
||||
}
|
||||
}
|
||||
}
|
||||
//} else {
|
||||
@ -310,7 +315,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
* @param pos
|
||||
* the relative position (value of range <0, 1> (both inclusive))
|
||||
* @param size
|
||||
* the size of the line the pixel lies on (width, heigth or
|
||||
* the size of the line the pixel lies on (width, height or
|
||||
* depth)
|
||||
* @return the integer index of the pixel on the line of the specified width
|
||||
*/
|
||||
@ -429,10 +434,10 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method loads the textre from outside the blend file using the
|
||||
* This method loads the texture from outside the blend file using the
|
||||
* AssetManager that the blend file was loaded with. It returns a texture
|
||||
* with a full assetKey that references the original texture so it later
|
||||
* doesn't need to ba packed when the model data is serialized. It searches
|
||||
* doesn't need to be packed when the model data is serialized. It searches
|
||||
* the AssetManager for the full path if the model file is a relative path
|
||||
* and will attempt to truncate the path if it is an absolute file path
|
||||
* until the path can be found in the AssetManager. If the texture can not
|
||||
@ -614,8 +619,15 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
|
||||
boolean negateTexture = (texflag & 0x04) != 0;
|
||||
|
||||
boolean colorSet = false;
|
||||
for (int i = 0; i < mappings.length; ++i) {
|
||||
if ((mappings[i] & mapto.intValue()) != 0) {
|
||||
if(mappings[i] == MaterialContext.MTEX_COL) {
|
||||
colorSet = true;
|
||||
} else if(colorSet && mappings[i] == MaterialContext.MTEX_ALPHA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CombinedTexture combinedTexture = new CombinedTexture(mappings[i], !skyTexture);
|
||||
int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
|
||||
float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() };
|
||||
@ -646,8 +658,16 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
Map<Number, List<TextureData>> result = new HashMap<Number, List<TextureData>>();
|
||||
for (TextureData data : textures) {
|
||||
Number mapto = (Number) data.mtex.getFieldValue("mapto");
|
||||
|
||||
boolean colorSet = false;
|
||||
for (int i = 0; i < mappings.length; ++i) {
|
||||
if ((mappings[i] & mapto.intValue()) != 0) {
|
||||
if(mappings[i] == MaterialContext.MTEX_COL) {
|
||||
colorSet = true;
|
||||
} else if(colorSet && mappings[i] == MaterialContext.MTEX_ALPHA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<TextureData> datas = result.get(mappings[i]);
|
||||
if (datas == null) {
|
||||
datas = new ArrayList<TextureData>();
|
||||
|
||||
@ -163,8 +163,18 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
|
||||
* the blender context
|
||||
*/
|
||||
protected void blendPixel(float[] result, float[] materialColor, float[] pixelColor, BlenderContext blenderContext) {
|
||||
// We calculate first the importance of the texture (colFactor * texAlphaValue)
|
||||
float blendFactor = this.blendFactor * pixelColor[3];
|
||||
float oneMinusFactor = 1.0f - blendFactor, col;
|
||||
// Then, we get the object material factor ((1 - texture importance) * matAlphaValue)
|
||||
float oneMinusFactor = (1f - blendFactor) * materialColor[3];
|
||||
// Finally, we can get the final blendFactor, which is 1 - the material factor.
|
||||
blendFactor = 1f - oneMinusFactor;
|
||||
|
||||
// --- Compact method ---
|
||||
// float blendFactor = this.blendFactor * (1f - ((1f - pixelColor[3]) * materialColor[3]));
|
||||
// float oneMinusFactor = 1f - blendFactor;
|
||||
|
||||
float col;
|
||||
|
||||
switch (blendType) {
|
||||
case MTEX_BLEND:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -40,7 +40,7 @@ public interface PhysicsCollisionGroupListener {
|
||||
/**
|
||||
* Called when two physics objects of the registered group are about to collide, <i>called from physics thread</i>.<br>
|
||||
* This is only called when the collision will happen based on the collisionGroup and collideWithGroups
|
||||
* settings in the PhysicsCollisionObject. That is the case when <b>one</b> of the partys has the
|
||||
* settings in the PhysicsCollisionObject. That is the case when <b>one</b> of the parties has the
|
||||
* collisionGroup of the other in its collideWithGroups set.<br>
|
||||
* @param nodeA CollisionObject #1
|
||||
* @param nodeB CollisionObject #2
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,6 +41,7 @@ import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
@ -163,6 +164,12 @@ public abstract class AbstractPhysicsControl implements PhysicsControl, JmeClone
|
||||
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloneFields( Cloner cloner, Object original ) {
|
||||
this.spatial = cloner.clone(spatial);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -48,9 +48,7 @@ import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@ -665,13 +663,6 @@ public class BetterCharacterControl extends AbstractPhysicsControl implements Ph
|
||||
rigidBody.setUserObject(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
BetterCharacterControl control = new BetterCharacterControl(radius, height, mass);
|
||||
control.setJumpForce(jumpForce);
|
||||
return control;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
BetterCharacterControl control = new BetterCharacterControl(radius, height, mass);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -89,21 +89,10 @@ public class CharacterControl extends PhysicsCharacter implements PhysicsControl
|
||||
return spatial.getWorldTranslation();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
CharacterControl control = new CharacterControl(collisionShape, stepHeight);
|
||||
control.setCcdMotionThreshold(getCcdMotionThreshold());
|
||||
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
|
||||
control.setCollideWithGroups(getCollideWithGroups());
|
||||
control.setCollisionGroup(getCollisionGroup());
|
||||
control.setFallSpeed(getFallSpeed());
|
||||
control.setGravity(getGravity());
|
||||
control.setJumpSpeed(getJumpSpeed());
|
||||
control.setMaxSlope(getMaxSlope());
|
||||
control.setPhysicsLocation(getPhysicsLocation());
|
||||
control.setUpAxis(getUpAxis());
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
return control;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -95,17 +95,10 @@ public class GhostControl extends PhysicsGhostObject implements PhysicsControl,
|
||||
return spatial.getWorldRotation();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
GhostControl control = new GhostControl(collisionShape);
|
||||
control.setCcdMotionThreshold(getCcdMotionThreshold());
|
||||
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
|
||||
control.setCollideWithGroups(getCollideWithGroups());
|
||||
control.setCollisionGroup(getCollisionGroup());
|
||||
control.setPhysicsLocation(getPhysicsLocation());
|
||||
control.setPhysicsRotation(getPhysicsRotationMatrix());
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
return control;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -59,9 +59,7 @@ import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
@ -73,7 +71,7 @@ import java.util.logging.Logger;
|
||||
* use this control you need a model with an AnimControl and a
|
||||
* SkeletonControl.<br> This should be the case if you imported an animated
|
||||
* model from Ogre or blender.<br> Note enabling/disabling the control
|
||||
* add/removes it from the physic space<br> <p> This control creates collision
|
||||
* add/removes it from the physics space<br> <p> This control creates collision
|
||||
* shapes for each bones of the skeleton when you call
|
||||
* spatial.addControl(ragdollControl). <ul> <li>The shape is HullCollision shape
|
||||
* based on the vertices associated with each bone and based on a tweakable
|
||||
@ -84,11 +82,11 @@ import java.util.logging.Logger;
|
||||
* </ul> </p> <p> There are 2 modes for this control : <ul> <li><strong>The
|
||||
* kinematic modes :</strong><br> this is the default behavior, this means that
|
||||
* the collision shapes of the body are able to interact with physics enabled
|
||||
* objects. in this mode physic shapes follow the moovements of the animated
|
||||
* objects. in this mode physics shapes follow the motion of the animated
|
||||
* skeleton (for example animated by a key framed animation) this mode is
|
||||
* enabled by calling setKinematicMode(); </li> <li><strong>The ragdoll modes
|
||||
* :</strong><br> To enable this behavior, you need to call setRagdollMode()
|
||||
* method. In this mode the charater is entirely controled by physics, so it
|
||||
* method. In this mode the character is entirely controlled by physics, so it
|
||||
* will fall under the gravity and move if any force is applied to it. </li>
|
||||
* </ul> </p>
|
||||
*
|
||||
@ -171,7 +169,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
}
|
||||
|
||||
/**
|
||||
* contruct a KinematicRagdollControl
|
||||
* construct a KinematicRagdollControl
|
||||
*/
|
||||
public KinematicRagdollControl() {
|
||||
baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(0.1f)), 1);
|
||||
@ -201,7 +199,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
if(mode == Mode.IK){
|
||||
ikUpdate(tpf);
|
||||
} else if (mode == mode.Ragdoll && targetModel.getLocalTranslation().equals(modelPosition)) {
|
||||
//if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space.
|
||||
//if the ragdoll has the control of the skeleton, we update each bone with its position in physics world space.
|
||||
ragDollUpdate(tpf);
|
||||
} else {
|
||||
kinematicUpdate(tpf);
|
||||
@ -217,12 +215,12 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
|
||||
Vector3f position = vars.vect1;
|
||||
|
||||
//retrieving bone position in physic world space
|
||||
//retrieving bone position in physics world space
|
||||
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
||||
//transforming this position with inverse transforms of the model
|
||||
targetModel.getWorldTransform().transformInverseVector(p, position);
|
||||
|
||||
//retrieving bone rotation in physic world space
|
||||
//retrieving bone rotation in physics world space
|
||||
Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();
|
||||
|
||||
//multiplying this rotation by the initialWorld rotation of the bone,
|
||||
@ -255,7 +253,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
link.bone.setUserTransformsInModelSpace(position, tmpRot1);
|
||||
} else {
|
||||
//boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape.
|
||||
//So we update them recusively
|
||||
//So we update them recursively
|
||||
RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
|
||||
}
|
||||
}
|
||||
@ -264,7 +262,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
}
|
||||
|
||||
protected void kinematicUpdate(float tpf) {
|
||||
//the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
|
||||
//the ragdoll does not have control, so the keyframed animation updates the physics position of the physics bonces
|
||||
TempVars vars = TempVars.get();
|
||||
Quaternion tmpRot1 = vars.quat1;
|
||||
Quaternion tmpRot2 = vars.quat2;
|
||||
@ -420,7 +418,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
targetModel.getWorldRotation().mult(tmpRot1, tmpRot1);
|
||||
tmpRot1.normalizeLocal();
|
||||
|
||||
//updating physic location/rotation of the physic bone
|
||||
//updating physics location/rotation of the physics bone
|
||||
link.rigidBody.setPhysicsLocation(position);
|
||||
link.rigidBody.setPhysicsRotation(tmpRot1);
|
||||
|
||||
@ -707,9 +705,9 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
|
||||
/**
|
||||
* Enable or disable the ragdoll behaviour. if ragdollEnabled is true, the
|
||||
* character motion will only be powerd by physics else, the characted will
|
||||
* character motion will only be powered by physics else, the character will
|
||||
* be animated by the keyframe animation, but will be able to physically
|
||||
* interact with its physic environnement
|
||||
* interact with its physics environment
|
||||
*
|
||||
* @param ragdollEnabled
|
||||
*/
|
||||
@ -789,9 +787,9 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the control into Kinematic mode In theis mode, the collision shapes
|
||||
* Set the control into Kinematic mode In this mode, the collision shapes
|
||||
* follow the movements of the skeleton, and can interact with physical
|
||||
* environement
|
||||
* environment
|
||||
*/
|
||||
public void setKinematicMode() {
|
||||
if (mode != Mode.Kinematic) {
|
||||
@ -820,7 +818,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
}
|
||||
|
||||
/**
|
||||
* retruns the mode of this control
|
||||
* returns the mode of this control
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@ -903,7 +901,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use only specific render for the ragdoll(if debugging)
|
||||
* For internal use only specific render for the ragdoll (if debugging)
|
||||
*
|
||||
* @param rm
|
||||
* @param vp
|
||||
@ -912,16 +910,6 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
|
||||
public void render(RenderManager rm, ViewPort vp) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
KinematicRagdollControl control = new KinematicRagdollControl(preset, weightThreshold);
|
||||
control.setMode(mode);
|
||||
control.setRootMass(rootMass);
|
||||
control.setWeightThreshold(weightThreshold);
|
||||
control.setApplyPhysicsLocal(applyLocal);
|
||||
return control;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
KinematicRagdollControl control = new KinematicRagdollControl(preset, weightThreshold);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -53,7 +53,6 @@ import com.jme3.scene.shape.Box;
|
||||
import com.jme3.scene.shape.Sphere;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -92,31 +91,10 @@ public class RigidBodyControl extends PhysicsRigidBody implements PhysicsControl
|
||||
super(shape, mass);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
RigidBodyControl control = new RigidBodyControl(collisionShape, mass);
|
||||
control.setAngularFactor(getAngularFactor());
|
||||
control.setAngularSleepingThreshold(getAngularSleepingThreshold());
|
||||
control.setCcdMotionThreshold(getCcdMotionThreshold());
|
||||
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
|
||||
control.setCollideWithGroups(getCollideWithGroups());
|
||||
control.setCollisionGroup(getCollisionGroup());
|
||||
control.setDamping(getLinearDamping(), getAngularDamping());
|
||||
control.setFriction(getFriction());
|
||||
control.setGravity(getGravity());
|
||||
control.setKinematic(isKinematic());
|
||||
control.setKinematicSpatial(isKinematicSpatial());
|
||||
control.setLinearSleepingThreshold(getLinearSleepingThreshold());
|
||||
control.setPhysicsLocation(getPhysicsLocation(null));
|
||||
control.setPhysicsRotation(getPhysicsRotationMatrix(null));
|
||||
control.setRestitution(getRestitution());
|
||||
|
||||
if (mass > 0) {
|
||||
control.setAngularVelocity(getAngularVelocity());
|
||||
control.setLinearVelocity(getLinearVelocity());
|
||||
}
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
return control;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -43,7 +43,6 @@ import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
@ -108,54 +107,10 @@ public class VehicleControl extends PhysicsVehicle implements PhysicsControl, Jm
|
||||
return spatial.getWorldRotation();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
VehicleControl control = new VehicleControl(collisionShape, mass);
|
||||
control.setAngularFactor(getAngularFactor());
|
||||
control.setAngularSleepingThreshold(getAngularSleepingThreshold());
|
||||
control.setAngularVelocity(getAngularVelocity());
|
||||
control.setCcdMotionThreshold(getCcdMotionThreshold());
|
||||
control.setCcdSweptSphereRadius(getCcdSweptSphereRadius());
|
||||
control.setCollideWithGroups(getCollideWithGroups());
|
||||
control.setCollisionGroup(getCollisionGroup());
|
||||
control.setDamping(getLinearDamping(), getAngularDamping());
|
||||
control.setFriction(getFriction());
|
||||
control.setGravity(getGravity());
|
||||
control.setKinematic(isKinematic());
|
||||
control.setLinearSleepingThreshold(getLinearSleepingThreshold());
|
||||
control.setLinearVelocity(getLinearVelocity());
|
||||
control.setPhysicsLocation(getPhysicsLocation());
|
||||
control.setPhysicsRotation(getPhysicsRotationMatrix());
|
||||
control.setRestitution(getRestitution());
|
||||
|
||||
control.setFrictionSlip(getFrictionSlip());
|
||||
control.setMaxSuspensionTravelCm(getMaxSuspensionTravelCm());
|
||||
control.setSuspensionStiffness(getSuspensionStiffness());
|
||||
control.setSuspensionCompression(tuning.suspensionCompression);
|
||||
control.setSuspensionDamping(tuning.suspensionDamping);
|
||||
control.setMaxSuspensionForce(getMaxSuspensionForce());
|
||||
|
||||
for (Iterator<VehicleWheel> it = wheels.iterator(); it.hasNext();) {
|
||||
VehicleWheel wheel = it.next();
|
||||
VehicleWheel newWheel = control.addWheel(wheel.getLocation(), wheel.getDirection(), wheel.getAxle(), wheel.getRestLength(), wheel.getRadius(), wheel.isFrontWheel());
|
||||
newWheel.setFrictionSlip(wheel.getFrictionSlip());
|
||||
newWheel.setMaxSuspensionTravelCm(wheel.getMaxSuspensionTravelCm());
|
||||
newWheel.setSuspensionStiffness(wheel.getSuspensionStiffness());
|
||||
newWheel.setWheelsDampingCompression(wheel.getWheelsDampingCompression());
|
||||
newWheel.setWheelsDampingRelaxation(wheel.getWheelsDampingRelaxation());
|
||||
newWheel.setMaxSuspensionForce(wheel.getMaxSuspensionForce());
|
||||
|
||||
//TODO: bad way finding children!
|
||||
if (spatial instanceof Node) {
|
||||
Node node = (Node) spatial;
|
||||
Spatial wheelSpat = node.getChild(wheel.getWheelSpatial().getName());
|
||||
if (wheelSpat != null) {
|
||||
newWheel.setWheelSpatial(wheelSpat);
|
||||
}
|
||||
}
|
||||
}
|
||||
control.setApplyPhysicsLocal(isApplyPhysicsLocal());
|
||||
return control;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -123,7 +123,7 @@ public class RagdollUtils {
|
||||
|
||||
/**
|
||||
* Create a hull collision shape from linked vertices to this bone.
|
||||
* Vertices have to be previoulsly gathered in a map using buildPointMap method
|
||||
* Vertices have to be previously gathered in a map using buildPointMap method
|
||||
*
|
||||
* @param pointsMap
|
||||
* @param boneIndices
|
||||
@ -160,7 +160,7 @@ public class RagdollUtils {
|
||||
return new HullCollisionShape(p);
|
||||
}
|
||||
|
||||
//retruns the list of bone indices of the given bone and its child(if they are not in the boneList)
|
||||
//returns the list of bone indices of the given bone and its child (if they are not in the boneList)
|
||||
public static List<Integer> getBoneIndices(Bone bone, Skeleton skeleton, Set<String> boneList) {
|
||||
List<Integer> list = new LinkedList<Integer>();
|
||||
if (boneList.isEmpty()) {
|
||||
@ -266,7 +266,7 @@ public class RagdollUtils {
|
||||
|
||||
/**
|
||||
* Updates a bone position and rotation.
|
||||
* if the child bones are not in the bone list this means, they are not associated with a physic shape.
|
||||
* if the child bones are not in the bone list this means, they are not associated with a physics shape.
|
||||
* So they have to be updated
|
||||
* @param bone the bone
|
||||
* @param pos the position
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -235,7 +235,7 @@ public class PhysicsSpace {
|
||||
// collides = (bp1.collisionFilterGroup & bp.collisionFilterMask) != 0;
|
||||
// }
|
||||
// if (collides) {
|
||||
// assert (bp.clientObject instanceof com.bulletphysics.collision.dispatch.CollisionObject && bp.clientObject instanceof com.bulletphysics.collision.dispatch.CollisionObject);
|
||||
// assert (bp.clientObject instanceof com.bulletphysics.collision.dispatch.CollisionObject && bp1.clientObject instanceof com.bulletphysics.collision.dispatch.CollisionObject);
|
||||
// com.bulletphysics.collision.dispatch.CollisionObject colOb = (com.bulletphysics.collision.dispatch.CollisionObject) bp.clientObject;
|
||||
// com.bulletphysics.collision.dispatch.CollisionObject colOb1 = (com.bulletphysics.collision.dispatch.CollisionObject) bp1.clientObject;
|
||||
// assert (colOb.getUserPointer() != null && colOb1.getUserPointer() != null);
|
||||
@ -954,7 +954,7 @@ public class PhysicsSpace {
|
||||
* determinism in physics. For example a maximum number of 2 can compensate
|
||||
* for framerates as low as 30fps when the physics has the default accuracy
|
||||
* of 60 fps. Note that setting this value too high can make the physics
|
||||
* drive down its own fps in case its overloaded.
|
||||
* drive down its own fps in case it's overloaded.
|
||||
*
|
||||
* @param steps The maximum number of extra steps, default is 4.
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -96,7 +96,7 @@ public abstract class PhysicsCollisionObject implements Savable {
|
||||
* Sets the collision group number for this physics object. <br>
|
||||
* The groups are integer bit masks and some pre-made variables are available in CollisionObject.
|
||||
* All physics objects are by default in COLLISION_GROUP_01.<br>
|
||||
* Two object will collide when <b>one</b> of the partys has the
|
||||
* Two object will collide when <b>one</b> of the parties has the
|
||||
* collisionGroup of the other in its collideWithGroups set.
|
||||
* @param collisionGroup the collisionGroup to set
|
||||
*/
|
||||
@ -109,7 +109,7 @@ public abstract class PhysicsCollisionObject implements Savable {
|
||||
|
||||
/**
|
||||
* Add a group that this object will collide with.<br>
|
||||
* Two object will collide when <b>one</b> of the partys has the
|
||||
* Two object will collide when <b>one</b> of the parties has the
|
||||
* collisionGroup of the other in its collideWithGroups set.<br>
|
||||
* @param collisionGroup
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -44,7 +44,7 @@ import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* <i>From bullet manual:</i><br>
|
||||
* To create ragdolls, the conve twist constraint is very useful for limbs like the upper arm.
|
||||
* To create ragdolls, the cone twist constraint is very useful for limbs like the upper arm.
|
||||
* It is a special point to point constraint that adds cone and twist axis limits.
|
||||
* The x-axis serves as twist axis.
|
||||
* @author normenhansen
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -121,7 +121,7 @@ public class HingeJoint extends PhysicsJoint {
|
||||
* @param high the high limit in radians.
|
||||
* @param _softness the factor at which the velocity error correction starts operating,i.e a softness of 0.9 means that the vel. corr starts at 90% of the limit range.
|
||||
* @param _biasFactor the magnitude of the position correction. It tells you how strictly the position error (drift ) is corrected.
|
||||
* @param _relaxationFactor the rate at which velocity errors are corrected. This can be seen as the strength of the limits. A low value will make the the limits more spongy.
|
||||
* @param _relaxationFactor the rate at which velocity errors are corrected. This can be seen as the strength of the limits. A low value will make the limits more spongy.
|
||||
*/
|
||||
public void setLimit(float low, float high, float _softness, float _biasFactor, float _relaxationFactor) {
|
||||
biasFactor = _biasFactor;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -265,7 +265,7 @@ public class PhysicsRigidBody extends PhysicsCollisionObject {
|
||||
// }
|
||||
/**
|
||||
* Sets the node to kinematic mode. in this mode the node is not affected by physics
|
||||
* but affects other physics objects. Iits kinetic force is calculated by the amount
|
||||
* but affects other physics objects. Its kinetic force is calculated by the amount
|
||||
* of movement it is exposed to and its weight.
|
||||
* @param kinematic
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -283,8 +283,8 @@ public class PhysicsVehicle extends PhysicsRigidBody {
|
||||
}
|
||||
|
||||
/**
|
||||
* This vaue caps the maximum suspension force, raise this above the default 6000 if your suspension cannot
|
||||
* handle the weight of your vehcile.
|
||||
* This value caps the maximum suspension force, raise this above the default 6000 if your suspension cannot
|
||||
* handle the weight of your vehicle.
|
||||
* @param maxSuspensionForce
|
||||
*/
|
||||
public void setMaxSuspensionForce(float maxSuspensionForce) {
|
||||
@ -292,8 +292,8 @@ public class PhysicsVehicle extends PhysicsRigidBody {
|
||||
}
|
||||
|
||||
/**
|
||||
* This vaue caps the maximum suspension force, raise this above the default 6000 if your suspension cannot
|
||||
* handle the weight of your vehcile.
|
||||
* This value caps the maximum suspension force, raise this above the default 6000 if your suspension cannot
|
||||
* handle the weight of your vehicle.
|
||||
* @param wheel
|
||||
* @param maxSuspensionForce
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -242,7 +242,7 @@ public class VehicleWheel implements Savable {
|
||||
|
||||
/**
|
||||
* The maximum suspension force, raise this above the default 6000 if your suspension cannot
|
||||
* handle the weight of your vehcile.
|
||||
* handle the weight of your vehicle.
|
||||
* @param maxSuspensionTravelCm
|
||||
*/
|
||||
public void setMaxSuspensionForce(float maxSuspensionForce) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2017 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,6 +35,7 @@ import com.jme3.bullet.collision.shapes.CollisionShape;
|
||||
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
|
||||
import com.jme3.bullet.collision.shapes.infos.ChildCollisionShape;
|
||||
import com.jme3.math.Matrix3f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Mesh;
|
||||
import com.jme3.scene.Node;
|
||||
@ -111,9 +112,16 @@ public class DebugShapeFactory {
|
||||
|
||||
public static Mesh getDebugMesh(CollisionShape shape) {
|
||||
Mesh mesh = new Mesh();
|
||||
mesh = new Mesh();
|
||||
DebugMeshCallback callback = new DebugMeshCallback();
|
||||
/*
|
||||
* Populate the mesh based on an unscaled shape;
|
||||
* the shape's scale will be applied later, to the geometry.
|
||||
*/
|
||||
Vector3f savedScale = shape.getScale().clone();
|
||||
shape.setScale(Vector3f.UNIT_XYZ);
|
||||
getVertices(shape.getObjectId(), callback);
|
||||
shape.setScale(savedScale);
|
||||
|
||||
mesh.setBuffer(Type.Position, 3, callback.getVertices());
|
||||
mesh.getFloatBuffer(Type.Position).clear();
|
||||
return mesh;
|
||||
|
||||
@ -15,7 +15,7 @@ import java.lang.annotation.Target;
|
||||
* annotations of the same name at a single location.
|
||||
*
|
||||
* Example:
|
||||
* <!-- is a hack that prevents @ from being the first charater on the line, which confuses Javadoc -->
|
||||
* <!-- is a hack that prevents @ from being the first character on the line, which confuses Javadoc -->
|
||||
* <code><pre>
|
||||
* @DefaultQualifiers({
|
||||
* @DefaultQualifier("NonNull"),
|
||||
|
||||
@ -68,7 +68,11 @@ public final class AnimChannel {
|
||||
private float blendAmount = 1f;
|
||||
private float blendRate = 0;
|
||||
|
||||
AnimChannel(AnimControl control){
|
||||
public AnimChannel(){
|
||||
|
||||
}
|
||||
|
||||
public AnimChannel(AnimControl control){
|
||||
this.control = control;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -34,19 +34,16 @@ package com.jme3.animation;
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Mesh;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.AbstractControl;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import com.jme3.util.TempVars;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* <code>AnimControl</code> is a Spatial control that allows manipulation
|
||||
@ -108,32 +105,6 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
|
||||
public AnimControl() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only.
|
||||
*/
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
try {
|
||||
AnimControl clone = (AnimControl) super.clone();
|
||||
clone.spatial = spatial;
|
||||
clone.channels = new ArrayList<AnimChannel>();
|
||||
clone.listeners = new ArrayList<AnimEventListener>();
|
||||
|
||||
if (skeleton != null) {
|
||||
clone.skeleton = new Skeleton(skeleton);
|
||||
}
|
||||
|
||||
// animationMap is cloned, but only ClonableTracks will be cloned as they need a reference to a cloned spatial
|
||||
for (Entry<String, Animation> animEntry : animationMap.entrySet()) {
|
||||
clone.animationMap.put(animEntry.getKey(), animEntry.getValue().cloneForSpatial(spatial));
|
||||
}
|
||||
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
AnimControl clone = (AnimControl) super.jmeClone();
|
||||
|
||||
@ -31,17 +31,15 @@
|
||||
*/
|
||||
package com.jme3.animation;
|
||||
|
||||
import static com.jme3.animation.LoopMode.Cycle;
|
||||
import static com.jme3.animation.LoopMode.DontLoop;
|
||||
import static com.jme3.animation.LoopMode.Loop;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Nehon
|
||||
*/
|
||||
public class AnimationUtils {
|
||||
|
||||
public AnimationUtils(){
|
||||
|
||||
}
|
||||
/**
|
||||
* Clamps the time according to duration and loopMode
|
||||
* @param time
|
||||
@ -50,7 +48,7 @@ public class AnimationUtils {
|
||||
* @return
|
||||
*/
|
||||
public static float clampWrapTime(float time, float duration, LoopMode loopMode){
|
||||
if (time == 0) {
|
||||
if (time == 0 || duration == 0) {
|
||||
return 0; // prevent division by 0 errors
|
||||
}
|
||||
switch (loopMode) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2017 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -32,15 +32,15 @@
|
||||
package com.jme3.animation;
|
||||
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.material.MatParamOverride;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Mesh;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.*;
|
||||
import com.jme3.shader.VarType;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -550,7 +550,7 @@ public final class Bone implements Savable, JmeCloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates world transforms for this bone and it's children.
|
||||
* Updates world transforms for this bone and its children.
|
||||
*/
|
||||
public final void update() {
|
||||
this.updateModelTransforms();
|
||||
@ -590,7 +590,7 @@ public final class Bone implements Savable, JmeCloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the bone and it's children to bind pose.
|
||||
* Reset the bone and its children to bind pose.
|
||||
*/
|
||||
final void reset() {
|
||||
if (!userControl) {
|
||||
@ -677,7 +677,7 @@ public final class Bone implements Savable, JmeCloneable {
|
||||
modelPos.set(translation);
|
||||
modelRot.set(rotation);
|
||||
|
||||
//if there is an attached Node we need to set it's local transforms too.
|
||||
//if there is an attached Node we need to set its local transforms too.
|
||||
if(attachNode != null){
|
||||
attachNode.setLocalTranslation(translation);
|
||||
attachNode.setLocalRotation(rotation);
|
||||
@ -723,6 +723,8 @@ public final class Bone implements Savable, JmeCloneable {
|
||||
if (attachNode == null) {
|
||||
attachNode = new Node(name + "_attachnode");
|
||||
attachNode.setUserData("AttachedBone", this);
|
||||
//We don't want the node to have a numBone set by a parent node so we force it to null
|
||||
attachNode.addMatParamOverride(new MatParamOverride(VarType.Int, "NumberOfBones", null));
|
||||
}
|
||||
|
||||
return attachNode;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,6 +35,8 @@ import com.jme3.export.*;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.util.BitSet;
|
||||
|
||||
@ -43,10 +45,10 @@ import java.util.BitSet;
|
||||
*
|
||||
* @author Kirill Vainer
|
||||
*/
|
||||
public final class BoneTrack implements Track {
|
||||
public final class BoneTrack implements JmeCloneable, Track {
|
||||
|
||||
/**
|
||||
* Bone index in the skeleton which this track effects.
|
||||
* Bone index in the skeleton which this track affects.
|
||||
*/
|
||||
private int targetBoneIndex;
|
||||
|
||||
@ -138,16 +140,23 @@ public final class BoneTrack implements Track {
|
||||
|
||||
/**
|
||||
* Set the translations and rotations for this bone track
|
||||
* @param times a float array with the time of each frame
|
||||
* @param translations the translation of the bone for each frame
|
||||
* @param rotations the rotation of the bone for each frame
|
||||
*
|
||||
* @param times the time of each frame, measured from the start of the track
|
||||
* (not null, length>0)
|
||||
* @param translations the translation of the bone for each frame (not null,
|
||||
* same length as times)
|
||||
* @param rotations the rotation of the bone for each frame (not null, same
|
||||
* length as times)
|
||||
*/
|
||||
public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations) {
|
||||
if (times.length == 0) {
|
||||
throw new RuntimeException("BoneTrack with no keyframes!");
|
||||
}
|
||||
|
||||
assert times.length == translations.length && times.length == rotations.length;
|
||||
assert translations != null;
|
||||
assert times.length == translations.length;
|
||||
assert rotations != null;
|
||||
assert times.length == rotations.length;
|
||||
|
||||
this.times = times;
|
||||
this.translations = new CompactVector3Array();
|
||||
@ -160,15 +169,19 @@ public final class BoneTrack implements Track {
|
||||
|
||||
/**
|
||||
* Set the translations, rotations and scales for this bone track
|
||||
* @param times a float array with the time of each frame
|
||||
* @param translations the translation of the bone for each frame
|
||||
* @param rotations the rotation of the bone for each frame
|
||||
* @param scales the scale of the bone for each frame
|
||||
*
|
||||
* @param times the time of each frame, measured from the start of the track
|
||||
* (not null, length>0)
|
||||
* @param translations the translation of the bone for each frame (not null,
|
||||
* same length as times)
|
||||
* @param rotations the rotation of the bone for each frame (not null, same
|
||||
* length as times)
|
||||
* @param scales the scale of the bone for each frame (ignored if null)
|
||||
*/
|
||||
public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) {
|
||||
this.setKeyframes(times, translations, rotations);
|
||||
assert times.length == scales.length;
|
||||
if (scales != null) {
|
||||
assert times.length == scales.length;
|
||||
this.scales = new CompactVector3Array();
|
||||
this.scales.add(scales);
|
||||
this.scales.freeze();
|
||||
@ -263,29 +276,44 @@ public final class BoneTrack implements Track {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a clone of the current object.
|
||||
* @return a clone of the current object
|
||||
* Create a deep clone of this track.
|
||||
*
|
||||
* @return a new track
|
||||
*/
|
||||
@Override
|
||||
public BoneTrack clone() {
|
||||
int tablesLength = times.length;
|
||||
|
||||
float[] times = this.times.clone();
|
||||
Vector3f[] sourceTranslations = this.getTranslations();
|
||||
Quaternion[] sourceRotations = this.getRotations();
|
||||
Vector3f[] sourceScales = this.getScales();
|
||||
|
||||
Vector3f[] translations = new Vector3f[tablesLength];
|
||||
Quaternion[] rotations = new Quaternion[tablesLength];
|
||||
Vector3f[] scales = new Vector3f[tablesLength];
|
||||
for (int i = 0; i < tablesLength; ++i) {
|
||||
translations[i] = sourceTranslations[i].clone();
|
||||
rotations[i] = sourceRotations[i].clone();
|
||||
scales[i] = sourceScales != null ? sourceScales[i].clone() : new Vector3f(1.0f, 1.0f, 1.0f);
|
||||
return Cloner.deepClone(this);
|
||||
}
|
||||
|
||||
// Need to use the constructor here because of the final fields used in this class
|
||||
return new BoneTrack(targetBoneIndex, times, translations, rotations, scales);
|
||||
/**
|
||||
* Create a shallow clone for the JME cloner.
|
||||
*
|
||||
* @return a new track
|
||||
*/
|
||||
@Override
|
||||
public BoneTrack jmeClone() {
|
||||
try {
|
||||
return (BoneTrack) super.clone();
|
||||
} catch (CloneNotSupportedException exception) {
|
||||
throw new RuntimeException("Can't clone track", exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from {@link com.jme3.util.clone.Cloner} to convert this
|
||||
* shallow-cloned track into a deep-cloned one, using the specified cloner
|
||||
* to resolve copied fields.
|
||||
*
|
||||
* @param cloner the cloner currently cloning this control (not null)
|
||||
* @param original the track from which this track was shallow-cloned
|
||||
* (unused)
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields(Cloner cloner, Object original) {
|
||||
translations = cloner.clone(translations);
|
||||
rotations = cloner.clone(rotations);
|
||||
scales = cloner.clone(scales);
|
||||
times = cloner.clone(times);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,6 +31,8 @@
|
||||
*/
|
||||
package com.jme3.animation;
|
||||
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -40,7 +42,7 @@ import java.util.Map;
|
||||
* @author Lim, YongHoon
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class CompactArray<T> {
|
||||
public abstract class CompactArray<T> implements JmeCloneable {
|
||||
|
||||
private Map<T, Integer> indexPool = new HashMap<T, Integer>();
|
||||
protected int[] index;
|
||||
@ -68,6 +70,7 @@ public abstract class CompactArray<T> {
|
||||
* They are serialized automatically when get() method is called.
|
||||
* @param objArray
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(T... objArray) {
|
||||
if (objArray == null || objArray.length == 0) {
|
||||
return;
|
||||
@ -186,10 +189,11 @@ public abstract class CompactArray<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* retrun an array of indices for the given objects
|
||||
* Return an array of indices for the given objects
|
||||
* @param objArray
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final int[] getIndex(T... objArray) {
|
||||
int[] index = new int[objArray.length];
|
||||
for (int i = 0; i < index.length; i++) {
|
||||
@ -228,6 +232,7 @@ public abstract class CompactArray<T> {
|
||||
* decompress and return object array
|
||||
* @return decompress and return object array
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final T[] toObjectArray() {
|
||||
try {
|
||||
T[] compactArr = (T[]) Array.newInstance(getElementClass(), getSerializedSize() / getTupleSize());
|
||||
@ -247,6 +252,47 @@ public abstract class CompactArray<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deep clone of this array.
|
||||
*
|
||||
* @return a new array
|
||||
* @throws java.lang.CloneNotSupportedException
|
||||
*/
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return Cloner.deepClone(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow clone for the JME cloner.
|
||||
*
|
||||
* @return a new array
|
||||
*/
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException exception) {
|
||||
throw new RuntimeException("Can't clone array", exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from {@link com.jme3.util.clone.Cloner} to convert this
|
||||
* shallow-cloned array into a deep-cloned one, using the specified cloner
|
||||
* to resolve copied fields.
|
||||
*
|
||||
* @param cloner the cloner currently cloning this control (not null)
|
||||
* @param original the array from which this array was shallow-cloned
|
||||
* (unused)
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields(Cloner cloner, Object original) {
|
||||
indexPool = cloner.clone(indexPool);
|
||||
index = cloner.clone(index);
|
||||
array = cloner.clone(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* serialize object
|
||||
* @param compactIndex compacted object index
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -42,18 +42,16 @@ import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.Spatial.CullHint;
|
||||
import com.jme3.scene.control.AbstractControl;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* EffectTrack is a track to add to an existing animation, to emit particles
|
||||
* during animations for example : exhausts, dust raised by foot steps, shock
|
||||
* waves, lightnings etc...
|
||||
* during animations for example: exhaust, dust raised by footsteps, shock
|
||||
* waves, lightning, etc...
|
||||
*
|
||||
* usage is
|
||||
* <pre>
|
||||
@ -62,9 +60,9 @@ import java.util.logging.Logger;
|
||||
* control.getAnim("TheAnim").addTrack(track);
|
||||
* </pre>
|
||||
*
|
||||
* if the emitter has emits 0 particles per seconds emmitAllPArticles will be
|
||||
* called on it at time 0 + startOffset. if it he it has more it will start
|
||||
* emit normally at time 0 + startOffset.
|
||||
* if the emitter emits 0 particles per second, emitAllPArticles will be
|
||||
* called on it at time 0 + startOffset. if it has more it will start
|
||||
* emitting normally at time 0 + startOffset.
|
||||
*
|
||||
*
|
||||
* @author Nehon
|
||||
@ -132,19 +130,6 @@ public class EffectTrack implements ClonableTrack {
|
||||
@Override
|
||||
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
|
||||
KillParticleControl c = new KillParticleControl();
|
||||
//this control should be removed as it shouldn't have been persisted in the first place
|
||||
//In the quest to find the less hackish solution to achieve this,
|
||||
//making it remove itself from the spatial in the first update loop when loaded was the less bad.
|
||||
c.remove = true;
|
||||
c.setSpatial(spatial);
|
||||
return c;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
//Anim listener that stops the Emmitter when the animation is finished or changed.
|
||||
@ -213,7 +198,7 @@ public class EffectTrack implements ClonableTrack {
|
||||
control.addListener(new OnEndListener());
|
||||
initialized = true;
|
||||
}
|
||||
//checking fo time to trigger the effect
|
||||
//checking for time to trigger the effect
|
||||
if (!emitted && time >= startOffset) {
|
||||
emitted = true;
|
||||
emitter.setCullHint(CullHint.Dynamic);
|
||||
@ -430,7 +415,7 @@ public class EffectTrack implements ClonableTrack {
|
||||
*/
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
OutputCapsule out = ex.getCapsule(this);
|
||||
//reseting the particle emission rate on the emitter before saving.
|
||||
//reset the particle emission rate on the emitter before saving.
|
||||
emitter.setParticlesPerSec(particlesPerSeconds);
|
||||
out.write(emitter, "emitter", null);
|
||||
out.write(particlesPerSeconds, "particlesPerSeconds", 0);
|
||||
@ -449,7 +434,7 @@ public class EffectTrack implements ClonableTrack {
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
InputCapsule in = im.getCapsule(this);
|
||||
this.particlesPerSeconds = in.readFloat("particlesPerSeconds", 0);
|
||||
//reading the emitter even if the track will then reference its cloned counter part if it's loaded with the assetManager.
|
||||
//reading the emitter even if the track will then reference its cloned counterpart if it's loaded with the assetManager.
|
||||
//This also avoid null pointer exception if the model is not loaded via the AssetManager.
|
||||
emitter = (ParticleEmitter) in.readSavable("emitter", null);
|
||||
emitter.setParticlesPerSec(0);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -53,7 +53,7 @@ public final class Skeleton implements Savable, JmeCloneable {
|
||||
private Bone[] boneList;
|
||||
|
||||
/**
|
||||
* Contains the skinning matrices, multiplying it by a vertex effected by a bone
|
||||
* Contains the skinning matrices, multiplying it by a vertex affected by a bone
|
||||
* will cause it to go to the animated position.
|
||||
*/
|
||||
private transient Matrix4f[] skinningMatrixes;
|
||||
@ -169,7 +169,7 @@ public final class Skeleton implements Savable, JmeCloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current skeleton state as it's binding pose.
|
||||
* Saves the current skeleton state as its binding pose.
|
||||
*/
|
||||
public void setBindingPose() {
|
||||
for (int i = rootBones.length - 1; i >= 0; i--) {
|
||||
@ -304,6 +304,7 @@ public final class Skeleton implements Savable, JmeCloneable {
|
||||
createSkinningMatrices();
|
||||
|
||||
for (Bone rootBone : rootBones) {
|
||||
rootBone.reset();
|
||||
rootBone.update();
|
||||
rootBone.setBindingPose();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2017 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,21 +35,18 @@ import com.jme3.export.*;
|
||||
import com.jme3.material.MatParamOverride;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.RendererException;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.renderer.*;
|
||||
import com.jme3.scene.*;
|
||||
import com.jme3.scene.VertexBuffer.Type;
|
||||
import com.jme3.scene.control.AbstractControl;
|
||||
import com.jme3.scene.control.Control;
|
||||
import com.jme3.scene.mesh.IndexBuffer;
|
||||
import com.jme3.shader.VarType;
|
||||
import com.jme3.util.*;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -145,6 +142,12 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl
|
||||
}
|
||||
|
||||
private boolean testHardwareSupported(RenderManager rm) {
|
||||
|
||||
//Only 255 bones max supported with hardware skinning
|
||||
if (skeleton.getBoneCount() > 255) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switchToHardware();
|
||||
|
||||
try {
|
||||
@ -158,7 +161,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl
|
||||
|
||||
/**
|
||||
* Specifies if hardware skinning is preferred. If it is preferred and
|
||||
* supported by GPU, it shall be enabled, if its not preferred, or not
|
||||
* supported by GPU, it shall be enabled, if it's not preferred, or not
|
||||
* supported by GPU, then it shall be disabled.
|
||||
*
|
||||
* @param preferred
|
||||
@ -326,7 +329,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl
|
||||
bpb.clear();
|
||||
bnb.clear();
|
||||
|
||||
//reseting bind tangents if there is a bind tangent buffer
|
||||
//reset bind tangents if there is a bind tangent buffer
|
||||
VertexBuffer bindTangents = mesh.getBuffer(Type.BindPoseTangent);
|
||||
if (bindTangents != null) {
|
||||
VertexBuffer tangents = mesh.getBuffer(Type.Tangent);
|
||||
@ -344,47 +347,6 @@ public class SkeletonControl extends AbstractControl implements Cloneable, JmeCl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
Node clonedNode = (Node) spatial;
|
||||
SkeletonControl clone = new SkeletonControl();
|
||||
|
||||
AnimControl ctrl = spatial.getControl(AnimControl.class);
|
||||
if (ctrl != null) {
|
||||
// AnimControl is responsible for cloning the skeleton, not
|
||||
// SkeletonControl.
|
||||
clone.skeleton = ctrl.getSkeleton();
|
||||
} else {
|
||||
// If there's no AnimControl, create the clone ourselves.
|
||||
clone.skeleton = new Skeleton(skeleton);
|
||||
}
|
||||
clone.hwSkinningDesired = this.hwSkinningDesired;
|
||||
clone.hwSkinningEnabled = this.hwSkinningEnabled;
|
||||
clone.hwSkinningSupported = this.hwSkinningSupported;
|
||||
clone.hwSkinningTested = this.hwSkinningTested;
|
||||
|
||||
clone.setSpatial(clonedNode);
|
||||
|
||||
// Fix attachments for the cloned node
|
||||
for (int i = 0; i < clonedNode.getQuantity(); i++) {
|
||||
// go through attachment nodes, apply them to correct bone
|
||||
Spatial child = clonedNode.getChild(i);
|
||||
if (child instanceof Node) {
|
||||
Node clonedAttachNode = (Node) child;
|
||||
Bone originalBone = (Bone) clonedAttachNode.getUserData("AttachedBone");
|
||||
|
||||
if (originalBone != null) {
|
||||
Bone clonedBone = clone.skeleton.getBone(originalBone.getName());
|
||||
|
||||
clonedAttachNode.setUserData("AttachedBone", clonedBone);
|
||||
clonedBone.setAttachmentsNode(clonedAttachNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
return super.jmeClone();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,16 +41,14 @@ import com.jme3.scene.Spatial;
|
||||
import com.jme3.util.TempVars;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class represents the track for spatial animation.
|
||||
*
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
public class SpatialTrack implements Track, JmeCloneable {
|
||||
public class SpatialTrack implements JmeCloneable, Track {
|
||||
|
||||
/**
|
||||
* Translations of the track.
|
||||
@ -250,9 +248,16 @@ public class SpatialTrack implements Track, JmeCloneable {
|
||||
return times == null ? 0 : times[times.length - 1] - times[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone with the same track spatial.
|
||||
*
|
||||
* @return a new track
|
||||
*/
|
||||
@Override
|
||||
public Track clone() {
|
||||
return (Track) jmeClone();
|
||||
public SpatialTrack clone() {
|
||||
Cloner cloner = new Cloner();
|
||||
cloner.setClonedValue(trackSpatial, trackSpatial);
|
||||
return cloner.clone(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -268,22 +273,36 @@ public class SpatialTrack implements Track, JmeCloneable {
|
||||
return trackSpatial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow clone for the JME cloner.
|
||||
*
|
||||
* @return a new track
|
||||
*/
|
||||
@Override
|
||||
public Object jmeClone() {
|
||||
int tablesLength = times.length;
|
||||
|
||||
float[] timesCopy = this.times.clone();
|
||||
Vector3f[] translationsCopy = this.getTranslations() == null ? null : Arrays.copyOf(this.getTranslations(), tablesLength);
|
||||
Quaternion[] rotationsCopy = this.getRotations() == null ? null : Arrays.copyOf(this.getRotations(), tablesLength);
|
||||
Vector3f[] scalesCopy = this.getScales() == null ? null : Arrays.copyOf(this.getScales(), tablesLength);
|
||||
|
||||
//need to use the constructor here because of the final fields used in this class
|
||||
return new SpatialTrack(timesCopy, translationsCopy, rotationsCopy, scalesCopy);
|
||||
public SpatialTrack jmeClone() {
|
||||
try {
|
||||
return (SpatialTrack) super.clone();
|
||||
} catch (CloneNotSupportedException exception) {
|
||||
throw new RuntimeException("Can't clone track", exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from {@link com.jme3.util.clone.Cloner} to convert this
|
||||
* shallow-cloned track into a deep-cloned one, using the specified cloner
|
||||
* to resolve copied fields.
|
||||
*
|
||||
* @param cloner the cloner currently cloning this control (not null)
|
||||
* @param original the track from which this track was shallow-cloned
|
||||
* (unused)
|
||||
*/
|
||||
@Override
|
||||
public void cloneFields(Cloner cloner, Object original) {
|
||||
this.trackSpatial = cloner.clone(((SpatialTrack) original).trackSpatial);
|
||||
translations = cloner.clone(translations);
|
||||
rotations = cloner.clone(rotations);
|
||||
scales = cloner.clone(scales);
|
||||
trackSpatial = cloner.clone(trackSpatial);
|
||||
times = cloner.clone(times);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -45,8 +45,8 @@ public interface Track extends Savable, Cloneable {
|
||||
*
|
||||
* @param time The time in the animation
|
||||
* @param weight The weight from 0 to 1 on how much to apply the track
|
||||
* @param control The control which the track should effect
|
||||
* @param channel The channel which the track should effect
|
||||
* @param control The control which the track should affect
|
||||
* @param channel The channel which the track should affect
|
||||
*/
|
||||
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars);
|
||||
|
||||
|
||||
@ -59,6 +59,8 @@ public class DetailedProfilerState extends BaseAppState {
|
||||
private ColorRGBA dimmedOrange = ColorRGBA.Orange.mult(0.7f);
|
||||
private ColorRGBA dimmedRed = ColorRGBA.Red.mult(0.7f);
|
||||
|
||||
private ProfilerInputListener inputListener = new ProfilerInputListener();
|
||||
|
||||
public DetailedProfilerState() {
|
||||
|
||||
}
|
||||
@ -119,23 +121,17 @@ public class DetailedProfilerState extends BaseAppState {
|
||||
if (inputManager != null) {
|
||||
inputManager.addMapping(TOGGLE_KEY, new KeyTrigger(KeyInput.KEY_F6));
|
||||
inputManager.addMapping(CLICK_KEY, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
|
||||
inputManager.addListener(new ActionListener() {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (name.equals(TOGGLE_KEY) && isPressed) {
|
||||
setEnabled(!isEnabled());
|
||||
}
|
||||
if (isEnabled() && name.equals(CLICK_KEY) && isPressed) {
|
||||
handleClick(inputManager.getCursorPosition());
|
||||
}
|
||||
}
|
||||
}, TOGGLE_KEY, CLICK_KEY);
|
||||
inputManager.addListener(inputListener, TOGGLE_KEY, CLICK_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanup(Application app) {
|
||||
|
||||
ui.detachAllChildren();
|
||||
InputManager manager = getApplication().getInputManager();
|
||||
manager.deleteMapping(TOGGLE_KEY);
|
||||
manager.deleteMapping(CLICK_KEY);
|
||||
manager.removeListener(inputListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -441,8 +437,18 @@ public class DetailedProfilerState extends BaseAppState {
|
||||
public String toString() {
|
||||
return label.getText() + " - " + df.format(getMsFromNs(cpuValue)) + "ms / " + df.format(getMsFromNs(gpuValue)) + "ms";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ProfilerInputListener implements ActionListener {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (name.equals(TOGGLE_KEY) && isPressed) {
|
||||
setEnabled(!isEnabled());
|
||||
}
|
||||
if (isEnabled() && name.equals(CLICK_KEY) && isPressed) {
|
||||
handleClick(getApplication().getInputManager().getCursorPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -117,9 +117,10 @@ public class StatsView extends Node implements Control, JmeCloneable {
|
||||
//statistics.clearFrame();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
return (Control) spatial;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -80,10 +80,10 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
|
||||
/**
|
||||
* This constructor allows you to specify the output file path of the screenshot.
|
||||
* Include the seperator at the end of the path.
|
||||
* Use an emptry string to use the application folder. Use NULL to use the system
|
||||
* Include the separator at the end of the path.
|
||||
* Use an empty string to use the application folder. Use NULL to use the system
|
||||
* default storage folder.
|
||||
* @param filePath The screenshot file path to use. Include the seperator at the end of the path.
|
||||
* @param filePath The screenshot file path to use. Include the separator at the end of the path.
|
||||
*/
|
||||
public ScreenshotAppState(String filePath) {
|
||||
this.filePath = filePath;
|
||||
@ -91,11 +91,11 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
|
||||
/**
|
||||
* This constructor allows you to specify the output file path of the screenshot.
|
||||
* Include the seperator at the end of the path.
|
||||
* Use an emptry string to use the application folder. Use NULL to use the system
|
||||
* Include the separator at the end of the path.
|
||||
* Use an empty string to use the application folder. Use NULL to use the system
|
||||
* default storage folder.
|
||||
* @param filePath The screenshot file path to use. Include the seperator at the end of the path.
|
||||
* @param fileName The name of the file to save the screeshot as.
|
||||
* @param filePath The screenshot file path to use. Include the separator at the end of the path.
|
||||
* @param fileName The name of the file to save the screenshot as.
|
||||
*/
|
||||
public ScreenshotAppState(String filePath, String fileName) {
|
||||
this.filePath = filePath;
|
||||
@ -105,10 +105,10 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
/**
|
||||
* This constructor allows you to specify the output file path of the screenshot and
|
||||
* a base index for the shot index.
|
||||
* Include the seperator at the end of the path.
|
||||
* Use an emptry string to use the application folder. Use NULL to use the system
|
||||
* Include the separator at the end of the path.
|
||||
* Use an empty string to use the application folder. Use NULL to use the system
|
||||
* default storage folder.
|
||||
* @param filePath The screenshot file path to use. Include the seperator at the end of the path.
|
||||
* @param filePath The screenshot file path to use. Include the separator at the end of the path.
|
||||
* @param shotIndex The base index for screen shots. The first screen shot will have
|
||||
* shotIndex + 1 appended, the next shotIndex + 2, and so on.
|
||||
*/
|
||||
@ -120,11 +120,11 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
/**
|
||||
* This constructor allows you to specify the output file path of the screenshot and
|
||||
* a base index for the shot index.
|
||||
* Include the seperator at the end of the path.
|
||||
* Use an emptry string to use the application folder. Use NULL to use the system
|
||||
* Include the separator at the end of the path.
|
||||
* Use an empty string to use the application folder. Use NULL to use the system
|
||||
* default storage folder.
|
||||
* @param filePath The screenshot file path to use. Include the seperator at the end of the path.
|
||||
* @param fileName The name of the file to save the screeshot as.
|
||||
* @param filePath The screenshot file path to use. Include the separator at the end of the path.
|
||||
* @param fileName The name of the file to save the screenshot as.
|
||||
* @param shotIndex The base index for screen shots. The first screen shot will have
|
||||
* shotIndex + 1 appended, the next shotIndex + 2, and so on.
|
||||
*/
|
||||
@ -136,10 +136,10 @@ public class ScreenshotAppState extends AbstractAppState implements ActionListen
|
||||
|
||||
/**
|
||||
* Set the file path to store the screenshot.
|
||||
* Include the seperator at the end of the path.
|
||||
* Use an emptry string to use the application folder. Use NULL to use the system
|
||||
* Include the separator at the end of the path.
|
||||
* Use an empty string to use the application folder. Use NULL to use the system
|
||||
* default storage folder.
|
||||
* @param filePath File path to use to store the screenshot. Include the seperator at the end of the path.
|
||||
* @param filePath File path to use to store the screenshot. Include the separator at the end of the path.
|
||||
*/
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -217,7 +217,7 @@ public interface AssetManager {
|
||||
* Load an asset from a key, the asset will be located
|
||||
* by one of the {@link AssetLocator} implementations provided in the
|
||||
* {@link AssetManager#registerLocator(java.lang.String, java.lang.Class) }
|
||||
* call. If located successfully, it will be loaded via the the appropriate
|
||||
* call. If located successfully, it will be loaded via the appropriate
|
||||
* {@link AssetLoader} implementation based on the file's extension, as
|
||||
* specified in the call
|
||||
* {@link AssetManager#registerLoader(java.lang.Class, java.lang.String[]) }.
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
package com.jme3.asset;
|
||||
|
||||
import com.jme3.asset.cache.AssetCache;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -279,9 +280,9 @@ final class ImplHandler {
|
||||
// Synchronized access must be used for any ops on classToLoaderMap
|
||||
// Find the loader ImplThreadLocal for this class
|
||||
synchronized (classToLoaderMap){
|
||||
ImplThreadLocal local = classToLoaderMap.get(loaderType);
|
||||
// Remove it from the class->loader map
|
||||
classToLoaderMap.remove(loaderType);
|
||||
ImplThreadLocal local = classToLoaderMap.remove(loaderType);
|
||||
if (local == null) return;
|
||||
// Remove it from the extension->loader map
|
||||
for (String extension : local.getExtensions()){
|
||||
extensionToLoaderMap.remove(extension);
|
||||
|
||||
@ -112,11 +112,10 @@ public class WeakRefCloneAssetCache implements AssetCache {
|
||||
// might not even have this asset anymore, it is OK.
|
||||
if (smartCache.remove(key) != null){
|
||||
removedAssets ++;
|
||||
//System.out.println("WeakRefAssetCache: The asset " + ref.assetKey + " was purged from the cache");
|
||||
}
|
||||
}
|
||||
if (removedAssets >= 1) {
|
||||
logger.log(Level.FINE, "WeakRefAssetCache: {0} assets were purged from the cache.", removedAssets);
|
||||
logger.log(Level.FINE, "WeakRefCloneAssetCache: {0} assets were purged from the cache.", removedAssets);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012, 2016 jMonkeyEngine
|
||||
* Copyright (c) 2009-2012, 2016, 2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -221,7 +221,7 @@ public class AudioNode extends Node implements AudioSource {
|
||||
/**
|
||||
* Start playing an instance of this audio. This method can be used
|
||||
* to play the same <code>AudioNode</code> multiple times. Note
|
||||
* that changes to the parameters of this AudioNode will not effect the
|
||||
* that changes to the parameters of this AudioNode will not affect the
|
||||
* instances already playing.
|
||||
*/
|
||||
public void playInstance(){
|
||||
@ -278,8 +278,8 @@ public class AudioNode extends Node implements AudioSource {
|
||||
* the dry filter will only influence the "dry" portion of the audio,
|
||||
* e.g. not the reverberated parts of the AudioNode playing.
|
||||
*
|
||||
* See the relevent documentation for the {@link Filter} to determine
|
||||
* the effect.
|
||||
* See the relevant documentation for the {@link Filter} to determine the
|
||||
* effect.
|
||||
*
|
||||
* @param dryFilter The filter to set, or null to disable dry filter.
|
||||
*/
|
||||
@ -692,7 +692,7 @@ public class AudioNode extends Node implements AudioSource {
|
||||
|
||||
/**
|
||||
* Set the audio node as positional.
|
||||
* The position, velocity, and distance parameters effect positional
|
||||
* The position, velocity, and distance parameters affect positional
|
||||
* audio nodes. Set to false if the audio node should play in "headspace".
|
||||
*
|
||||
* @param positional True if the audio node should be positional, otherwise
|
||||
|
||||
@ -12,37 +12,37 @@ public interface AL {
|
||||
/**
|
||||
* Boolean False.
|
||||
*/
|
||||
static final int AL_FALSE = 0;
|
||||
public static final int AL_FALSE = 0;
|
||||
|
||||
/**
|
||||
* Boolean True.
|
||||
*/
|
||||
static final int AL_TRUE = 1;
|
||||
public static final int AL_TRUE = 1;
|
||||
|
||||
/* "no distance model" or "no buffer" */
|
||||
static final int AL_NONE = 0;
|
||||
public static final int AL_NONE = 0;
|
||||
|
||||
/**
|
||||
* Indicate Source has relative coordinates.
|
||||
*/
|
||||
static final int AL_SOURCE_RELATIVE = 0x202;
|
||||
public static final int AL_SOURCE_RELATIVE = 0x202;
|
||||
|
||||
/**
|
||||
* Directional source, inner cone angle, in degrees. Range: [0-360] Default:
|
||||
* 360
|
||||
*/
|
||||
static final int AL_CONE_INNER_ANGLE = 0x1001;
|
||||
public static final int AL_CONE_INNER_ANGLE = 0x1001;
|
||||
|
||||
/**
|
||||
* Directional source, outer cone angle, in degrees. Range: [0-360] Default:
|
||||
* 360
|
||||
*/
|
||||
static final int AL_CONE_OUTER_ANGLE = 0x1002;
|
||||
public static final int AL_CONE_OUTER_ANGLE = 0x1002;
|
||||
|
||||
/**
|
||||
* Specify the pitch to be applied at source. Range: [0.5-2.0] Default: 1.0
|
||||
*/
|
||||
static final int AL_PITCH = 0x1003;
|
||||
public static final int AL_PITCH = 0x1003;
|
||||
|
||||
/**
|
||||
* Specify the current location in three dimensional space. OpenAL, like
|
||||
@ -52,84 +52,84 @@ public interface AL {
|
||||
* coordinate system, flip the sign on the Z coordinate. Listener position
|
||||
* is always in the world coordinate system.
|
||||
*/
|
||||
static final int AL_POSITION = 0x1004;
|
||||
public static final int AL_POSITION = 0x1004;
|
||||
|
||||
/**
|
||||
* Specify the current direction.
|
||||
*/
|
||||
static final int AL_DIRECTION = 0x1005;
|
||||
public static final int AL_DIRECTION = 0x1005;
|
||||
|
||||
/**
|
||||
* Specify the current velocity in three dimensional space.
|
||||
*/
|
||||
static final int AL_VELOCITY = 0x1006;
|
||||
public static final int AL_VELOCITY = 0x1006;
|
||||
|
||||
/**
|
||||
* Indicate whether source is looping. Type: ALboolean? Range: [AL_TRUE,
|
||||
* AL_FALSE] Default: FALSE.
|
||||
*/
|
||||
static final int AL_LOOPING = 0x1007;
|
||||
public static final int AL_LOOPING = 0x1007;
|
||||
|
||||
/**
|
||||
* Indicate the buffer to provide sound samples. Type: ALuint. Range: any
|
||||
* valid Buffer id.
|
||||
*/
|
||||
static final int AL_BUFFER = 0x1009;
|
||||
public static final int AL_BUFFER = 0x1009;
|
||||
|
||||
/**
|
||||
* Indicate the gain (volume amplification) applied. Type: ALfloat. Range:
|
||||
* ]0.0- ] A value of 1.0 means un-attenuated/unchanged. Each division by 2
|
||||
* equals an attenuation of -6dB. Each multiplicaton with 2 equals an
|
||||
* equals an attenuation of -6dB. Each multiplication by 2 equals an
|
||||
* amplification of +6dB. A value of 0.0 is meaningless with respect to a
|
||||
* logarithmic scale; it is interpreted as zero volume - the channel is
|
||||
* effectively disabled.
|
||||
*/
|
||||
static final int AL_GAIN = 0x100A;
|
||||
public static final int AL_GAIN = 0x100A;
|
||||
|
||||
/*
|
||||
* Indicate minimum source attenuation
|
||||
* Type: ALfloat
|
||||
* Range: [0.0 - 1.0]
|
||||
*
|
||||
* Logarthmic
|
||||
* Logarithmic
|
||||
*/
|
||||
static final int AL_MIN_GAIN = 0x100D;
|
||||
public static final int AL_MIN_GAIN = 0x100D;
|
||||
|
||||
/**
|
||||
* Indicate maximum source attenuation Type: ALfloat Range: [0.0 - 1.0]
|
||||
*
|
||||
* Logarthmic
|
||||
* Logarithmic
|
||||
*/
|
||||
static final int AL_MAX_GAIN = 0x100E;
|
||||
public static final int AL_MAX_GAIN = 0x100E;
|
||||
|
||||
/**
|
||||
* Indicate listener orientation.
|
||||
*
|
||||
* at/up
|
||||
*/
|
||||
static final int AL_ORIENTATION = 0x100F;
|
||||
public static final int AL_ORIENTATION = 0x100F;
|
||||
|
||||
/**
|
||||
* Source state information.
|
||||
*/
|
||||
static final int AL_SOURCE_STATE = 0x1010;
|
||||
static final int AL_INITIAL = 0x1011;
|
||||
static final int AL_PLAYING = 0x1012;
|
||||
static final int AL_PAUSED = 0x1013;
|
||||
static final int AL_STOPPED = 0x1014;
|
||||
public static final int AL_SOURCE_STATE = 0x1010;
|
||||
public static final int AL_INITIAL = 0x1011;
|
||||
public static final int AL_PLAYING = 0x1012;
|
||||
public static final int AL_PAUSED = 0x1013;
|
||||
public static final int AL_STOPPED = 0x1014;
|
||||
|
||||
/**
|
||||
* Buffer Queue params
|
||||
*/
|
||||
static final int AL_BUFFERS_QUEUED = 0x1015;
|
||||
static final int AL_BUFFERS_PROCESSED = 0x1016;
|
||||
public static final int AL_BUFFERS_QUEUED = 0x1015;
|
||||
public static final int AL_BUFFERS_PROCESSED = 0x1016;
|
||||
|
||||
/**
|
||||
* Source buffer position information
|
||||
*/
|
||||
static final int AL_SEC_OFFSET = 0x1024;
|
||||
static final int AL_SAMPLE_OFFSET = 0x1025;
|
||||
static final int AL_BYTE_OFFSET = 0x1026;
|
||||
public static final int AL_SEC_OFFSET = 0x1024;
|
||||
public static final int AL_SAMPLE_OFFSET = 0x1025;
|
||||
public static final int AL_BYTE_OFFSET = 0x1026;
|
||||
|
||||
/*
|
||||
* Source type (Static, Streaming or undetermined)
|
||||
@ -137,38 +137,38 @@ public interface AL {
|
||||
* Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
|
||||
* Source is undetermined when it has the NULL buffer attached
|
||||
*/
|
||||
static final int AL_SOURCE_TYPE = 0x1027;
|
||||
static final int AL_STATIC = 0x1028;
|
||||
static final int AL_STREAMING = 0x1029;
|
||||
static final int AL_UNDETERMINED = 0x1030;
|
||||
public static final int AL_SOURCE_TYPE = 0x1027;
|
||||
public static final int AL_STATIC = 0x1028;
|
||||
public static final int AL_STREAMING = 0x1029;
|
||||
public static final int AL_UNDETERMINED = 0x1030;
|
||||
|
||||
/**
|
||||
* Sound samples: format specifier.
|
||||
*/
|
||||
static final int AL_FORMAT_MONO8 = 0x1100;
|
||||
static final int AL_FORMAT_MONO16 = 0x1101;
|
||||
static final int AL_FORMAT_STEREO8 = 0x1102;
|
||||
static final int AL_FORMAT_STEREO16 = 0x1103;
|
||||
public static final int AL_FORMAT_MONO8 = 0x1100;
|
||||
public static final int AL_FORMAT_MONO16 = 0x1101;
|
||||
public static final int AL_FORMAT_STEREO8 = 0x1102;
|
||||
public static final int AL_FORMAT_STEREO16 = 0x1103;
|
||||
|
||||
/**
|
||||
* source specific reference distance Type: ALfloat Range: 0.0 - +inf
|
||||
*
|
||||
* At 0.0, no distance attenuation occurs. Default is 1.0.
|
||||
*/
|
||||
static final int AL_REFERENCE_DISTANCE = 0x1020;
|
||||
public static final int AL_REFERENCE_DISTANCE = 0x1020;
|
||||
|
||||
/**
|
||||
* source specific rolloff factor Type: ALfloat Range: 0.0 - +inf
|
||||
*
|
||||
*/
|
||||
static final int AL_ROLLOFF_FACTOR = 0x1021;
|
||||
public static final int AL_ROLLOFF_FACTOR = 0x1021;
|
||||
|
||||
/**
|
||||
* Directional source, outer cone gain.
|
||||
*
|
||||
* Default: 0.0 Range: [0.0 - 1.0] Logarithmic
|
||||
*/
|
||||
static final int AL_CONE_OUTER_GAIN = 0x1022;
|
||||
public static final int AL_CONE_OUTER_GAIN = 0x1022;
|
||||
|
||||
/**
|
||||
* Indicate distance above which sources are not attenuated using the
|
||||
@ -176,64 +176,64 @@ public interface AL {
|
||||
*
|
||||
* Default: +inf Type: ALfloat Range: 0.0 - +inf
|
||||
*/
|
||||
static final int AL_MAX_DISTANCE = 0x1023;
|
||||
public static final int AL_MAX_DISTANCE = 0x1023;
|
||||
|
||||
/**
|
||||
* Sound samples: frequency, in units of Hertz [Hz]. This is the number of
|
||||
* samples per second. Half of the sample frequency marks the maximum
|
||||
* significant frequency component.
|
||||
*/
|
||||
static final int AL_FREQUENCY = 0x2001;
|
||||
static final int AL_BITS = 0x2002;
|
||||
static final int AL_CHANNELS = 0x2003;
|
||||
static final int AL_SIZE = 0x2004;
|
||||
public static final int AL_FREQUENCY = 0x2001;
|
||||
public static final int AL_BITS = 0x2002;
|
||||
public static final int AL_CHANNELS = 0x2003;
|
||||
public static final int AL_SIZE = 0x2004;
|
||||
|
||||
/**
|
||||
* Buffer state.
|
||||
*
|
||||
* Not supported for public use (yet).
|
||||
*/
|
||||
static final int AL_UNUSED = 0x2010;
|
||||
static final int AL_PENDING = 0x2011;
|
||||
static final int AL_PROCESSED = 0x2012;
|
||||
public static final int AL_UNUSED = 0x2010;
|
||||
public static final int AL_PENDING = 0x2011;
|
||||
public static final int AL_PROCESSED = 0x2012;
|
||||
|
||||
/**
|
||||
* Errors: No Error.
|
||||
*/
|
||||
static final int AL_NO_ERROR = 0;
|
||||
public static final int AL_NO_ERROR = 0;
|
||||
|
||||
/**
|
||||
* Invalid Name paramater passed to AL call.
|
||||
* Invalid Name parameter passed to AL call.
|
||||
*/
|
||||
static final int AL_INVALID_NAME = 0xA001;
|
||||
public static final int AL_INVALID_NAME = 0xA001;
|
||||
|
||||
/**
|
||||
* Invalid parameter passed to AL call.
|
||||
*/
|
||||
static final int AL_INVALID_ENUM = 0xA002;
|
||||
public static final int AL_INVALID_ENUM = 0xA002;
|
||||
|
||||
/**
|
||||
* Invalid enum parameter value.
|
||||
*/
|
||||
static final int AL_INVALID_VALUE = 0xA003;
|
||||
public static final int AL_INVALID_VALUE = 0xA003;
|
||||
|
||||
/**
|
||||
* Illegal call.
|
||||
*/
|
||||
static final int AL_INVALID_OPERATION = 0xA004;
|
||||
public static final int AL_INVALID_OPERATION = 0xA004;
|
||||
|
||||
/**
|
||||
* No mojo.
|
||||
*/
|
||||
static final int AL_OUT_OF_MEMORY = 0xA005;
|
||||
public static final int AL_OUT_OF_MEMORY = 0xA005;
|
||||
|
||||
/**
|
||||
* Context strings: Vendor Name.
|
||||
*/
|
||||
static final int AL_VENDOR = 0xB001;
|
||||
static final int AL_VERSION = 0xB002;
|
||||
static final int AL_RENDERER = 0xB003;
|
||||
static final int AL_EXTENSIONS = 0xB004;
|
||||
public static final int AL_VENDOR = 0xB001;
|
||||
public static final int AL_VERSION = 0xB002;
|
||||
public static final int AL_RENDERER = 0xB003;
|
||||
public static final int AL_EXTENSIONS = 0xB004;
|
||||
|
||||
/**
|
||||
* Global tweakage.
|
||||
@ -241,56 +241,241 @@ public interface AL {
|
||||
/**
|
||||
* Doppler scale. Default 1.0
|
||||
*/
|
||||
static final int AL_DOPPLER_FACTOR = 0xC000;
|
||||
public static final int AL_DOPPLER_FACTOR = 0xC000;
|
||||
|
||||
/**
|
||||
* Tweaks speed of propagation.
|
||||
*/
|
||||
static final int AL_DOPPLER_VELOCITY = 0xC001;
|
||||
public static final int AL_DOPPLER_VELOCITY = 0xC001;
|
||||
|
||||
/**
|
||||
* Speed of Sound in units per second
|
||||
*/
|
||||
static final int AL_SPEED_OF_SOUND = 0xC003;
|
||||
public static final int AL_SPEED_OF_SOUND = 0xC003;
|
||||
|
||||
/**
|
||||
* Distance models
|
||||
*
|
||||
* used in conjunction with DistanceModel
|
||||
*
|
||||
* implicit: NONE, which disances distance attenuation.
|
||||
* implicit: NONE, which disables distance attenuation.
|
||||
*/
|
||||
static final int AL_DISTANCE_MODEL = 0xD000;
|
||||
static final int AL_INVERSE_DISTANCE = 0xD001;
|
||||
static final int AL_INVERSE_DISTANCE_CLAMPED = 0xD002;
|
||||
static final int AL_LINEAR_DISTANCE = 0xD003;
|
||||
static final int AL_LINEAR_DISTANCE_CLAMPED = 0xD004;
|
||||
static final int AL_EXPONENT_DISTANCE = 0xD005;
|
||||
static final int AL_EXPONENT_DISTANCE_CLAMPED = 0xD006;
|
||||
//
|
||||
///* Listener parameter value ranges and defaults. */
|
||||
//#define AL_MIN_METERS_PER_UNIT FLT_MIN
|
||||
//#define AL_MAX_METERS_PER_UNIT FLT_MAX
|
||||
//#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
|
||||
public static final int AL_DISTANCE_MODEL = 0xD000;
|
||||
public static final int AL_INVERSE_DISTANCE = 0xD001;
|
||||
public static final int AL_INVERSE_DISTANCE_CLAMPED = 0xD002;
|
||||
public static final int AL_LINEAR_DISTANCE = 0xD003;
|
||||
public static final int AL_LINEAR_DISTANCE_CLAMPED = 0xD004;
|
||||
public static final int AL_EXPONENT_DISTANCE = 0xD005;
|
||||
public static final int AL_EXPONENT_DISTANCE_CLAMPED = 0xD006;
|
||||
|
||||
//
|
||||
///* Listener parameter value ranges and defaults. */
|
||||
//#define AL_MIN_METERS_PER_UNIT FLT_MIN
|
||||
//#define AL_MAX_METERS_PER_UNIT FLT_MAX
|
||||
//#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
|
||||
|
||||
public String alGetString(int parameter);
|
||||
|
||||
/**
|
||||
* Requests a number of source names.
|
||||
*
|
||||
* @return the number of source names.
|
||||
*/
|
||||
public int alGenSources();
|
||||
|
||||
/**
|
||||
* Obtains error information.
|
||||
* <p>
|
||||
* <p>Each detectable error is assigned a numeric code. When an error is detected by AL, a flag is set and the error code is recorded. Further errors, if they
|
||||
* occur, do not affect this recorded code. When alGetError is called, the code is returned and the flag is cleared, so that a further error will again
|
||||
* record its code. If a call to alGetError returns AL_NO_ERROR then there has been no detectable error since the last call to alGetError (or since the AL
|
||||
* was initialized).</p>
|
||||
* <p>
|
||||
* <p>Error codes can be mapped to strings. The alGetString function returns a pointer to a constant (literal) string that is identical to the identifier used
|
||||
* for the enumeration value, as defined in the specification.</p>
|
||||
*/
|
||||
public int alGetError();
|
||||
|
||||
/**
|
||||
* Requests the deletion of a number of sources.
|
||||
*
|
||||
* @param numSources the number of sources.
|
||||
* @param sources the sources to delete.
|
||||
*/
|
||||
public void alDeleteSources(int numSources, IntBuffer sources);
|
||||
|
||||
/**
|
||||
* Requests a number of buffer names.
|
||||
*
|
||||
* @param numBuffers the number of buffers.
|
||||
* @param buffers the buffer that will receive the buffer names.
|
||||
*/
|
||||
public void alGenBuffers(int numBuffers, IntBuffer buffers);
|
||||
|
||||
/**
|
||||
* Requests the deletion of a number of buffers.
|
||||
*
|
||||
* @param numBuffers the number of buffers.
|
||||
* @param buffers the buffers to delete.
|
||||
*/
|
||||
public void alDeleteBuffers(int numBuffers, IntBuffer buffers);
|
||||
|
||||
/**
|
||||
* Sets the source state to AL_STOPPED.
|
||||
* <p>
|
||||
* <p>alSourceStop applied to an AL_INITIAL source is a legal NOP. alSourceStop applied to a AL_PLAYING source will change its state to AL_STOPPED. The source
|
||||
* is exempt from processing, its current state is preserved. alSourceStop applied to a AL_PAUSED source will change its state to AL_STOPPED, with the same
|
||||
* consequences as on a AL_PLAYING source. alSourceStop applied to a AL_STOPPED source is a legal NOP.</p>
|
||||
*
|
||||
* @param source the source to stop.
|
||||
*/
|
||||
public void alSourceStop(int source);
|
||||
|
||||
/**
|
||||
* Integer version of {@link #alSourcef Sourcef}.
|
||||
*
|
||||
* @param source the source to modify.
|
||||
* @param param the parameter to modify.
|
||||
* @param value the parameter value.
|
||||
*/
|
||||
public void alSourcei(int source, int param, int value);
|
||||
|
||||
/**
|
||||
* Sets the sample data of the specified buffer.
|
||||
* <p>
|
||||
* <p>The data specified is copied to an internal software, or if possible, hardware buffer. The implementation is free to apply decompression, conversion,
|
||||
* resampling, and filtering as needed.</p>
|
||||
* <p>
|
||||
* <p>8-bit data is expressed as an unsigned value over the range 0 to 255, 128 being an audio output level of zero.</p>
|
||||
* <p>
|
||||
* <p>16-bit data is expressed as a signed value over the range -32768 to 32767, 0 being an audio output level of zero. Byte order for 16-bit values is
|
||||
* determined by the native format of the CPU.</p>
|
||||
* <p>
|
||||
* <p>Stereo data is expressed in an interleaved format, left channel sample followed by the right channel sample.</p>
|
||||
* <p>
|
||||
* <p>Buffers containing audio data with more than one channel will be played without 3D spatialization features – these formats are normally used for
|
||||
* background music.</p>
|
||||
*
|
||||
* @param buffer the buffer to modify.
|
||||
* @param format the data format. One of:<br><table><tr><td>{@link #AL_FORMAT_MONO8 FORMAT_MONO8}</td><td>{@link #AL_FORMAT_MONO16 FORMAT_MONO16}</td><td>{@link #AL_FORMAT_STEREO8 FORMAT_STEREO8}</td><td>{@link #AL_FORMAT_STEREO16 FORMAT_STEREO16}</td></tr></table>
|
||||
* @param data the sample data.
|
||||
* @param frequency the data frequency.
|
||||
*/
|
||||
public void alBufferData(int buffer, int format, ByteBuffer data, int size, int frequency);
|
||||
|
||||
/**
|
||||
* Sets the source state to AL_PLAYING.
|
||||
* <p>
|
||||
* <p>alSourcePlay applied to an AL_INITIAL source will promote the source to AL_PLAYING, thus the data found in the buffer will be fed into the processing,
|
||||
* starting at the beginning. alSourcePlay applied to a AL_PLAYING source will restart the source from the beginning. It will not affect the configuration,
|
||||
* and will leave the source in AL_PLAYING state, but reset the sampling offset to the beginning. alSourcePlay applied to a AL_PAUSED source will resume
|
||||
* processing using the source state as preserved at the alSourcePause operation. alSourcePlay applied to a AL_STOPPED source will propagate it to
|
||||
* AL_INITIAL then to AL_PLAYING immediately.</p>
|
||||
*
|
||||
* @param source the source to play.
|
||||
*/
|
||||
public void alSourcePlay(int source);
|
||||
|
||||
/**
|
||||
* Sets the source state to AL_PAUSED.
|
||||
* <p>
|
||||
* <p>alSourcePause applied to an AL_INITIAL source is a legal NOP. alSourcePause applied to a AL_PLAYING source will change its state to AL_PAUSED. The
|
||||
* source is exempt from processing, its current state is preserved. alSourcePause applied to a AL_PAUSED source is a legal NOP. alSourcePause applied to a
|
||||
* AL_STOPPED source is a legal NOP.</p>
|
||||
*
|
||||
* @param source the source to pause.
|
||||
*/
|
||||
public void alSourcePause(int source);
|
||||
|
||||
/**
|
||||
* Sets the float value of a source parameter.
|
||||
*
|
||||
* @param source the source to modify.
|
||||
* @param param the parameter to modify. One of:<br><table><tr><td>{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}</td><td>{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}</td><td>{@link #AL_PITCH PITCH}</td><td>{@link #AL_DIRECTION DIRECTION}</td><td>{@link #AL_LOOPING LOOPING}</td><td>{@link #AL_BUFFER BUFFER}</td><td>{@link #AL_SOURCE_STATE SOURCE_STATE}</td></tr><tr><td>{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}</td><td>{@link #AL_SOURCE_TYPE SOURCE_TYPE}</td><td>{@link #AL_POSITION POSITION}</td><td>{@link #AL_VELOCITY VELOCITY}</td><td>{@link #AL_GAIN GAIN}</td><td>{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}</td><td>{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}</td></tr><tr><td>{@link #AL_MAX_DISTANCE MAX_DISTANCE}</td></tr></table>
|
||||
* @param value the parameter value.
|
||||
*/
|
||||
public void alSourcef(int source, int param, float value);
|
||||
|
||||
/**
|
||||
* Sets the 3 dimensional values of a source parameter.
|
||||
*
|
||||
* @param source the source to modify.
|
||||
* @param param the parameter to modify. One of:<br><table><tr><td>{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}</td><td>{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}</td><td>{@link #AL_PITCH PITCH}</td><td>{@link #AL_DIRECTION DIRECTION}</td><td>{@link #AL_LOOPING LOOPING}</td><td>{@link #AL_BUFFER BUFFER}</td><td>{@link #AL_SOURCE_STATE SOURCE_STATE}</td></tr><tr><td>{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}</td><td>{@link #AL_SOURCE_TYPE SOURCE_TYPE}</td><td>{@link #AL_POSITION POSITION}</td><td>{@link #AL_VELOCITY VELOCITY}</td><td>{@link #AL_GAIN GAIN}</td><td>{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}</td><td>{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}</td></tr><tr><td>{@link #AL_MAX_DISTANCE MAX_DISTANCE}</td></tr></table>
|
||||
* @param value1 the first parameter value.
|
||||
* @param value2 the second parameter value.
|
||||
* @param value3 the third parameter value.
|
||||
*/
|
||||
public void alSource3f(int source, int param, float value1, float value2, float value3);
|
||||
|
||||
/**
|
||||
* Returns the integer value of the specified source parameter.
|
||||
*
|
||||
* @param source the source to query.
|
||||
* @param param the parameter to query. One of:<br><table><tr><td>{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}</td><td>{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}</td><td>{@link #AL_PITCH PITCH}</td><td>{@link #AL_DIRECTION DIRECTION}</td><td>{@link #AL_LOOPING LOOPING}</td><td>{@link #AL_BUFFER BUFFER}</td><td>{@link #AL_SOURCE_STATE SOURCE_STATE}</td></tr><tr><td>{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}</td><td>{@link #AL_SOURCE_TYPE SOURCE_TYPE}</td><td>{@link #AL_POSITION POSITION}</td><td>{@link #AL_VELOCITY VELOCITY}</td><td>{@link #AL_GAIN GAIN}</td><td>{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}</td><td>{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}</td></tr><tr><td>{@link #AL_MAX_DISTANCE MAX_DISTANCE}</td></tr></table>
|
||||
*/
|
||||
public int alGetSourcei(int source, int param);
|
||||
|
||||
/**
|
||||
* Removes a number of buffer entries that have finished processing, in the order of apperance, from the queue of the specified source.
|
||||
* <p>
|
||||
* <p>Once a queue entry for a buffer has been appended to a queue and is pending processing, it should not be changed. Removal of a given queue entry is not
|
||||
* possible unless either the source is stopped (in which case then entire queue is considered processed), or if the queue entry has already been processed
|
||||
* (AL_PLAYING or AL_PAUSED source). A playing source will enter the AL_STOPPED state if it completes playback of the last buffer in its queue (the same
|
||||
* behavior as when a single buffer has been attached to a source and has finished playback).</p>
|
||||
*
|
||||
* @param source the target source
|
||||
* @param numBuffers the names count.
|
||||
* @param buffers the buffer names
|
||||
*/
|
||||
public void alSourceUnqueueBuffers(int source, int numBuffers, IntBuffer buffers);
|
||||
|
||||
/**
|
||||
* Queues up one or multiple buffer names to the specified source.
|
||||
* <p>
|
||||
* <p>The buffers will be queued in the sequence in which they appear in the array. This command is legal on a source in any playback state (to allow for
|
||||
* streaming, queuing has to be possible on a AL_PLAYING source). All buffers in a queue must have the same format and attributes, with the exception of
|
||||
* the {@code NULL} buffer (i.e., 0) which can always be queued.</p>
|
||||
*
|
||||
* @param source the target source.
|
||||
* @param numBuffers the names count.
|
||||
* @param buffers the buffer names.
|
||||
*/
|
||||
public void alSourceQueueBuffers(int source, int numBuffers, IntBuffer buffers);
|
||||
|
||||
/**
|
||||
* Pointer version of {@link #alListenerf Listenerf}.
|
||||
*
|
||||
* @param param the parameter to modify.
|
||||
* @param data the parameter values.
|
||||
*/
|
||||
public void alListener(int param, FloatBuffer data);
|
||||
|
||||
/**
|
||||
* Sets the float value of a listener parameter.
|
||||
*
|
||||
* @param param the parameter to modify. One of:<br><table><tr><td>{@link #AL_ORIENTATION ORIENTATION}</td><td>{@link #AL_POSITION POSITION}</td><td>{@link #AL_VELOCITY VELOCITY}</td><td>{@link #AL_GAIN GAIN}</td></tr></table>
|
||||
* @param value the parameter value.
|
||||
*/
|
||||
public void alListenerf(int param, float value);
|
||||
|
||||
/**
|
||||
* Sets the 3 dimensional float values of a listener parameter.
|
||||
*
|
||||
* @param param the parameter to modify. One of:<br><table><tr><td>{@link #AL_ORIENTATION ORIENTATION}</td><td>{@link #AL_POSITION POSITION}</td><td>{@link #AL_VELOCITY VELOCITY}</td><td>{@link #AL_GAIN GAIN}</td></tr></table>
|
||||
* @param value1 the first value.
|
||||
* @param value2 the second value.
|
||||
* @param value3 the third value.
|
||||
*/
|
||||
public void alListener3f(int param, float value1, float value2, float value3);
|
||||
|
||||
/**
|
||||
* Sets the 3 dimensional integer values of a source parameter.
|
||||
*
|
||||
* @param source the source to modify.
|
||||
* @param param the parameter to modify.
|
||||
* @param value1 the first value.
|
||||
* @param value2 the second value.
|
||||
* @param value3 the third value.
|
||||
*/
|
||||
public void alSource3i(int source, int param, int value1, int value2, int value3);
|
||||
}
|
||||
|
||||
@ -7,67 +7,120 @@ public interface ALC {
|
||||
/**
|
||||
* No error
|
||||
*/
|
||||
static final int ALC_NO_ERROR = 0;
|
||||
public static final int ALC_NO_ERROR = 0;
|
||||
|
||||
/**
|
||||
* No device
|
||||
*/
|
||||
static final int ALC_INVALID_DEVICE = 0xA001;
|
||||
public static final int ALC_INVALID_DEVICE = 0xA001;
|
||||
|
||||
/**
|
||||
* invalid context ID
|
||||
*/
|
||||
static final int ALC_INVALID_CONTEXT = 0xA002;
|
||||
public static final int ALC_INVALID_CONTEXT = 0xA002;
|
||||
|
||||
/**
|
||||
* bad enum
|
||||
*/
|
||||
static final int ALC_INVALID_ENUM = 0xA003;
|
||||
public static final int ALC_INVALID_ENUM = 0xA003;
|
||||
|
||||
/**
|
||||
* bad value
|
||||
*/
|
||||
static final int ALC_INVALID_VALUE = 0xA004;
|
||||
public static final int ALC_INVALID_VALUE = 0xA004;
|
||||
|
||||
/**
|
||||
* Out of memory.
|
||||
*/
|
||||
static final int ALC_OUT_OF_MEMORY = 0xA005;
|
||||
public static final int ALC_OUT_OF_MEMORY = 0xA005;
|
||||
|
||||
/**
|
||||
* The Specifier string for default device
|
||||
*/
|
||||
static final int ALC_DEFAULT_DEVICE_SPECIFIER = 0x1004;
|
||||
static final int ALC_DEVICE_SPECIFIER = 0x1005;
|
||||
static final int ALC_EXTENSIONS = 0x1006;
|
||||
public static final int ALC_DEFAULT_DEVICE_SPECIFIER = 0x1004;
|
||||
public static final int ALC_DEVICE_SPECIFIER = 0x1005;
|
||||
public static final int ALC_EXTENSIONS = 0x1006;
|
||||
|
||||
static final int ALC_MAJOR_VERSION = 0x1000;
|
||||
static final int ALC_MINOR_VERSION = 0x1001;
|
||||
public static final int ALC_MAJOR_VERSION = 0x1000;
|
||||
public static final int ALC_MINOR_VERSION = 0x1001;
|
||||
|
||||
static final int ALC_ATTRIBUTES_SIZE = 0x1002;
|
||||
static final int ALC_ALL_ATTRIBUTES = 0x1003;
|
||||
public static final int ALC_ATTRIBUTES_SIZE = 0x1002;
|
||||
public static final int ALC_ALL_ATTRIBUTES = 0x1003;
|
||||
|
||||
/**
|
||||
* Capture extension
|
||||
*/
|
||||
static final int ALC_CAPTURE_DEVICE_SPECIFIER = 0x310;
|
||||
static final int ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = 0x311;
|
||||
static final int ALC_CAPTURE_SAMPLES = 0x312;
|
||||
public static final int ALC_CAPTURE_DEVICE_SPECIFIER = 0x310;
|
||||
public static final int ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = 0x311;
|
||||
public static final int ALC_CAPTURE_SAMPLES = 0x312;
|
||||
|
||||
/**
|
||||
* ALC_ENUMERATE_ALL_EXT enums
|
||||
*/
|
||||
static final int ALC_DEFAULT_ALL_DEVICES_SPECIFIER = 0x1012;
|
||||
static final int ALC_ALL_DEVICES_SPECIFIER = 0x1013;
|
||||
public static final int ALC_DEFAULT_ALL_DEVICES_SPECIFIER = 0x1012;
|
||||
public static final int ALC_ALL_DEVICES_SPECIFIER = 0x1013;
|
||||
|
||||
//public static ALCCapabilities createCapabilities(long device);
|
||||
|
||||
/**
|
||||
* Creates an AL context.
|
||||
*/
|
||||
public void createALC();
|
||||
|
||||
/**
|
||||
* Destroys an AL context.
|
||||
*/
|
||||
public void destroyALC();
|
||||
|
||||
/**
|
||||
* Checks of creating an AL context.
|
||||
*
|
||||
* @return true if an AL context is created.
|
||||
*/
|
||||
public boolean isCreated();
|
||||
|
||||
/**
|
||||
* Obtains string value(s) from ALC.
|
||||
*
|
||||
* @param parameter the information to query. One of:<br><table><tr><td>{@link #ALC_DEFAULT_DEVICE_SPECIFIER DEFAULT_DEVICE_SPECIFIER}</td><td>{@link #ALC_DEVICE_SPECIFIER DEVICE_SPECIFIER}</td><td>{@link #ALC_EXTENSIONS EXTENSIONS}</td></tr><tr><td>{@link #ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER CAPTURE_DEFAULT_DEVICE_SPECIFIER}</td><td>{@link #ALC_CAPTURE_DEVICE_SPECIFIER CAPTURE_DEVICE_SPECIFIER}</td></tr></table>
|
||||
*/
|
||||
public String alcGetString(int parameter);
|
||||
|
||||
/**
|
||||
* Verifies that a given extension is available for the current context and the device it is associated with.
|
||||
* <p>
|
||||
* <p>Invalid and unsupported string tokens return ALC_FALSE. A {@code NULL} deviceHandle is acceptable. {@code extName} is not case sensitive – the implementation
|
||||
* will convert the name to all upper-case internally (and will express extension names in upper-case).</p>
|
||||
*
|
||||
* @param extension the extension name.
|
||||
*/
|
||||
public boolean alcIsExtensionPresent(String extension);
|
||||
|
||||
/**
|
||||
* Obtains integer value(s) from ALC.
|
||||
*
|
||||
* @param param the information to query. One of:<br><table><tr><td>{@link #ALC_MAJOR_VERSION MAJOR_VERSION}</td><td>{@link #ALC_MINOR_VERSION MINOR_VERSION}</td><td>{@link #ALC_ATTRIBUTES_SIZE ATTRIBUTES_SIZE}</td><td>{@link #ALC_ALL_ATTRIBUTES ALL_ATTRIBUTES}</td><td>{@link #ALC_CAPTURE_SAMPLES CAPTURE_SAMPLES}</td></tr></table>
|
||||
* @param buffer the destination buffer.
|
||||
* @param size the buffer size.
|
||||
*/
|
||||
public void alcGetInteger(int param, IntBuffer buffer, int size);
|
||||
|
||||
/**
|
||||
* Pauses a playback device.
|
||||
* <p>
|
||||
* <p>When paused, no contexts associated with the device will be processed or updated. Playing sources will not produce sound, have their offsets
|
||||
* incremented, or process any more buffers, until the device is resumed. Pausing a device that is already paused is a legal no-op.</p>
|
||||
*/
|
||||
public void alcDevicePauseSOFT();
|
||||
|
||||
/**
|
||||
* Resumes playback of a paused device.
|
||||
* <p>
|
||||
* <p>This will restart processing on the device -- sources will resume playing sound as normal. Resuming playback on a device that is not paused is a legal
|
||||
* no-op.</p>
|
||||
* <p>
|
||||
* <p>These functions are not reference counted. alcDeviceResumeSOFT only needs to be called once to resume playback, regardless of how many times
|
||||
* {@link #alcDevicePauseSOFT DevicePauseSOFT} was called.</p>
|
||||
*/
|
||||
public void alcDeviceResumeSOFT();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -36,14 +36,18 @@ import com.jme3.app.Application;
|
||||
import com.jme3.app.state.AppState;
|
||||
import com.jme3.app.state.AppStateManager;
|
||||
import com.jme3.cinematic.events.AbstractCinematicEvent;
|
||||
import com.jme3.cinematic.events.CameraEvent;
|
||||
import com.jme3.cinematic.events.CinematicEvent;
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.CameraNode;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.control.CameraControl;
|
||||
import com.jme3.scene.control.CameraControl.ControlDirection;
|
||||
import com.jme3.scene.control.Control;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -88,12 +92,12 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Application.class.getName());
|
||||
private static final Logger logger = Logger.getLogger(Cinematic.class.getName());
|
||||
private Node scene;
|
||||
protected TimeLine timeLine = new TimeLine();
|
||||
private int lastFetchedKeyFrame = -1;
|
||||
private List<CinematicEvent> cinematicEvents = new ArrayList<CinematicEvent>();
|
||||
private Map<String, CameraNode> cameras = new HashMap<String, CameraNode>();
|
||||
private List<CinematicEvent> cinematicEvents = new ArrayList<>();
|
||||
private Map<String, CameraNode> cameras = new HashMap<>();
|
||||
private CameraNode currentCam;
|
||||
private boolean initialized = false;
|
||||
private Map<String, Map<Object, Object>> eventsData;
|
||||
@ -104,6 +108,19 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
* directly
|
||||
*/
|
||||
public Cinematic() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Cinematic(float initialDuration) {
|
||||
super(initialDuration);
|
||||
}
|
||||
|
||||
public Cinematic(LoopMode loopMode) {
|
||||
super(loopMode);
|
||||
}
|
||||
|
||||
public Cinematic(float initialDuration, LoopMode loopMode) {
|
||||
super(initialDuration, loopMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,8 +223,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
|
||||
oc.writeSavableArrayList((ArrayList) cinematicEvents, "cinematicEvents", null);
|
||||
oc.write(cinematicEvents.toArray(new CinematicEvent[cinematicEvents.size()]), "cinematicEvents", null);
|
||||
oc.writeStringSavableMap(cameras, "cameras", null);
|
||||
oc.write(timeLine, "timeLine", null);
|
||||
|
||||
@ -224,7 +240,11 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
|
||||
cinematicEvents = ic.readSavableArrayList("cinematicEvents", null);
|
||||
Savable[] events = ic.readSavableArray("cinematicEvents", null);
|
||||
for (Savable c : events) {
|
||||
// addCinematicEvent(((CinematicEvent) c).getTime(), (CinematicEvent) c)
|
||||
cinematicEvents.add((CinematicEvent) c);
|
||||
}
|
||||
cameras = (Map<String, CameraNode>) ic.readStringSavableMap("cameras", null);
|
||||
timeLine = (TimeLine) ic.readSavable("timeLine", null);
|
||||
}
|
||||
@ -244,7 +264,6 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
ce.setSpeed(speed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +277,11 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
for (CinematicEvent cinematicEvent : cinematicEvents) {
|
||||
cinematicEvent.initEvent(app, this);
|
||||
}
|
||||
|
||||
if(!cameras.isEmpty()){
|
||||
for(CameraNode n : cameras.values()){
|
||||
n.setCamera(app.getCamera());
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@ -315,8 +338,9 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
*
|
||||
* @param tpf
|
||||
*/
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
if (isInitialized()) {
|
||||
if (isInitialized() && playState == PlayState.Playing) {
|
||||
internalUpdate(tpf);
|
||||
}
|
||||
}
|
||||
@ -338,13 +362,11 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < cinematicEvents.size(); i++) {
|
||||
CinematicEvent ce = cinematicEvents.get(i);
|
||||
ce.internalUpdate(tpf);
|
||||
}
|
||||
|
||||
|
||||
lastFetchedKeyFrame = keyFrameIndex;
|
||||
}
|
||||
|
||||
@ -386,8 +408,8 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
* Adds a cinematic event to this cinematic at the given timestamp. This
|
||||
* operation returns a keyFrame
|
||||
*
|
||||
* @param timeStamp the time when the event will start after the beginning of
|
||||
* the cinematic
|
||||
* @param timeStamp the time when the event will start after the beginning
|
||||
* of the cinematic
|
||||
* @param cinematicEvent the cinematic event
|
||||
* @return the keyFrame for that event.
|
||||
*/
|
||||
@ -580,39 +602,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
* Cinematic#bindCamera())
|
||||
*/
|
||||
public void activateCamera(final float timeStamp, final String cameraName) {
|
||||
addCinematicEvent(timeStamp, new AbstractCinematicEvent() {
|
||||
@Override
|
||||
public void play() {
|
||||
super.play();
|
||||
stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlay() {
|
||||
setActiveCamera(cameraName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(float tpf) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceStop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTime(float time) {
|
||||
play();
|
||||
}
|
||||
});
|
||||
addCinematicEvent(timeStamp, new CameraEvent(this, cameraName));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -684,6 +674,11 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
|
||||
*/
|
||||
public void setScene(Node scene) {
|
||||
this.scene = scene;
|
||||
if(!cameras.isEmpty()){
|
||||
for(CameraNode n : cameras.values()){
|
||||
this.scene.attachChild(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -43,7 +43,11 @@ import java.util.List;
|
||||
*/
|
||||
public class KeyFrame implements Savable {
|
||||
|
||||
List<CinematicEvent> cinematicEvents = new ArrayList<CinematicEvent>();
|
||||
public KeyFrame(){
|
||||
|
||||
}
|
||||
|
||||
List<CinematicEvent> cinematicEvents = new ArrayList<>();
|
||||
private int index;
|
||||
|
||||
public List<CinematicEvent> getCinematicEvents() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -202,7 +202,7 @@ public class MotionPath implements Savable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Addsa waypoint to the path
|
||||
* Add a waypoint to the path
|
||||
* @param wayPoint a position in world space
|
||||
*/
|
||||
public void addWayPoint(Vector3f wayPoint) {
|
||||
@ -210,7 +210,7 @@ public class MotionPath implements Savable {
|
||||
}
|
||||
|
||||
/**
|
||||
* retruns the length of the path in world units
|
||||
* Return the length of the path in world units
|
||||
* @return the length
|
||||
*/
|
||||
public float getLength() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -34,7 +34,7 @@ package com.jme3.cinematic;
|
||||
import com.jme3.cinematic.events.MotionEvent;
|
||||
|
||||
/**
|
||||
* Trigger the events happening on an motion path
|
||||
* Trigger the events happening on a motion path
|
||||
* @author Nehon
|
||||
*/
|
||||
public interface MotionPathListener {
|
||||
|
||||
@ -41,7 +41,10 @@ import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.util.clone.Cloner;
|
||||
import com.jme3.util.clone.JmeCloneable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@ -80,6 +83,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
* constructors
|
||||
*/
|
||||
public AnimationEvent() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,6 +94,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
*/
|
||||
public AnimationEvent(Spatial model, String animationName) {
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
|
||||
}
|
||||
@ -104,6 +109,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public AnimationEvent(Spatial model, String animationName, float initialDuration) {
|
||||
super(initialDuration);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
}
|
||||
|
||||
@ -119,6 +125,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
super(loopMode);
|
||||
initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
}
|
||||
|
||||
@ -134,6 +141,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public AnimationEvent(Spatial model, String animationName, float initialDuration, LoopMode loopMode) {
|
||||
super(initialDuration, loopMode);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
}
|
||||
|
||||
@ -149,6 +157,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public AnimationEvent(Spatial model, String animationName, float initialDuration, float blendTime) {
|
||||
super(initialDuration);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.blendTime = blendTime;
|
||||
}
|
||||
@ -167,6 +176,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
super(loopMode);
|
||||
initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.blendTime = blendTime;
|
||||
}
|
||||
@ -185,6 +195,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public AnimationEvent(Spatial model, String animationName, float initialDuration, LoopMode loopMode, float blendTime) {
|
||||
super(initialDuration, loopMode);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.blendTime = blendTime;
|
||||
}
|
||||
@ -203,6 +214,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
super(loopMode);
|
||||
initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.channelIndex = channelIndex;
|
||||
}
|
||||
@ -217,6 +229,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
*/
|
||||
public AnimationEvent(Spatial model, String animationName, int channelIndex) {
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
|
||||
this.channelIndex = channelIndex;
|
||||
@ -233,6 +246,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
*/
|
||||
public AnimationEvent(Spatial model, String animationName, LoopMode loopMode, int channelIndex, float blendTime) {
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.loopMode = loopMode;
|
||||
initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
|
||||
@ -252,6 +266,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public AnimationEvent(Spatial model, String animationName, float initialDuration, int channelIndex) {
|
||||
super(initialDuration);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.channelIndex = channelIndex;
|
||||
}
|
||||
@ -270,6 +285,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public AnimationEvent(Spatial model, String animationName, float initialDuration, LoopMode loopMode, int channelIndex) {
|
||||
super(initialDuration, loopMode);
|
||||
this.model = model;
|
||||
this.modelName = model.getName();
|
||||
this.animationName = animationName;
|
||||
this.channelIndex = channelIndex;
|
||||
}
|
||||
@ -299,6 +315,18 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
model = cinematic.getScene().getChild(modelName);
|
||||
}
|
||||
if (model != null) {
|
||||
if(cinematic.getScene() != null){
|
||||
Spatial sceneModel = cinematic.getScene().getChild(model.getName());
|
||||
if(sceneModel != null){
|
||||
Node parent = sceneModel.getParent();
|
||||
parent.detachChild(sceneModel);
|
||||
sceneModel = model;
|
||||
parent.attachChild(sceneModel);
|
||||
} else {
|
||||
cinematic.getScene().attachChild(model);
|
||||
}
|
||||
}
|
||||
|
||||
channel = model.getControl(AnimControl.class).createChannel();
|
||||
map.put(channelIndex, channel);
|
||||
} else {
|
||||
@ -401,6 +429,7 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
|
||||
oc.write(model, "model", null);
|
||||
oc.write(modelName, "modelName", null);
|
||||
oc.write(animationName, "animationName", "");
|
||||
oc.write(blendTime, "blendTime", 0f);
|
||||
oc.write(channelIndex, "channelIndex", 0);
|
||||
@ -411,9 +440,9 @@ public class AnimationEvent extends AbstractCinematicEvent {
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
if (im.getFormatVersion() == 0) {
|
||||
// if (im.getFormatVersion() == 0) {
|
||||
modelName = ic.readString("modelName", "");
|
||||
}
|
||||
// }
|
||||
//FIXME always the same issue, because of the clonning of assets, this won't work
|
||||
//we have to somehow store userdata in the spatial and then recurse the
|
||||
//scene sub scenegraph to find the correct instance of the model
|
||||
|
||||
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2017 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* 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.cinematic.events;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.cinematic.Cinematic;
|
||||
import com.jme3.cinematic.TimeLine;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.export.Savable;
|
||||
import com.jme3.scene.CameraNode;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rickard <neph1 @ github>
|
||||
*/
|
||||
public class CameraEvent extends AbstractCinematicEvent{
|
||||
|
||||
private String cameraName;
|
||||
private Cinematic cinematic;
|
||||
|
||||
public String getCameraName() {
|
||||
return cameraName;
|
||||
}
|
||||
|
||||
public void setCameraName(String cameraName) {
|
||||
this.cameraName = cameraName;
|
||||
}
|
||||
|
||||
public CameraEvent(){
|
||||
|
||||
}
|
||||
|
||||
public CameraEvent(Cinematic parentEvent, String cameraName){
|
||||
this.cinematic = parentEvent;
|
||||
this.cameraName = cameraName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initEvent(Application app, Cinematic cinematic) {
|
||||
super.initEvent(app, cinematic);
|
||||
this.cinematic = cinematic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play() {
|
||||
super.play();
|
||||
stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlay() {
|
||||
cinematic.setActiveCamera(cameraName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(float tpf) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceStop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTime(float time) {
|
||||
play();
|
||||
}
|
||||
|
||||
public Cinematic getCinematic() {
|
||||
return cinematic;
|
||||
}
|
||||
|
||||
public void setCinematic(Cinematic cinematic) {
|
||||
this.cinematic = cinematic;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* used internally for serialization
|
||||
*
|
||||
* @param ex
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(cameraName, "cameraName", null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* used internally for serialization
|
||||
*
|
||||
* @param im
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void read(JmeImporter im) throws IOException {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
cameraName = ic.readString("cameraName", null);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2016 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -274,23 +274,10 @@ public class MotionEvent extends AbstractCinematicEvent implements Control, JmeC
|
||||
* @param spatial
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
MotionEvent control = new MotionEvent();
|
||||
control.setPath(path);
|
||||
control.playState = playState;
|
||||
control.currentWayPoint = currentWayPoint;
|
||||
control.currentValue = currentValue;
|
||||
control.direction = direction.clone();
|
||||
control.lookAt = lookAt;
|
||||
control.upVector = upVector.clone();
|
||||
control.rotation = rotation;
|
||||
control.initialDuration = initialDuration;
|
||||
control.speed = speed;
|
||||
control.loopMode = loopMode;
|
||||
control.directionType = directionType;
|
||||
|
||||
return control;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -147,6 +147,7 @@ public class SoundEvent extends AbstractCinematicEvent {
|
||||
* used for serialization
|
||||
*/
|
||||
public SoundEvent() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -217,7 +217,7 @@ class SweepSphere implements Collidable {
|
||||
|
||||
float signedDistanceToPlane = triPlane.pseudoDistance(sCenter);
|
||||
if (normalDotVelocity == 0.0f){
|
||||
// we are travelling exactly parrallel to the plane
|
||||
// we are travelling exactly parallel to the plane
|
||||
if (FastMath.abs(signedDistanceToPlane) >= 1.0f){
|
||||
// no collision possible
|
||||
return null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -121,10 +121,10 @@ public class ParticleEmitter extends Geometry {
|
||||
this.parentEmitter = parentEmitter;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
return this; // WARNING: Sets wrong control on spatial. Will be
|
||||
// fixed automatically by ParticleEmitter.clone() method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -384,7 +384,7 @@ public class ParticleEmitter extends Geometry {
|
||||
* Set to true if particles should spawn in world space.
|
||||
*
|
||||
* <p>If set to true and the particle emitter is moved in the scene,
|
||||
* then particles that have already spawned won't be effected by this
|
||||
* then particles that have already spawned won't be affected by this
|
||||
* motion. If set to false, the particles will emit in local space
|
||||
* and when the emitter is moved, so are all the particles that
|
||||
* were emitted previously.
|
||||
@ -846,7 +846,7 @@ public class ParticleEmitter extends Geometry {
|
||||
* @param initialVelocity Set the initial velocity a particle is spawned with,
|
||||
* the initial velocity given in the parameter will be varied according
|
||||
* to the velocity variation set in {@link ParticleEmitter#setVelocityVariation(float) }.
|
||||
* A particle will move toward its velocity unless it is effected by the
|
||||
* The particle will move with this velocity unless it is affected by
|
||||
* gravity.
|
||||
*
|
||||
* @deprecated
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -64,7 +64,7 @@ public interface ParticleInfluencer extends Savable, Cloneable, JmeCloneable {
|
||||
* Set the initial velocity a particle is spawned with,
|
||||
* the initial velocity given in the parameter will be varied according
|
||||
* to the velocity variation set in {@link ParticleEmitter#setVelocityVariation(float) }.
|
||||
* A particle will move toward its velocity unless it is effected by the
|
||||
* The particle will move with this velocity unless it is affected by
|
||||
* gravity.
|
||||
*/
|
||||
void setInitialVelocity(Vector3f initialVelocity);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -37,7 +37,7 @@ import com.jme3.scene.Mesh;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This emiter shape emits the particles from the given shape's interior constrained by its convex hull
|
||||
* This emitter shape emits the particles from the given shape's interior constrained by its convex hull
|
||||
* (a geometry that tightly wraps the mesh). So in case of multiple meshes some vertices may appear
|
||||
* in a space between them.
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -40,7 +40,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This emiter shape emits the particles from the given shape's faces.
|
||||
* This emitter shape emits the particles from the given shape's faces.
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
public class EmitterMeshFaceShape extends EmitterMeshVertexShape {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -50,7 +50,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* This emiter shape emits the particles from the given shape's vertices
|
||||
* This emitter shape emits the particles from the given shape's vertices
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
public class EmitterMeshVertexShape implements EmitterShape {
|
||||
@ -74,7 +74,7 @@ public class EmitterMeshVertexShape implements EmitterShape {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the meshes that will form the emiter's shape.
|
||||
* This method sets the meshes that will form the emitter's shape.
|
||||
* @param meshes
|
||||
* a list of meshes that will form the emitter's shape
|
||||
*/
|
||||
|
||||
@ -96,10 +96,12 @@ public class EmitterSphereShape implements EmitterShape {
|
||||
@Override
|
||||
public void getRandomPoint(Vector3f store) {
|
||||
do {
|
||||
store.x = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
|
||||
store.y = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
|
||||
store.z = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
|
||||
} while (store.distance(center) > radius);
|
||||
store.x = (FastMath.nextRandomFloat() * 2f - 1f);
|
||||
store.y = (FastMath.nextRandomFloat() * 2f - 1f);
|
||||
store.z = (FastMath.nextRandomFloat() * 2f - 1f);
|
||||
} while (store.lengthSquared() > 1);
|
||||
store.multLocal(radius);
|
||||
store.addLocal(center);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -48,6 +48,7 @@ import com.jme3.texture.Texture2D;
|
||||
import com.jme3.texture.TextureCubeMap;
|
||||
import com.jme3.texture.image.ColorSpace;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.MipMapGenerator;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
@ -72,6 +73,8 @@ public class EnvironmentCamera extends BaseAppState {
|
||||
|
||||
protected Image.Format imageFormat = Image.Format.RGB16F;
|
||||
|
||||
public TextureCubeMap debugEnv;
|
||||
|
||||
//Axis for cameras
|
||||
static {
|
||||
//PositiveX axis(left, up, direction)
|
||||
@ -188,10 +191,11 @@ public class EnvironmentCamera extends BaseAppState {
|
||||
buffers[i] = BufferUtils.createByteBuffer(size * size * imageFormat.getBitsPerPixel() / 8);
|
||||
renderManager.getRenderer().readFrameBufferWithFormat(framebuffers[i], buffers[i], imageFormat);
|
||||
images[i] = new Image(imageFormat, size, size, buffers[i], ColorSpace.Linear);
|
||||
MipMapGenerator.generateMipMaps(images[i]);
|
||||
}
|
||||
|
||||
final TextureCubeMap map = EnvMapUtils.makeCubeMap(images[0], images[1], images[2], images[3], images[4], images[5], imageFormat);
|
||||
|
||||
debugEnv = map;
|
||||
job.callback.done(map);
|
||||
map.getImage().dispose();
|
||||
jobs.remove(0);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,13 +31,14 @@
|
||||
*/
|
||||
package com.jme3.environment;
|
||||
|
||||
import com.jme3.environment.generation.*;
|
||||
import com.jme3.light.LightProbe;
|
||||
import com.jme3.environment.util.EnvMapUtils;
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.environment.generation.*;
|
||||
import com.jme3.environment.util.EnvMapUtils;
|
||||
import com.jme3.light.LightProbe;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.texture.TextureCubeMap;
|
||||
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
@ -46,7 +47,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
* Since the process can be long, you can provide a JobProgressListener that
|
||||
* will be notified of the ongoing generation process when calling the makeProbe method.
|
||||
*
|
||||
* The process is the folowing :
|
||||
* The process is as follows:
|
||||
* 1. Create an EnvironmentCamera
|
||||
* 2. give it a position in the scene
|
||||
* 3. call {@link LightProbeFactory#makeProbe(com.jme3.environment.EnvironmentCamera, com.jme3.scene.Node)}
|
||||
@ -60,7 +61,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
* This class is entirely thread safe and can be called from any thread.
|
||||
*
|
||||
* Note that in case you are using a {@link JobProgressListener} all the its
|
||||
* method will be called inside and app.enqueu callable.
|
||||
* method will be called inside and app.enqueue callable.
|
||||
* This means that it's completely safe to modify the scenegraph within the
|
||||
* Listener method, but also means that the even will be delayed until next update loop.
|
||||
*
|
||||
@ -72,7 +73,7 @@ public class LightProbeFactory {
|
||||
/**
|
||||
* Creates a LightProbe with the giver EnvironmentCamera in the given scene.
|
||||
*
|
||||
* Note that this is an assynchronous process that will run on multiple threads.
|
||||
* Note that this is an asynchronous process that will run on multiple threads.
|
||||
* The process is thread safe.
|
||||
* The created lightProbe will only be marked as ready when the rendering process is done.
|
||||
*
|
||||
@ -93,7 +94,7 @@ public class LightProbeFactory {
|
||||
/**
|
||||
* Creates a LightProbe with the giver EnvironmentCamera in the given scene.
|
||||
*
|
||||
* Note that this is an assynchronous process that will run on multiple threads.
|
||||
* Note that this is an asynchronous process that will run on multiple threads.
|
||||
* The process is thread safe.
|
||||
* The created lightProbe will only be marked as ready when the rendering process is done.
|
||||
*
|
||||
@ -106,10 +107,11 @@ public class LightProbeFactory {
|
||||
|
||||
* @param envCam the EnvironmentCamera
|
||||
* @param scene the Scene
|
||||
* @param listener the listener of the genration progress.
|
||||
* @param genType Fast or HighQuality. Fast may be ok for many types of environment, but you may need high quality when an environment map has very high lighting values.
|
||||
* @param listener the listener of the generation progress.
|
||||
* @return the created LightProbe
|
||||
*/
|
||||
public static LightProbe makeProbe(final EnvironmentCamera envCam, Spatial scene, final JobProgressListener<LightProbe> listener) {
|
||||
public static LightProbe makeProbe(final EnvironmentCamera envCam, Spatial scene, final EnvMapUtils.GenerationType genType, final JobProgressListener<LightProbe> listener) {
|
||||
final LightProbe probe = new LightProbe();
|
||||
probe.setPosition(envCam.getPosition());
|
||||
probe.setPrefilteredMap(EnvMapUtils.createPrefilteredEnvMap(envCam.getSize(), envCam.getImageFormat()));
|
||||
@ -117,33 +119,37 @@ public class LightProbeFactory {
|
||||
|
||||
@Override
|
||||
public void done(TextureCubeMap map) {
|
||||
generatePbrMaps(map, probe, envCam.getApplication(), listener);
|
||||
generatePbrMaps(map, probe, envCam.getApplication(), genType, listener);
|
||||
}
|
||||
});
|
||||
return probe;
|
||||
}
|
||||
|
||||
public static LightProbe makeProbe(final EnvironmentCamera envCam, Spatial scene, final JobProgressListener<LightProbe> listener) {
|
||||
return makeProbe(envCam, scene, EnvMapUtils.GenerationType.Fast, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a LightProbe with the giver EnvironmentCamera in the given scene.
|
||||
*
|
||||
* Note that this is an assynchronous process that will run on multiple threads.
|
||||
* Updates a LightProbe with the given EnvironmentCamera in the given scene.
|
||||
* <p>
|
||||
* Note that this is an asynchronous process that will run on multiple threads.
|
||||
* The process is thread safe.
|
||||
* The created lightProbe will only be marked as ready when the rendering process is done.
|
||||
*
|
||||
* <p>
|
||||
* The JobProgressListener will be notified of the progress of the generation.
|
||||
* Note that you can also use a {@link JobProgressAdapter}.
|
||||
*
|
||||
* @see LightProbe
|
||||
* @see EnvironmentCamera
|
||||
* @see JobProgressListener
|
||||
*
|
||||
* @param probe the Light probe to update
|
||||
* @param envCam the EnvironmentCamera
|
||||
* @param scene the Scene
|
||||
* @param listener the listener of the genration progress.
|
||||
* @param genType Fast or HighQuality. Fast may be ok for many types of environment, but you may need high quality when an environment map has very high lighting values.
|
||||
* @param listener the listener of the generation progress.
|
||||
* @return the created LightProbe
|
||||
* @see LightProbe
|
||||
* @see EnvironmentCamera
|
||||
* @see JobProgressListener
|
||||
*/
|
||||
public static LightProbe updateProbe(final LightProbe probe, final EnvironmentCamera envCam, Spatial scene, final JobProgressListener<LightProbe> listener) {
|
||||
public static LightProbe updateProbe(final LightProbe probe, final EnvironmentCamera envCam, Spatial scene, final EnvMapUtils.GenerationType genType, final JobProgressListener<LightProbe> listener) {
|
||||
|
||||
envCam.setPosition(probe.getPosition());
|
||||
|
||||
@ -159,23 +165,27 @@ public class LightProbeFactory {
|
||||
|
||||
@Override
|
||||
public void done(TextureCubeMap map) {
|
||||
generatePbrMaps(map, probe, envCam.getApplication(), listener);
|
||||
generatePbrMaps(map, probe, envCam.getApplication(), genType, listener);
|
||||
}
|
||||
});
|
||||
return probe;
|
||||
}
|
||||
|
||||
public static LightProbe updateProbe(final LightProbe probe, final EnvironmentCamera envCam, Spatial scene, final JobProgressListener<LightProbe> listener) {
|
||||
return updateProbe(probe, envCam, scene, EnvMapUtils.GenerationType.Fast, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internally called to generate the maps.
|
||||
* This method will spawn 7 thread (one for the Irradiance spherical harmonics generator, and one for each face of the prefiltered env map).
|
||||
* Those threads will be executed in a ScheduledThreadPoolExecutor that will be shutdown when the genration is done.
|
||||
* Those threads will be executed in a ScheduledThreadPoolExecutor that will be shutdown when the generation is done.
|
||||
*
|
||||
* @param envMap the raw env map rendered by the env camera
|
||||
* @param probe the LigthProbe to generate maps for
|
||||
* @param probe the LightProbe to generate maps for
|
||||
* @param app the Application
|
||||
* @param listener a progress listener. (can be null if no progress reporting is needed)
|
||||
*/
|
||||
private static void generatePbrMaps(TextureCubeMap envMap, final LightProbe probe, Application app, final JobProgressListener<LightProbe> listener) {
|
||||
private static void generatePbrMaps(TextureCubeMap envMap, final LightProbe probe, Application app, EnvMapUtils.GenerationType genType, final JobProgressListener<LightProbe> listener) {
|
||||
IrradianceSphericalHarmonicsGenerator irrShGenerator;
|
||||
PrefilteredEnvMapFaceGenerator[] pemGenerators = new PrefilteredEnvMapFaceGenerator[6];
|
||||
|
||||
@ -189,7 +199,7 @@ public class LightProbeFactory {
|
||||
|
||||
for (int i = 0; i < pemGenerators.length; i++) {
|
||||
pemGenerators[i] = new PrefilteredEnvMapFaceGenerator(app, i, new JobListener(listener, jobState, probe, i));
|
||||
pemGenerators[i].setGenerationParam(EnvMapUtils.duplicateCubeMap(envMap), size, EnvMapUtils.FixSeamsMethod.None, probe.getPrefilteredEnvMap());
|
||||
pemGenerators[i].setGenerationParam(EnvMapUtils.duplicateCubeMap(envMap), size, EnvMapUtils.FixSeamsMethod.None, genType, probe.getPrefilteredEnvMap());
|
||||
jobState.executor.execute(pemGenerators[i]);
|
||||
}
|
||||
}
|
||||
@ -227,7 +237,7 @@ public class LightProbeFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* An inner JobProgressListener to controll the genration process and properly clean up when it's done
|
||||
* An inner JobProgressListener to control the generation process and properly clean up when it's done
|
||||
*/
|
||||
private static class JobListener extends JobProgressAdapter<Integer> {
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -73,7 +73,7 @@ public class IrradianceSphericalHarmonicsGenerator extends RunnableWithProgress
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills all the genration parameters
|
||||
* Fills all the generation parameters
|
||||
*
|
||||
* @param sourceMap the source cube map
|
||||
* {@link EnvMapUtils.FixSeamsMethod}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,30 +31,22 @@
|
||||
*/
|
||||
package com.jme3.environment.generation;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.environment.util.CubeMapWrapper;
|
||||
import com.jme3.environment.util.EnvMapUtils;
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.math.*;
|
||||
|
||||
import static com.jme3.math.FastMath.abs;
|
||||
import static com.jme3.math.FastMath.clamp;
|
||||
import static com.jme3.math.FastMath.pow;
|
||||
import static com.jme3.math.FastMath.sqrt;
|
||||
|
||||
import com.jme3.texture.TextureCubeMap;
|
||||
|
||||
import static com.jme3.environment.util.EnvMapUtils.getHammersleyPoint;
|
||||
import static com.jme3.environment.util.EnvMapUtils.getRoughnessFromMip;
|
||||
import static com.jme3.environment.util.EnvMapUtils.getSampleFromMip;
|
||||
import static com.jme3.environment.util.EnvMapUtils.getVectorFromCubemapFaceTexCoord;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.jme3.environment.util.EnvMapUtils.*;
|
||||
import static com.jme3.math.FastMath.abs;
|
||||
import static com.jme3.math.FastMath.sqrt;
|
||||
|
||||
/**
|
||||
* Generates one face of the prefiltered environnement map for PBR. This job can
|
||||
* be lauched from a separate thread.
|
||||
* Generates one face of the prefiltered environment map for PBR. This job can
|
||||
* be launched from a separate thread.
|
||||
* <p>
|
||||
* TODO there is a lot of duplicate code here with the EnvMapUtils.
|
||||
*
|
||||
@ -69,6 +61,7 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
|
||||
private int targetMapSize;
|
||||
private EnvMapUtils.FixSeamsMethod fixSeamsMethod;
|
||||
private EnvMapUtils.GenerationType genType;
|
||||
private TextureCubeMap sourceMap;
|
||||
private TextureCubeMap store;
|
||||
private final Application app;
|
||||
@ -98,7 +91,7 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
|
||||
|
||||
/**
|
||||
* Fills all the genration parameters
|
||||
* Fills all the generation parameters
|
||||
*
|
||||
* @param sourceMap the source cube map
|
||||
* @param targetMapSize the size of the generated map (width or height in
|
||||
@ -107,11 +100,12 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
* {@link EnvMapUtils.FixSeamsMethod}
|
||||
* @param store The cube map to store the result in.
|
||||
*/
|
||||
public void setGenerationParam(TextureCubeMap sourceMap, int targetMapSize, EnvMapUtils.FixSeamsMethod fixSeamsMethod, TextureCubeMap store) {
|
||||
public void setGenerationParam(TextureCubeMap sourceMap, int targetMapSize, EnvMapUtils.FixSeamsMethod fixSeamsMethod, EnvMapUtils.GenerationType genType, TextureCubeMap store) {
|
||||
this.sourceMap = sourceMap;
|
||||
this.targetMapSize = targetMapSize;
|
||||
this.fixSeamsMethod = fixSeamsMethod;
|
||||
this.store = store;
|
||||
this.genType = genType;
|
||||
init();
|
||||
}
|
||||
|
||||
@ -162,12 +156,16 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
* @return The irradiance cube map for the given coefficients
|
||||
*/
|
||||
private TextureCubeMap generatePrefilteredEnvMap(TextureCubeMap sourceEnvMap, int targetMapSize, EnvMapUtils.FixSeamsMethod fixSeamsMethod, TextureCubeMap store) {
|
||||
try {
|
||||
TextureCubeMap pem = store;
|
||||
|
||||
int nbMipMap = (int) (Math.log(targetMapSize) / Math.log(2) - 1);
|
||||
int nbMipMap = store.getImage().getMipMapSizes().length;
|
||||
|
||||
setEnd(nbMipMap);
|
||||
|
||||
if (!sourceEnvMap.getImage().hasMipmaps() || sourceEnvMap.getImage().getMipMapSizes().length < nbMipMap) {
|
||||
throw new IllegalArgumentException("The input cube map must have at least " + nbMipMap + "mip maps");
|
||||
}
|
||||
|
||||
CubeMapWrapper sourceWrapper = new CubeMapWrapper(sourceEnvMap);
|
||||
CubeMapWrapper targetWrapper = new CubeMapWrapper(pem);
|
||||
@ -175,55 +173,88 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
Vector3f texelVect = new Vector3f();
|
||||
Vector3f color = new Vector3f();
|
||||
ColorRGBA outColor = new ColorRGBA();
|
||||
int targetMipMapSize = targetMapSize;
|
||||
for (int mipLevel = 0; mipLevel < nbMipMap; mipLevel++) {
|
||||
float roughness = getRoughnessFromMip(mipLevel, nbMipMap);
|
||||
int nbSamples = getSampleFromMip(mipLevel, nbMipMap);
|
||||
int targetMipMapSize = (int) pow(2, nbMipMap + 1 - mipLevel);
|
||||
|
||||
for (int y = 0; y < targetMipMapSize; y++) {
|
||||
for (int x = 0; x < targetMipMapSize; x++) {
|
||||
color.set(0, 0, 0);
|
||||
getVectorFromCubemapFaceTexCoord(x, y, targetMipMapSize, face, texelVect, fixSeamsMethod);
|
||||
prefilterEnvMapTexel(sourceWrapper, roughness, texelVect, nbSamples, color);
|
||||
prefilterEnvMapTexel(sourceWrapper, roughness, texelVect, nbSamples, mipLevel, color);
|
||||
|
||||
outColor.set(Math.max(color.x, 0.0001f), Math.max(color.y, 0.0001f), Math.max(color.z, 0.0001f), 1);
|
||||
log.log(Level.FINE, "coords {0},{1}", new Object[]{x, y});
|
||||
targetWrapper.setPixel(x, y, face, mipLevel, outColor);
|
||||
|
||||
}
|
||||
}
|
||||
targetMipMapSize /= 2;
|
||||
progress();
|
||||
}
|
||||
|
||||
return pem;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3f prefilterEnvMapTexel(CubeMapWrapper envMapReader, float roughness, Vector3f N, int numSamples, Vector3f store) {
|
||||
private Vector3f prefilterEnvMapTexel(CubeMapWrapper envMapReader, float roughness, Vector3f N, int numSamples, int mipLevel, Vector3f store) {
|
||||
|
||||
Vector3f prefilteredColor = store;
|
||||
float totalWeight = 0.0f;
|
||||
|
||||
int nbRotations = 1;
|
||||
if (genType == GenerationType.HighQuality) {
|
||||
nbRotations = numSamples == 1 ? 1 : 18;
|
||||
}
|
||||
|
||||
float rad = 2f * FastMath.PI / (float) nbRotations;
|
||||
// offset rotation to avoid sampling pattern
|
||||
float gi = (float) (FastMath.abs(N.z + N.x) * 256.0);
|
||||
float offset = rad * (FastMath.cos((gi * 0.5f) % (2f * FastMath.PI)) * 0.5f + 0.5f);
|
||||
|
||||
// a = roughness² and a2 = a²
|
||||
float a2 = roughness * roughness;
|
||||
a2 *= a2;
|
||||
|
||||
//Computing tangent frame
|
||||
Vector3f upVector = Vector3f.UNIT_X;
|
||||
if (abs(N.z) < 0.999) {
|
||||
upVector = Vector3f.UNIT_Y;
|
||||
}
|
||||
Vector3f tangentX = tmp1.set(upVector).crossLocal(N).normalizeLocal();
|
||||
Vector3f tangentY = tmp2.set(N).crossLocal(tangentX);
|
||||
|
||||
// https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
|
||||
// in local space view == normal == 0,0,1
|
||||
Vector3f V = new Vector3f(0, 0, 1);
|
||||
|
||||
Vector3f lWorld = new Vector3f();
|
||||
for (int i = 0; i < numSamples; i++) {
|
||||
Xi = getHammersleyPoint(i, numSamples, Xi);
|
||||
H = importanceSampleGGX(Xi, a2, N, H);
|
||||
|
||||
H = importanceSampleGGX(Xi, a2, H);
|
||||
H.normalizeLocal();
|
||||
tmp.set(H);
|
||||
float NoH = N.dot(tmp);
|
||||
float VoH = H.z;
|
||||
Vector3f L = H.multLocal(VoH * 2f).subtractLocal(V);
|
||||
float NoL = L.z;
|
||||
|
||||
Vector3f L = tmp.multLocal(NoH * 2).subtractLocal(N);
|
||||
float NoL = clamp(N.dot(L), 0.0f, 1.0f);
|
||||
if (NoL > 0) {
|
||||
envMapReader.getPixel(L, c);
|
||||
prefilteredColor.setX(prefilteredColor.x + c.r * NoL);
|
||||
prefilteredColor.setY(prefilteredColor.y + c.g * NoL);
|
||||
prefilteredColor.setZ(prefilteredColor.z + c.b * NoL);
|
||||
|
||||
totalWeight += NoL;
|
||||
float computedMipLevel = mipLevel;
|
||||
if (mipLevel != 0) {
|
||||
computedMipLevel = computeMipLevel(roughness, numSamples, this.targetMapSize, VoH);
|
||||
}
|
||||
|
||||
toWorld(L, N, tangentX, tangentY, lWorld);
|
||||
totalWeight += samplePixel(envMapReader, lWorld, NoL, computedMipLevel, prefilteredColor);
|
||||
|
||||
for (int j = 1; j < nbRotations; j++) {
|
||||
rotateDirection(offset + j * rad, L, lWorld);
|
||||
L.set(lWorld);
|
||||
toWorld(L, N, tangentX, tangentY, lWorld);
|
||||
totalWeight += samplePixel(envMapReader, lWorld, NoL, computedMipLevel, prefilteredColor);
|
||||
}
|
||||
|
||||
}
|
||||
if (totalWeight > 0) {
|
||||
prefilteredColor.divideLocal(totalWeight);
|
||||
@ -232,7 +263,78 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
return prefilteredColor;
|
||||
}
|
||||
|
||||
public Vector3f importanceSampleGGX(Vector4f xi, float a2, Vector3f normal, Vector3f store) {
|
||||
private float samplePixel(CubeMapWrapper envMapReader, Vector3f lWorld, float NoL, float computedMipLevel, Vector3f store) {
|
||||
|
||||
if (NoL <= 0) {
|
||||
return 0;
|
||||
}
|
||||
envMapReader.getPixel(lWorld, computedMipLevel, c);
|
||||
store.setX(store.x + c.r * NoL);
|
||||
store.setY(store.y + c.g * NoL);
|
||||
store.setZ(store.z + c.b * NoL);
|
||||
|
||||
return NoL;
|
||||
}
|
||||
|
||||
private void toWorld(Vector3f L, Vector3f N, Vector3f tangentX, Vector3f tangentY, Vector3f store) {
|
||||
store.set(tangentX).multLocal(L.x);
|
||||
tmp.set(tangentY).multLocal(L.y);
|
||||
store.addLocal(tmp);
|
||||
tmp.set(N).multLocal(L.z);
|
||||
store.addLocal(tmp);
|
||||
}
|
||||
|
||||
private float computeMipLevel(float roughness, int numSamples, float size, float voH) {
|
||||
// H[2] is NoH in local space
|
||||
// adds 1.e-5 to avoid ggx / 0.0
|
||||
float NoH = voH + 1E-5f;
|
||||
|
||||
// Probability Distribution Function
|
||||
float Pdf = ggx(NoH, roughness) * NoH / (4.0f * voH);
|
||||
|
||||
// Solid angle represented by this sample
|
||||
float omegaS = 1.0f / (numSamples * Pdf);
|
||||
|
||||
// Solid angle covered by 1 pixel with 6 faces that are EnvMapSize X EnvMapSize
|
||||
float omegaP = 4.0f * FastMath.PI / (6.0f * size * size);
|
||||
|
||||
// Original paper suggest biasing the mip to improve the results
|
||||
float mipBias = 1.0f; // I tested that the result is better with bias 1
|
||||
double maxLod = Math.log(size) / Math.log(2f);
|
||||
double log2 = Math.log(omegaS / omegaP) / Math.log(2);
|
||||
return Math.min(Math.max(0.5f * (float) log2 + mipBias, 0.0f), (float) maxLod);
|
||||
}
|
||||
|
||||
|
||||
private float ggx(float NoH, float alpha) {
|
||||
// use GGX / Trowbridge-Reitz, same as Disney and Unreal 4
|
||||
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p3
|
||||
float tmp = alpha / (NoH * NoH * (alpha * alpha - 1.0f) + 1.0f);
|
||||
return tmp * tmp * (1f / FastMath.PI);
|
||||
}
|
||||
|
||||
private Vector3f rotateDirection(float angle, Vector3f l, Vector3f store) {
|
||||
float s, c, t;
|
||||
|
||||
s = FastMath.sin(angle);
|
||||
c = FastMath.cos(angle);
|
||||
t = 1.f - c;
|
||||
|
||||
store.x = l.x * c + l.y * s;
|
||||
store.y = -l.x * s + l.y * c;
|
||||
store.z = l.z * (t + c);
|
||||
return store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes GGX half vector in local space
|
||||
*
|
||||
* @param xi
|
||||
* @param a2
|
||||
* @param store
|
||||
* @return
|
||||
*/
|
||||
public Vector3f importanceSampleGGX(Vector4f xi, float a2, Vector3f store) {
|
||||
if (store == null) {
|
||||
store = new Vector3f();
|
||||
}
|
||||
@ -243,22 +345,9 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
|
||||
float sinThetaCosPhi = sinTheta * xi.z;//xi.z is cos(phi)
|
||||
float sinThetaSinPhi = sinTheta * xi.w;//xi.w is sin(phi)
|
||||
|
||||
Vector3f upVector = Vector3f.UNIT_X;
|
||||
|
||||
if (abs(normal.z) < 0.999) {
|
||||
upVector = Vector3f.UNIT_Y;
|
||||
}
|
||||
|
||||
Vector3f tangentX = tmp1.set(upVector).crossLocal(normal).normalizeLocal();
|
||||
Vector3f tangentY = tmp2.set(normal).crossLocal(tangentX);
|
||||
|
||||
// Tangent to world space
|
||||
tangentX.multLocal(sinThetaCosPhi);
|
||||
tangentY.multLocal(sinThetaSinPhi);
|
||||
tmp3.set(normal).multLocal(cosTheta);
|
||||
|
||||
// Tangent to world space
|
||||
store.set(tangentX).addLocal(tangentY).addLocal(tmp3);
|
||||
store.x = sinThetaCosPhi;
|
||||
store.y = sinThetaSinPhi;
|
||||
store.z = cosTheta;
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -61,7 +61,7 @@ public abstract class RunnableWithProgress implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* return the curent progress of the process.
|
||||
* return the current progress of the process.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@ -31,17 +31,15 @@
|
||||
*/
|
||||
package com.jme3.environment.util;
|
||||
|
||||
import com.jme3.environment.util.EnvMapUtils;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import static com.jme3.math.FastMath.pow;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.TextureCubeMap;
|
||||
import com.jme3.texture.image.DefaultImageRaster;
|
||||
import com.jme3.texture.image.MipMapImageRaster;
|
||||
import com.jme3.util.BufferUtils;
|
||||
|
||||
import static com.jme3.math.FastMath.pow;
|
||||
|
||||
/**
|
||||
* Wraps a Cube map and allows to read from or write pixels into it.
|
||||
*
|
||||
@ -57,6 +55,8 @@ public class CubeMapWrapper {
|
||||
private final Vector2f uvs = new Vector2f();
|
||||
private final Image image;
|
||||
|
||||
private final ColorRGBA tmpColor = new ColorRGBA();
|
||||
|
||||
/**
|
||||
* Creates a CubeMapWrapper for the given cube map
|
||||
* Note that the cube map must be initialized, and the mipmaps sizes should
|
||||
@ -105,7 +105,7 @@ public class CubeMapWrapper {
|
||||
* @param store the color in which to store the pixel color read.
|
||||
* @return the color of the pixel read.
|
||||
*/
|
||||
public ColorRGBA getPixel(Vector3f vector, int mipLevel, ColorRGBA store) {
|
||||
public ColorRGBA getPixel(Vector3f vector, float mipLevel, ColorRGBA store) {
|
||||
if (mipMapRaster == null) {
|
||||
throw new IllegalArgumentException("This cube map has no mip maps");
|
||||
}
|
||||
@ -113,10 +113,26 @@ public class CubeMapWrapper {
|
||||
store = new ColorRGBA();
|
||||
}
|
||||
|
||||
int face = EnvMapUtils.getCubemapFaceTexCoordFromVector(vector, sizes[mipLevel], uvs, EnvMapUtils.FixSeamsMethod.Stretch);
|
||||
int lowerMipLevel = (int) mipLevel;
|
||||
int higherMipLevel = (int) FastMath.ceil(mipLevel);
|
||||
float ratio = mipLevel - lowerMipLevel;
|
||||
|
||||
int face = EnvMapUtils.getCubemapFaceTexCoordFromVector(vector, sizes[lowerMipLevel], uvs, EnvMapUtils.FixSeamsMethod.Stretch);
|
||||
mipMapRaster.setSlice(face);
|
||||
mipMapRaster.setMipLevel(mipLevel);
|
||||
return mipMapRaster.getPixel((int) uvs.x, (int) uvs.y, store);
|
||||
mipMapRaster.setMipLevel(lowerMipLevel);
|
||||
mipMapRaster.getPixel((int) uvs.x, (int) uvs.y, store);
|
||||
|
||||
face = EnvMapUtils.getCubemapFaceTexCoordFromVector(vector, sizes[higherMipLevel], uvs, EnvMapUtils.FixSeamsMethod.Stretch);
|
||||
mipMapRaster.setSlice(face);
|
||||
mipMapRaster.setMipLevel(higherMipLevel);
|
||||
mipMapRaster.getPixel((int) uvs.x, (int) uvs.y, tmpColor);
|
||||
|
||||
store.r = FastMath.interpolateLinear(ratio, store.r, tmpColor.r);
|
||||
store.g = FastMath.interpolateLinear(ratio, store.g, tmpColor.g);
|
||||
store.b = FastMath.interpolateLinear(ratio, store.b, tmpColor.b);
|
||||
store.a = FastMath.interpolateLinear(ratio, store.a, tmpColor.a);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -37,19 +37,16 @@ import com.jme3.math.*;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.Texture2D;
|
||||
import com.jme3.texture.TextureCubeMap;
|
||||
import com.jme3.texture.*;
|
||||
import com.jme3.texture.image.ColorSpace;
|
||||
import com.jme3.ui.Picture;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import static com.jme3.math.FastMath.*;
|
||||
|
||||
import com.jme3.util.TempVars;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.jme3.math.FastMath.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class holds several utility method unseful for Physically Based
|
||||
@ -88,6 +85,11 @@ public class EnvMapUtils {
|
||||
None
|
||||
}
|
||||
|
||||
public static enum GenerationType {
|
||||
Fast,
|
||||
HighQuality
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cube map from 6 images
|
||||
*
|
||||
@ -117,6 +119,8 @@ public class EnvMapUtils {
|
||||
cubeImage.addData(backImg.getData(0));
|
||||
cubeImage.addData(frontImg.getData(0));
|
||||
|
||||
cubeImage.setMipMapSizes(rightImg.getMipMapSizes());
|
||||
|
||||
TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
|
||||
cubeMap.setAnisotropicFilter(0);
|
||||
cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
|
||||
@ -148,6 +152,8 @@ public class EnvMapUtils {
|
||||
cubeImage.addData(d.duplicate());
|
||||
}
|
||||
|
||||
cubeImage.setMipMapSizes(srcImg.getMipMapSizes());
|
||||
|
||||
TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
|
||||
cubeMap.setAnisotropicFilter(sourceMap.getAnisotropicFilter());
|
||||
cubeMap.setMagFilter(sourceMap.getMagFilter());
|
||||
@ -730,7 +736,7 @@ public class EnvMapUtils {
|
||||
pem.setMagFilter(Texture.MagFilter.Bilinear);
|
||||
pem.setMinFilter(Texture.MinFilter.Trilinear);
|
||||
pem.getImage().setColorSpace(ColorSpace.Linear);
|
||||
int nbMipMap = (int) (Math.log(size) / Math.log(2) - 1);
|
||||
int nbMipMap = Math.min(6, (int) (Math.log(size) / Math.log(2)));
|
||||
CubeMapWrapper targetWrapper = new CubeMapWrapper(pem);
|
||||
targetWrapper.initMipMaps(nbMipMap);
|
||||
return pem;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -114,7 +114,7 @@ public class LightsDebugState extends BaseAppState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the scenes for wich to render light gizmos.
|
||||
* Set the scenes for which to render light gizmos.
|
||||
* @param scene
|
||||
*/
|
||||
public void setScene(Spatial scene) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -34,7 +34,6 @@ package com.jme3.input;
|
||||
import com.jme3.export.InputCapsule;
|
||||
import com.jme3.export.JmeExporter;
|
||||
import com.jme3.export.JmeImporter;
|
||||
import com.jme3.export.OutputCapsule;
|
||||
import com.jme3.input.controls.*;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Vector3f;
|
||||
@ -420,7 +419,7 @@ public class ChaseCamera implements ActionListener, AnalogListener, Control, Jme
|
||||
|
||||
//the user is rotating the cam by dragging the mouse
|
||||
if (canRotate) {
|
||||
//reseting the trailing lerp factor
|
||||
//reset the trailing lerp factor
|
||||
trailingLerpFactor = 0;
|
||||
//stop trailing user has the control
|
||||
trailing = false;
|
||||
@ -582,15 +581,14 @@ public class ChaseCamera implements ActionListener, AnalogListener, Control, Jme
|
||||
|
||||
/**
|
||||
* clone this camera for a spatial
|
||||
*
|
||||
* @param spatial
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public Control cloneForSpatial(Spatial spatial) {
|
||||
ChaseCamera cc = new ChaseCamera(cam, spatial, inputManager);
|
||||
cc.setMaxDistance(getMaxDistance());
|
||||
cc.setMinDistance(getMinDistance());
|
||||
return cc;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -423,16 +423,23 @@ public class InputManager implements RawInputListener {
|
||||
|
||||
/**
|
||||
* Callback from RawInputListener. Do not use.
|
||||
*
|
||||
* @param evt event to add to the input queue (not null)
|
||||
*/
|
||||
@Override
|
||||
public void onMouseMotionEvent(MouseMotionEvent evt) {
|
||||
if (!eventsPermitted) {
|
||||
throw new UnsupportedOperationException("MouseInput has raised an event at an illegal time.");
|
||||
}
|
||||
|
||||
/*
|
||||
* If events aren't allowed, the event may be a "first mouse event"
|
||||
* triggered by the constructor setting the mouse listener.
|
||||
* In that case, use the event to initialize the cursor position,
|
||||
* but don't queue it for further processing.
|
||||
* This is part of the fix for issue #792.
|
||||
*/
|
||||
cursorPos.set(evt.getX(), evt.getY());
|
||||
if (eventsPermitted) {
|
||||
inputQueue.add(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMouseButtonEventQueued(MouseButtonEvent evt) {
|
||||
int hash = MouseButtonTrigger.mouseButtonHash(evt.getButtonIndex());
|
||||
@ -867,7 +874,7 @@ public class InputManager implements RawInputListener {
|
||||
// larynx, 2011.06.10 - flag event as reusable because
|
||||
// the android input uses a non-allocating ringbuffer which
|
||||
// needs to know when the event is not anymore in inputQueue
|
||||
// and therefor can be reused.
|
||||
// and therefore can be reused.
|
||||
event.setConsumed();
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -123,7 +123,7 @@ public interface Joystick {
|
||||
|
||||
/**
|
||||
* Returns the POV Y axis for this joystick. This is a convenience axis
|
||||
* providing an y-axis subview of the HAT axis.
|
||||
* providing a y-axis subview of the HAT axis.
|
||||
*
|
||||
* @see JoystickAxis#assignAxis(java.lang.String, java.lang.String)
|
||||
*/
|
||||
|
||||
@ -445,6 +445,16 @@ public interface KeyInput extends Input {
|
||||
* (J3100).
|
||||
*/
|
||||
public static final int KEY_UNLABELED = 0x97;
|
||||
/**
|
||||
* PrtScr key.
|
||||
* Note: for use on keyboards with a PrtScr key that is
|
||||
* separate from the SysRq key. Most keyboards combine
|
||||
* SysRq and PrtScr so if the intent is to actually
|
||||
* capture the user's desire to capture the screen
|
||||
* then SysRq is the most likely scan code.
|
||||
* Use PrtScr to catch the rest (laptops, mini-keyboards, etc.)
|
||||
*/
|
||||
public static final int KEY_PRTSCR = 0x9A;
|
||||
/**
|
||||
* Enter key (num pad).
|
||||
*/
|
||||
|
||||
@ -128,14 +128,12 @@ public class LightProbe extends Light implements Savable {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
|
||||
|
||||
prefilteredEnvMap = (TextureCubeMap) ic.readSavable("prefilteredEnvMap", null);
|
||||
position = (Vector3f) ic.readSavable("position", this);
|
||||
position = (Vector3f) ic.readSavable("position", null);
|
||||
bounds = (BoundingVolume) ic.readSavable("bounds", new BoundingSphere(1.0f, Vector3f.ZERO));
|
||||
nbMipMaps = ic.readInt("nbMipMaps", 0);
|
||||
ready = ic.readBoolean("ready", false);
|
||||
|
||||
|
||||
Savable[] coeffs = ic.readSavableArray("shCoeffs", null);
|
||||
if (coeffs == null) {
|
||||
ready = false;
|
||||
@ -145,7 +143,6 @@ public class LightProbe extends Light implements Savable {
|
||||
for (int i = 0; i < coeffs.length; i++) {
|
||||
shCoeffs[i] = (Vector3f) coeffs[i];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2015 jMonkeyEngine
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -48,7 +48,7 @@ public interface LightProbeBlendingStrategy {
|
||||
public void registerProbe(LightProbe probe);
|
||||
/**
|
||||
* Populates the resulting light probes into the given light list.
|
||||
* @param g the geometry for wich the light list is computed
|
||||
* @param g the geometry for which the light list is computed
|
||||
* @param lightList the result light list
|
||||
*/
|
||||
public void populateProbes(Geometry g, LightList lightList);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
|
||||
* Copyright (c) 2009-2012, 2015-2016, 2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -54,7 +54,7 @@ import java.io.IOException;
|
||||
* <p>
|
||||
* In addition to a position, point lights also have a radius which
|
||||
* can be used to attenuate the influence of the light depending on the
|
||||
* distance between the light and the effected object.
|
||||
* distance between the light and the affected object.
|
||||
*
|
||||
*/
|
||||
public class PointLight extends Light {
|
||||
@ -155,7 +155,7 @@ public class PointLight extends Light {
|
||||
* Setting a non-zero radius indicates the light should use attenuation.
|
||||
* If a pixel's distance to this light's position
|
||||
* is greater than the light's radius, then the pixel will not be
|
||||
* effected by this light, if the distance is less than the radius, then
|
||||
* affected by this light, if the distance is less than the radius, then
|
||||
* the magnitude of the influence is equal to distance / radius.
|
||||
*
|
||||
* @param radius the radius of the light influence.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
|
||||
* Copyright (c) 2009-2012, 2015-2016, 2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -337,7 +337,7 @@ public class SpotLight extends Light {
|
||||
* Setting a non-zero range indicates the light should use attenuation.
|
||||
* If a pixel's distance to this light's position
|
||||
* is greater than the light's range, then the pixel will not be
|
||||
* effected by this light, if the distance is less than the range, then
|
||||
* affected by this light, if the distance is less than the range, then
|
||||
* the magnitude of the influence is equal to distance / range.
|
||||
*
|
||||
* @param spotRange the range of the light influence.
|
||||
|
||||
45
jme3-core/src/main/java/com/jme3/material/Materials.java
Normal file
45
jme3-core/src/main/java/com/jme3/material/Materials.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package com.jme3.material;
|
||||
|
||||
/**
|
||||
* This class is to provide some constants materials.
|
||||
*
|
||||
* @author oualid
|
||||
*/
|
||||
public class Materials {
|
||||
|
||||
public static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md";
|
||||
public static final String LIGHTING = "Common/MatDefs/Light/Lighting.j3md";
|
||||
public static final String PBR = "Common/MatDefs/Light/PBRLighting.j3md";
|
||||
|
||||
}
|
||||
@ -206,7 +206,9 @@ public class ShaderGenerationInfo implements Savable, Cloneable {
|
||||
clone.vertexUniforms.add(uniform.clone());
|
||||
}
|
||||
|
||||
if (vertexGlobal != null) {
|
||||
clone.vertexGlobal = vertexGlobal.clone();
|
||||
}
|
||||
|
||||
for (ShaderNodeVariable varying : varyings) {
|
||||
clone.varyings.add(varying.clone());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user