* HttpZipLocator UTF8 decoder replaced with proper code
* Removed some redundant javadoc from SceneProcessor * Fixed bug where GeometryBatchFactory.optimize() wouldn't reset the transform on the argument node as would be expected since optimize() applies the world transform of the geometries automatically * Terrain grid tests now stream terrain data from googlecode servers instead of having the data bundled in the nightly builds git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7619 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
@ -40,12 +40,12 @@ import com.jme3.texture.FrameBuffer;
|
||||
/**
|
||||
* 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
|
||||
@ -54,7 +54,6 @@ public interface SceneProcessor {
|
||||
public void initialize(RenderManager rm, ViewPort vp);
|
||||
|
||||
/**
|
||||
* For internal use only<br>
|
||||
* Called when the resolution of the viewport has been changed.
|
||||
* @param vp
|
||||
*/
|
||||
@ -67,7 +66,6 @@ public interface SceneProcessor {
|
||||
public boolean isInitialized();
|
||||
|
||||
/**
|
||||
* For internal use only<br>
|
||||
* Called before a frame
|
||||
*
|
||||
* @param tpf Time per frame
|
||||
@ -75,7 +73,6 @@ public interface SceneProcessor {
|
||||
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
|
||||
@ -83,7 +80,6 @@ public interface SceneProcessor {
|
||||
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.
|
||||
@ -91,7 +87,6 @@ public interface SceneProcessor {
|
||||
public void postFrame(FrameBuffer out);
|
||||
|
||||
/**
|
||||
* For internal use only<br>
|
||||
* Called when the SP is removed from the RM.
|
||||
*/
|
||||
public void cleanup();
|
||||
|
@ -40,6 +40,12 @@ import java.io.IOException;
|
||||
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;
|
||||
@ -57,6 +63,15 @@ public class HttpZipLocator implements AssetLocator {
|
||||
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;
|
||||
@ -94,66 +109,48 @@ public class HttpZipLocator implements AssetLocator {
|
||||
(((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{
|
||||
|
Before Width: | Height: | Size: 520 KiB |
Before Width: | Height: | Size: 708 KiB |
Before Width: | Height: | Size: 708 KiB |
Before Width: | Height: | Size: 702 KiB |
Before Width: | Height: | Size: 452 KiB |
Before Width: | Height: | Size: 447 KiB |
Before Width: | Height: | Size: 462 KiB |
Before Width: | Height: | Size: 467 KiB |
Before Width: | Height: | Size: 464 KiB |
Before Width: | Height: | Size: 451 KiB |
Before Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 446 KiB |
Before Width: | Height: | Size: 449 KiB |
Before Width: | Height: | Size: 452 KiB |
Before Width: | Height: | Size: 440 KiB |
Before Width: | Height: | Size: 449 KiB |
Before Width: | Height: | Size: 443 KiB |
Before Width: | Height: | Size: 449 KiB |
Before Width: | Height: | Size: 450 KiB |
Before Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 451 KiB |
Before Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 443 KiB |
Before Width: | Height: | Size: 450 KiB |
Before Width: | Height: | Size: 443 KiB |
Before Width: | Height: | Size: 442 KiB |
Before Width: | Height: | Size: 446 KiB |
Before Width: | Height: | Size: 458 KiB |
Before Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 442 KiB |
Before Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 442 KiB |
Before Width: | Height: | Size: 450 KiB |
Before Width: | Height: | Size: 454 KiB |
Before Width: | Height: | Size: 446 KiB |
Before Width: | Height: | Size: 436 KiB |
Before Width: | Height: | Size: 456 KiB |
Before Width: | Height: | Size: 453 KiB |
Before Width: | Height: | Size: 453 KiB |
Before Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 448 KiB |
@ -5,6 +5,8 @@ import java.util.List;
|
||||
|
||||
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;
|
||||
@ -20,12 +22,11 @@ import com.jme3.renderer.Camera;
|
||||
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;
|
||||
@ -58,6 +59,13 @@ public class TerrainGridAlphaMapTest extends SimpleApplication {
|
||||
|
||||
@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);
|
||||
@ -126,9 +134,8 @@ public class TerrainGridAlphaMapTest extends SimpleApplication {
|
||||
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);
|
||||
@ -139,7 +146,9 @@ public class TerrainGridAlphaMapTest extends SimpleApplication {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
@ -61,9 +61,9 @@ public class TerrainGridTest extends SimpleApplication {
|
||||
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);
|
||||
|
@ -2,6 +2,7 @@ package jme3tools.optimize;
|
||||
|
||||
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;
|
||||
@ -348,6 +349,9 @@ public class GeometryBatchFactory {
|
||||
geometry.removeFromParent();
|
||||
}
|
||||
|
||||
// Since the scene is returned unaltered the transform must be reset
|
||||
scene.setLocalTransform(Transform.IDENTITY);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|