Trying to create a city scape, but code is running very slow, can this be fixed by creating each tower as a PShape?

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();
  }
}
1 Like

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)

1 Like

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.

2 Likes

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!

2 Likes