import peasy.*;
PeasyCam cam;
float cubeSize = 15;
float xoff = 0.5;
PShape Box;
Building[] city = new Building[100];
void setup() {
//size( 1000, 1000, P3D);
fullScreen(P3D);
cam = new PeasyCam(this, width/2 -500, height/2, 1000, 2000);
//create brick for building
Box = createShape(BOX, cubeSize);
//populate city array with building objects and pass coordinates
for(int i = 0; i < city.length; i++){
float r = random(-100, 100);
float r2 = random(-100, 100);
city[i] = new Building(r, height, r2);
}
//build tower with box pshapes with coords passed in previous loop
for(Building city : city){
city.build();
}
}
void draw() {
background(140);
fill(255);
//draw floor
beginShape();
vertex(-20000, height, 20000);
vertex(20000, height, 20000);
vertex(20000, height, -20000);
vertex(-20000, height, -20000);
endShape();
//show buildings stored in city array
for(Building city : city){
city.show();
}
}
class Building {
float locX, locY, locZ;
float columns, rows;
ArrayList<Cube> walls = new ArrayList<Cube>();
Building(float locXTemp, float locYTemp, float locZTemp) {
locX = locXTemp;
locY = locYTemp;
locZ = locZTemp;
columns = random(5, 20);
rows = random(5, 40);
}
void build() {
for (float x = locX; x < columns + locX; x ++) {
for (float y = locY; y > locY-(rows*cubeSize); y -= cubeSize) {
float noiseVal = 0;
noiseVal= noise(xoff * x, xoff * y ) * (cubeSize * 1.2 );
walls.add(new Cube(x * cubeSize, y , locZ * cubeSize + noiseVal, 255, Box));
}
}
for (float x = locX; x < columns + locX; x ++) {
for (float y = locY; y > locY-(rows*cubeSize); y -= cubeSize) {
float noiseVal = 0;
noiseVal= noise(xoff * x, xoff * y ) * (cubeSize * 1.2 );
walls.add(new Cube(x * cubeSize + cubeSize, y, (locZ * cubeSize) + (columns * cubeSize) + noiseVal, 255, Box));
}
}
for (float z = locZ; z < columns + locZ; z ++) {
for (float y = locY; y > locY-(rows*cubeSize); y -= cubeSize) {
float noiseVal = 0;
noiseVal = noise(xoff * z, xoff * y ) * (cubeSize* 1.2);
walls.add(new Cube((locX * cubeSize) + (columns * cubeSize) + noiseVal, y, z * cubeSize, 255, Box));
}
}
for (float z = locZ; z < columns + locZ; z ++) {
for (float y = locY; y > locY-(rows*cubeSize); y -= cubeSize) {
float noiseVal = 0;
noiseVal = noise(xoff * z, xoff * y ) * (cubeSize* 1.2);
walls.add(new Cube(locX * cubeSize + noiseVal, y , z * cubeSize, 255, Box));
}
}
}
void show(){
for(Cube walls : walls){
walls.cube();
}
}
}
class Cube {
float x, y, z, c;
PShape b;
Cube(float xTemp, float yTemp, float zTemp, float cTemp, PShape bTemp) {
x = xTemp;
y = yTemp;
z = zTemp;
c = cTemp;
b = bTemp;
}
void cube() {
fill(c);
pushMatrix();
translate(x, y, z);
shape(b);
popMatrix();
}
}
also your floor is pretty big.
maybe as a floor you could make a thin box
box(40000, 5, 40000);
(which would be around 0,0,0)
or
pushMatrix();
translate(0,width,0);
box(40000, 5, 40000);
popMatrix();
(which would be around 0,width,0)
The most efficient way to draw triangles or quads is as a flat PShape. No GROUP, no BOXes, just a flat list of QUADS. If you make a PShape per building, you could even reuse them for multiple buildings of the same size. Make a dozen PShape buildings of different sizes, choose a few at random for each city block, and you could probably render hundreds of buildings smoothly.
Drawing quads using stroke()
for their edges will probably still be quite slow. You could speed that up by drawing the quads with a texture that has a simple picture of the outline.
The most efficient rendering would, of course, be a single box per building with a full wall texture on it.
That makes a lot of sense, especially as with the box the insides can’t really be seen.
One of them that I just started coding without much of a plan and was making it far too difficult for myself.
Thanks for your perspective!