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.
192 lines
7.3 KiB
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|