sorry for late response folks, i dont have much time lately. ;(

regarding models - trees are quite simple, you can use them. Just unpack client.jar and check resources1/static/trees for model and textures

regarding texture generation, it's actually an RGB filter which i use to mix 4 textures - one per each vertex, here is the code. It's rough and somewhat code dependent but.. anyway - it's enough to explain the idea

private static class MixFilter extends RGBImageFilter {

BufferedImage [] images;

int size = 0;

public MixFilter(Terrain3D []terrains) {

images = new BufferedImage[terrains.length];

for (int i = 0; i < terrains.length; i++) {

Terrain3D terrain = terrains[i];

images[i] = (BufferedImage) terrain.getImage();

}

size = images[0].getWidth();

}

public int filterRGB(int x, int y, int rgb) {

double maxLen = Math.sqrt(2) * size;

double[]weights = new double[images.length];

weights[0] = (maxLen - 1 - Point.distance(x, y, 0, 0)) / maxLen;

weights[1] = (maxLen - 1 - Point.distance(x, y, size, 0)) / maxLen;

weights[2] = (maxLen - 1 - Point.distance(x, y, size, size)) / maxLen;

weights[3] = (maxLen - 1 - Point.distance(x, y, 0, size)) / maxLen;

if (Math.random() > 0.2)

return getFineRGB(weights, x, y);

return getCoarseRGB(weights, x, y);

}

private int getFineRGB(double[] weights, int x, int y) {

double r = 0;

double g = 0;

double b = 0;

for (int i = 0; i < weights.length; i++) {

weights[i] = weights[i] * weights[i];

// weights[i] = Math.pow(weights[i],2.5);

}

double weightsSum = 0;

for (int i = 0; i < weights.length; i++) {

double weight = weights[i];

weightsSum += weight;

}

for (int i = 0; i < weights.length; i++) {

weights[i] = weights[i] / weightsSum;

}

for (int i = 0; i < weights.length; i++) {

double weight = weights[i];

Color col = new Color(images[i].getRGB(x, y));

r += (col.getRed() * weight);

g += (col.getGreen() * weight);

b += (col.getBlue() * weight);

}

return new Color((int) r, (int) g, (int) b).getRGB();

}

private int getCoarseRGB(double[] weights, int x, int y) {

double weightLimit = 0;

for (int i = 0; i < weights.length; i++) {

if (i < weights.length - 1) {

double lim = 0.2 * (0.5 - Math.random());

weights[i] += lim;

weightLimit += lim;

} else {

weights[i] -= weightLimit;

}

}

int idx = 0;

double maxWeight = 0;

for (int i = 0; i < weights.length; i++) {

double weight = weights[i];

if (weight > maxWeight) {

maxWeight = weight;

idx = i;

}

}

return images[idx].getRGB(x, y);

}

}