Right so here is my attempt at reading in an image in chunks of 3x3 pixels, making 4 quads, and placing them in space beside each other. I can’t work out how to manipulate the y values of each quads corners though.
I just had a thought though - is the x and z of each quad proportional? What I mean is, if the colours range between 0 and 1 (black b to white w), and say we have 4 quads made like this:
b b w
b b w
b b w
The x distance of whole thing should be 1 unit, as is the z distance. The top left quad is:
b b
b b
That would be 1 units x and z. The top right quad is:
b w
b w
That would be 0 unit x and 1 unit z and 1 unit y and would look like this:
Say we had this arrangement:
b b b
b b b
b b b
Both the top left and top right are:
b b
b b
and it would look like this:
I feel like I am really close, but, I can’t think how to do the proportional part. Its like the bigger the difference in pixel values between neighbor pixels is the more vertical space it takes and the less horizontal space…
Here is my code i have so far, sans any height stuff:
public GameEnvironment(AssetManager assetManager, BulletAppState bulletAppState) {
mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/alphamap.png"));
/**
* Add grid texture into the blue layer (Tex3)
*/
Texture surfaceTexture = assetManager.loadTexture("Textures/grid8.png");
surfaceTexture.setWrap(Texture.WrapMode.Repeat);
mat_terrain.setTexture("Tex3", surfaceTexture);
mat_terrain.setFloat("Tex3Scale", 2048f);
Texture theMap;
theMap = assetManager.loadTexture("Textures/play.png");
Image colorImage = theMap.getImage();
int imageWidth = colorImage.getWidth();
int imageHeight = colorImage.getHeight();
if (imageWidth % 3 != 0 || imageHeight % 3 != 0) {
throw new RuntimeException("imageWidth: " + imageWidth + " or imageHeight: " + imageHeight + " not divisible by 3");
}
System.out.println("number of thingys " + imageHeight + " " + imageWidth * imageHeight);
ImageRaster raster = ImageRaster.create(colorImage);
ColorRGBA colorStore = new ColorRGBA();
for (int h0 = 0; h0 < imageHeight; h0+=3) {
int h1 = h0+1;
int h2 = h0+2;
for (int w0 = 0; w0 < imageWidth; w0+=3) {
int w1 = w0+1;
int w2 = w0+2;
Node tempNode = new Node(w0 + "," + h0);
float[][] colour = new float[3][3];
colour[0][0] = this.getColourAt(w0, h0, raster);
colour[0][1] = this.getColourAt(w0, h1, raster);
colour[0][2] = this.getColourAt(w0, h2, raster);
colour[1][0] = this.getColourAt(w1, h0, raster);
colour[1][1] = this.getColourAt(w1, h1, raster);
colour[1][2] = this.getColourAt(w1, h2, raster);
colour[2][0] = this.getColourAt(w2, h0, raster);
colour[2][1] = this.getColourAt(w2, h1, raster);
colour[2][2] = this.getColourAt(w2, h2, raster);
System.out.println(colour[0][0] + "," + colour[0][1] + "," + colour[0][2]);
System.out.println(colour[1][0] + "," + colour[1][1] + "," + colour[1][2]);
System.out.println(colour[2][0] + "," + colour[2][1] + "," + colour[2][2]);
/* we add/remove tileWidthHeight/2 because the rotation isn't about the centre, I think its off to one side */
Vector3f transTopLeft = new Vector3f((1 * tileWidthHeight) - tileWidthHeight / 2, 0, (1 * tileWidthHeight) + tileWidthHeight / 2);
Vector3f transTopRight = new Vector3f((2 * tileWidthHeight) - tileWidthHeight / 2, 0, (1 * tileWidthHeight) + tileWidthHeight / 2);
Vector3f transBottomLeft = new Vector3f((1 * tileWidthHeight) - tileWidthHeight / 2, 0, (2 * tileWidthHeight) + tileWidthHeight / 2);
Vector3f transBottomRight = new Vector3f((2 * tileWidthHeight) - tileWidthHeight / 2, 0, (2 * tileWidthHeight) + tileWidthHeight / 2);
/* make a mesh and stick it in a geometry, and rotate it properly */
Geometry topleft = new Geometry("topleft", new Quad(tileWidthHeight, tileWidthHeight));
Geometry topright = new Geometry("topright", new Quad(tileWidthHeight, tileWidthHeight));
Geometry bottomleft = new Geometry("bottomleft", new Quad(tileWidthHeight, tileWidthHeight));
Geometry bottomright = new Geometry("bottomright", new Quad(tileWidthHeight, tileWidthHeight));
//flatten
topleft.rotate((float) (Math.PI / 2) * 3, 0, 0);
topright.rotate((float) (Math.PI / 2) * 3, 0, 0);
bottomleft.rotate((float) (Math.PI / 2) * 3, 0, 0);
bottomright.rotate((float) (Math.PI / 2) * 3, 0, 0);
topleft.setLocalTranslation(transTopLeft);
topright.setLocalTranslation(transTopRight);
bottomleft.setLocalTranslation(transBottomLeft);
bottomright.setLocalTranslation(transBottomRight);
topleft.setMaterial(mat_terrain);
topright.setMaterial(mat_terrain);
bottomleft.setMaterial(mat_terrain);
bottomright.setMaterial(mat_terrain);
tempNode.attachChild(topleft);
tempNode.attachChild(topright);
tempNode.attachChild(bottomleft);
tempNode.attachChild(bottomright);
tempNode.setLocalTranslation(new Vector3f((w0/3)*2, 0, (h0/3)*2));
environment.attachChild(tempNode);
}
/* make terrain solid */
CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(environment);
landscape = new RigidBodyControl(sceneShape, 0);
environment.addControl(landscape);
bulletAppState.getPhysicsSpace().add(landscape);
}
}
private Float getColourAt(int x, int y, ImageRaster r) {
if (x < 0 || y < 0 || x >= r.getWidth() || y >= r.getHeight()) {
return null;
}
float blue = r.getPixel(x, y).getBlue();
float red = r.getPixel(x, y).getRed();
float green = r.getPixel(x, y).getGreen();
return (blue + red + green) / 3;
}