/**
* Scene processors are used to compute/render things before and after the classic render of the scene.
* They have to be added to a viewport and are rendered in the order they've been added
- * @author Kirill Vainer aka Shadowislord aka Momoko_Fan
+ *
+ * @author Kirill Vainer
*/
public interface SceneProcessor {
/**
- * For internal use only<br>
* Called in the render thread to initialize the scene processor.
*
* @param rm The render manager to which the SP was added to
public void initialize(RenderManager rm, ViewPort vp);
/**
- * For internal use only<br>
* Called when the resolution of the viewport has been changed.
* @param vp
*/
public boolean isInitialized();
/**
- * For internal use only<br>
* Called before a frame
*
* @param tpf Time per frame
public void preFrame(float tpf);
/**
- * For internal use only<br>
* Called after the scene graph has been queued, but before it is flushed.
*
* @param rq The render queue
public void postQueue(RenderQueue rq);
/**
- * For internal use only<br>
* Called after a frame has been rendered and the queue flushed.
*
* @param out The FB to which the scene was rendered.
public void postFrame(FrameBuffer out);
/**
- * For internal use only<br>
* Called when the SP is removed from the RM.
*/
public void cleanup();
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
private int tableOffset;
private int tableLength;
private HashMap<String, ZipEntry2> entries;
+
+ private static final ByteBuffer byteBuf = ByteBuffer.allocate(250);
+ private static final CharBuffer charBuf = CharBuffer.allocate(250);
+ private static final CharsetDecoder utf8Decoder;
+
+ static {
+ Charset utf8 = Charset.forName("UTF-8");
+ utf8Decoder = utf8.newDecoder();
+ }
private static class ZipEntry2 {
String name;
(((long)(b[off]&0xff)) << 24);
}
- private static String getUTF8String(byte[] b, int off, int len) {
- // First, count the number of characters in the sequence
- int count = 0;
- int max = off + len;
- int i = off;
- while (i < max) {
- int c = b[i++] & 0xff;
- switch (c >> 4) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- // 0xxxxxxx
- count++;
- break;
- case 12: case 13:
- // 110xxxxx 10xxxxxx
- if ((int)(b[i++] & 0xc0) != 0x80) {
- throw new IllegalArgumentException();
- }
- count++;
- break;
- case 14:
- // 1110xxxx 10xxxxxx 10xxxxxx
- if (((int)(b[i++] & 0xc0) != 0x80) ||
- ((int)(b[i++] & 0xc0) != 0x80)) {
- throw new IllegalArgumentException();
- }
- count++;
- break;
- default:
- // 10xxxxxx, 1111xxxx
- throw new IllegalArgumentException();
- }
- }
- if (i != max) {
- throw new IllegalArgumentException();
- }
- // Now decode the characters...
- char[] cs = new char[count];
- i = 0;
- while (off < max) {
- int c = b[off++] & 0xff;
- switch (c >> 4) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- // 0xxxxxxx
- cs[i++] = (char)c;
- break;
- case 12: case 13:
- // 110xxxxx 10xxxxxx
- cs[i++] = (char)(((c & 0x1f) << 6) | (b[off++] & 0x3f));
- break;
- case 14:
- // 1110xxxx 10xxxxxx 10xxxxxx
- int t = (b[off++] & 0x3f) << 6;
- cs[i++] = (char)(((c & 0x0f) << 12) | t | (b[off++] & 0x3f));
- break;
- default:
- // 10xxxxxx, 1111xxxx
- throw new IllegalArgumentException();
- }
- }
- return new String(cs, 0, count);
+ private static String getUTF8String(byte[] b, int off, int len) throws CharacterCodingException {
+ StringBuilder sb = new StringBuilder();
+
+ int read = 0;
+ while (read < len){
+ // Either read n remaining bytes in b or 250 if n is higher.
+ int toRead = Math.min(len - read, byteBuf.capacity());
+
+ boolean endOfInput = toRead < byteBuf.capacity();
+
+ // read 'toRead' bytes into byteBuf
+ byteBuf.put(b, off + read, toRead);
+
+ // set limit to position and set position to 0
+ // so data can be decoded
+ byteBuf.flip();
+
+ // decode data in byteBuf
+ CoderResult result = utf8Decoder.decode(byteBuf, charBuf, endOfInput);
+
+ // if the result is not an underflow its an error
+ // that cannot be handled.
+ // if the error is an underflow and its the end of input
+ // then the decoder expects more bytes but there are no more => error
+ if (!result.isUnderflow() || !endOfInput){
+ result.throwException();
+ }
+
+ // flip the char buf to get the string just decoded
+ charBuf.flip();
+
+ // append the decoded data into the StringBuilder
+ sb.append(charBuf.toString());
+
+ // clear buffers for next use
+ byteBuf.clear();
+ charBuf.clear();
+
+ read += toRead;
+ }
+
+ return sb.toString();
}
private InputStream readData(int offset, int length) throws IOException{
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.ScreenshotAppState;
+import com.jme3.asset.plugins.HttpZipLocator;
+import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.terrain.geomipmap.TerrainGrid;
import com.jme3.terrain.geomipmap.TerrainGridListener;
import com.jme3.terrain.geomipmap.TerrainLodControl;
-import com.jme3.terrain.geomipmap.TerrainQuad;
-import com.jme3.terrain.heightmap.FractalHeightMapGrid;
import com.jme3.terrain.heightmap.ImageBasedHeightMapGrid;
import com.jme3.terrain.heightmap.Namer;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
+import java.io.File;
import org.novyon.noise.ShaderUtils;
import org.novyon.noise.basis.FilteredBasis;
import org.novyon.noise.filter.IterativeFilter;
@Override
public void simpleInitApp() {
+ File file = new File("mountains.zip");
+ if (!file.exists()) {
+ assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/mountains.zip", HttpZipLocator.class);
+ }else{
+ assetManager.registerLocator("mountains.zip", ZipLocator.class);
+ }
+
this.flyCam.setMoveSpeed(100f);
ScreenshotAppState state = new ScreenshotAppState();
this.stateManager.attach(state);
ground.addPreFilter(this.iterate);
this.terrain = new TerrainGrid("terrain", 65, 1025, new ImageBasedHeightMapGrid(assetManager, new Namer() {
-
public String getName(int x, int y) {
- return "Textures/Terrain/grid/terrain_" + x + "_" + y + ".png";
+ return "Scenes/TerrainAlphaTest/terrain_" + x + "_" + y + ".png";
}
}));
this.terrain.setMaterial(this.matRock);
}
public Material tileLoaded(Material material, Vector3f cell) {
- material.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/grid/alphamap_" + (int)Math.abs(512 * (cell.x % 2)) + "_" + (int)Math.abs(512 * (cell.z % 2)) + ".png"));
+ int x = (int)Math.abs(512 * (cell.x % 2));
+ int z = (int)Math.abs(512 * (cell.z % 2));
+ material.setTexture("Alpha", assetManager.loadTexture("Scenes/TerrainAlphaTest/alphamap_" + x + "_" + z + ".png"));
return material;
}
});
public void simpleInitApp() {
File file = new File("mountains.zip");
if (!file.exists()) {
- assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/mountains.zip", HttpZipLocator.class.getName());
+ assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/mountains.zip", HttpZipLocator.class);
}else{
- assetManager.registerLocator("mountains.zip", ZipLocator.class.getName());
+ assetManager.registerLocator("mountains.zip", ZipLocator.class);
}
this.flyCam.setMoveSpeed(100f);
import com.jme3.material.Material;
import com.jme3.math.Matrix4f;
+import com.jme3.math.Transform;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
geometry.removeFromParent();
}
+ // Since the scene is returned unaltered the transform must be reset
+ scene.setLocalTransform(Transform.IDENTITY);
+
return scene;
}