A complete 3D game development suite written purely in Java.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
jmonkeyengine/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstanceNode.java

192 lines
7.3 KiB

/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jme3test.scene.instancing;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial;
import com.jme3.scene.Node;
import com.jme3.scene.instancing.InstancedGeometry;
import com.jme3.scene.instancing.InstancedNode;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.system.AppSettings;
public class TestInstanceNode extends SimpleApplication {
private Mesh mesh1;
private Mesh mesh2;
private final Material[] materials = new Material[6];
private Node instancedNode;
private float time = 0;
private boolean INSTANCING = true;
public static void main(String[] args){
TestInstanceNode app = new TestInstanceNode();
AppSettings settings = new AppSettings(true);
settings.setVSync(false);
app.setSettings(settings);
app.start();
}
private Geometry createInstance(float x, float z) {
Mesh mesh;
if (FastMath.nextRandomInt(0, 1) == 1) mesh = mesh2;
else mesh = mesh1;
Geometry geometry = new Geometry("randomGeom", mesh);
geometry.setMaterial(materials[FastMath.nextRandomInt(0, materials.length - 1)]);
geometry.setLocalTranslation(x, 0, z);
return geometry;
}
@Override
public void simpleInitApp() {
mesh1 = new Sphere(13, 13, 0.4f, true, false);
mesh2 = new Box(0.4f, 0.4f, 0.4f);
materials[0] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
materials[0].setBoolean("UseInstancing", INSTANCING);
materials[0].setColor("Color", ColorRGBA.Red);
materials[1] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
materials[1].setBoolean("UseInstancing", INSTANCING);
materials[1].setColor("Color", ColorRGBA.Green);
materials[2] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
materials[2].setBoolean("UseInstancing", INSTANCING);
materials[2].setColor("Color", ColorRGBA.Blue);
materials[3] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
materials[3].setBoolean("UseInstancing", INSTANCING);
materials[3].setColor("Color", ColorRGBA.Cyan);
materials[4] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
materials[4].setBoolean("UseInstancing", INSTANCING);
materials[4].setColor("Color", ColorRGBA.Magenta);
materials[5] = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
materials[5].setBoolean("UseInstancing", INSTANCING);
materials[5].setColor("Color", ColorRGBA.Yellow);
instancedNode = new InstancedNode("instanced_node");
rootNode.attachChild(instancedNode);
int extent = 30;
for (int y = -extent; y < extent; y++) {
for (int x = -extent; x < extent; x++) {
Geometry instance = createInstance(x, y);
float height = (smoothstep(0, 1, FastMath.nextRandomFloat()) * 2.5f) - 1.25f;
instance.setUserData("height", height);
instance.setUserData("dir", 1f);
instancedNode.attachChild(instance);
}
}
if (INSTANCING) {
((InstancedNode)instancedNode).instance();
}
//instancedNode = (InstancedNode) instancedNode.clone();
//instancedNode.move(0, 5, 0);
//rootNode.attachChild(instancedNode);
cam.setLocation(new Vector3f(38.373516f, 6.689055f, 38.482082f));
cam.setRotation(new Quaternion(-0.04004206f, 0.918326f, -0.096310444f, -0.38183528f));
flyCam.setMoveSpeed(15);
flyCam.setEnabled(false);
}
private float smoothstep(float edge0, float edge1, float x) {
// Scale, bias and saturate x to 0..1 range
x = FastMath.clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
// Evaluate polynomial
return x * x * (3 - 2 * x);
}
@Override
public void simpleUpdate(float tpf) {
time += tpf;
if (time > 1f) {
time = 0f;
for (Spatial instance : instancedNode.getChildren()) {
if (!(instance instanceof InstancedGeometry)) {
Geometry geom = (Geometry) instance;
geom.setMaterial(materials[FastMath.nextRandomInt(0, materials.length - 1)]);
Mesh mesh;
if (FastMath.nextRandomInt(0, 1) == 1) mesh = mesh2;
else mesh = mesh1;
geom.setMesh(mesh);
}
}
}
for (Spatial child : instancedNode.getChildren()) {
if (!(child instanceof InstancedGeometry)) {
float val = child.getUserData("height");
float dir = child.getUserData("dir");
val += (dir + ((FastMath.nextRandomFloat() * 0.5f) - 0.25f)) * tpf;
if (val > 1f) {
val = 1f;
dir = -dir;
} else if (val < 0f) {
val = 0f;
dir = -dir;
}
Vector3f translation = child.getLocalTranslation();
translation.y = (smoothstep(0, 1, val) * 2.5f) - 1.25f;
child.setUserData("height", val);
child.setUserData("dir", dir);
child.setLocalTranslation(translation);
}
}
}
}