Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Binary file added .DS_Store
Binary file not shown.
99 changes: 59 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,62 @@

For this assignment you'll be building directly off of Project 3. To make things easier to keep track of, please fork and clone this repository [https://github.com/CIS700-Procedural-Graphics/Project4-Shape-Grammar](https://github.com/CIS700-Procedural-Graphics/Project4-Shape-Grammar) and copy your Project 3 code to start.

**Goal:** to model an urban environment using a shape grammar.

**Note:** We’re well aware that a nice-looking procedural city is a lot of work for a single week. Focus on designing a nice building grammar. The city layout strategies outlined in class (the extended l-systems) are complex and not expected. We will be satisfied with something reasonably simple, just not a uniform grid!

## Symbol Node (5 points)
Modify your symbol node class to include attributes necessary for rendering, such as
- Associated geometry instance
- Position
- Scale
- Anything else you may need

## Grammar design (55 points)
- Design at least five shape grammar rules for producing procedural buildings. Your buildings should vary in geometry and decorative features (beyond just differently-scaled cubes!). At least some of your rules should create child geometry that is in some way dependent on its parent’s state. (20 points)
- Eg. A building may be subdivided along the x, y, or z axis into two smaller buildings
- Some of your rules must be designed to use some property about its location. (10 points)
- Your grammar should have some element of variation so your buildings are non-deterministic. Eg. your buildings sometimes subdivide along the x axis, and sometimes the y. (10 points)
- Write a renderer that will interpret the results of your shape grammar parser and adds the appropriate geometry to your scene for each symbol in your set. (10 points)

## Create a city (30 points)
- Add a ground plane or some other base terrain to your scene (0 points, come on now)
- Using any strategy you’d like, procedurally generate features that demarcate your city into different areas in an interesting and plausible way (Just a uniform grid is neither interesting nor plausible). (20 points)
- Suggestions: roads, rivers, lakes, parks, high-population density
- Note, these features don’t have to be directly visible, like high-population density, but they should somehow be visible in the appearance or arrangement of your buildings. Eg. High population density is more likely to generate taller buildings
- Generate buildings throughout your city, using information about your city’s features. Color your buildings with a method that uses some aspect of its state. Eg. Color buildings by height, by population density, by number of rules used to generate it. (5 points)
- Document your grammar rules and general approach in the readme. (5 points)
- ???
- Profit.

## Make it interesting (10)
Experiment! Make your city a work of art.


## Warnings:
You can very easily blow up three.js with this assignment. With a very simple grammar, our medium quality machine was able to handle 100 buildings with 6 generations each, but be careful if you’re doing this all CPU-side.

## Suggestions for the overachievers:
Go for a very high level of decorative detail!
Place buildings with a strategy such that buildings have doors and windows that are always accessible.
Generate buildings with coherent interiors
If dividing your city into lots, generate odd-shaped lots and create building meshes that match their shape ie. rather than working with cubes, extrude upwards from the building footprints you find to generate a starting mesh to subdivide rather than starting with platonic geometry.
**Goal:** to model an urban environment using a shape grammars.

## Inspiration
I wanted to generate a city remeniscient of New York City, so I first analyzed the general characteristics of its buildings. I broke down the city to have two general types of building structures: 19th/20th century apartments, and modern skyscrapers.

For 19th/20th century apartments, I used two reference images.

![](./img/ref1.jpg)

The first image is of the New York Times building constructed in 1889 and is still standing today. What I took from this image is that there are 1-story as well as 2-story windows. In addition, arched windows seem like a common decor. The other 19th/20th century apartment image is black and white, so the brown-yellow coloring of this building also tells me more about the material used to construct it.

![](./img/ref2.jpg)

The second image is of the Old Metropolitan Opera House built in 1883 near Times Square. There generally seems to have an extruded "ledge" near the top of every window. In addition, the roof is relatively flat and has multiple "ledge" extrusions.

For modern skyscrapers, I used a reference image of the Wall Street skyline.

![](./img/ref3.jpg)

The modern skyscrapers are a lot simpler compared to the 19th/20th century apartments. Either the windows on each floor are horizontally aligned or vertically aligned. In addition, the color of the buildings have a blue tint because the windows are generally reflecting the colors of the sky.

## Building Design
I decided that each building will be made up of a bunch of sculpted unit cubes. That way, I can easily move them around to make differently shaped buildings. I have a pet peeve of having an exact reason for every decision I make in designing things, so I based all my cuts and extrusions on the Golden Ratio. Modeling every piece of the building using the Golden Ratio took a weekend to do.

Unfortunately, I ended up not using the arched windows because they had too many polygons and slowed down the program immensely. In addition, I had to take advantage of the simple structure of the New York skyscrapers, and made all the floors of the skyscraper one vertically-stretched out window. If I did not do that, the program would lag a lot.

![](./img/model1.png)

## Shape Node
Each shape node contains the following variables:
- String to keep track of the associating symbol to this shape
- 4x4 Matrix to keep track of position and rotation (similar to a scene graph)
- Vector3 to keep track of the building scale
- Boolean whether the shape is terminal or not
- String to keep track of which geometry type to apply these other parameters to.

## City Design
The grid system New York City uses seemed a little boring, so I decided to spice it up a bit. I used stratified sampling (yay advanced computer graphics!) to generate a Voronoi Diagram. The edges on the Voronoi Diagram represents the streets of the city. The reason for the stratified sampling is so that not many streets will clash with one another in a single area.

Using a gain function (yay toolbox functions!), I modeled the popluation density of the city so that the center of the city has the highest population, and decreases as you move farther away from the center. The higher the population density, the taller the buildings. Since 19th/20th century apartments are generally no taller than 30 stories, and skyscrapers are usually taller than 30 stories, I made it so that buildings less than 30 stories are apartments, and buildings taller than 30 stories are skyscrapers.

I colored the buildings with a gain function so that the farther away a building is from the center, the darker the color. In addition, I applied IQ's color gradient implementation (yay color mapping!) to the apartment buildings. The taller the apartment building, the more of the brownish-yellow gradient you can see. I did not do this with the skyscrapers because the floors of the skyscrapers is generated by stretching out one window mesh.

## Grammar Design
![](./img/shapegrammar1.JPG)

![](./img/shapegrammar2.JPG)

![](./img/shapegrammar3.JPG)

## Optimizations
- Did not save geometry in each Shape Node. Instead, just used the geom_type to add the geometry to the scene.
- Removed unneeded "new" keywords because web browser garbage collection is not that great.
- Removed arched windows because they had too many polygons.
- Made all the floors of the skyscraper one vertically-stretched out window.
- Deleted unseen faces of each building geometry model to avoid unncessary lambertian shading.

![](./img/model2.png)

38 changes: 38 additions & 0 deletions deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var colors = require('colors');
var path = require('path');
var git = require('simple-git')(__dirname);
var deploy = require('gh-pages-deploy');
var packageJSON = require('require-module')('./package.json');

var success = 1;
git.fetch('origin', 'master', function(err) {
if (err) throw err;
git.status(function(err, status) {
if (err) throw err;
if (!status.isClean()) {
success = 0;
console.error('Error: You have uncommitted changes! Please commit them first'.red);
}

if (status.current !== 'master') {
success = 0;
console.warn('Warning: Please deploy from the master branch!'.yellow)
}

git.diffSummary(['origin/master'], function(err, diff) {
if (err) throw err;

if (diff.files.length || diff.insertions || diff.deletions) {
success = 0;
console.error('Error: Current branch is different from origin/master! Please push all changes first'.red)
}

if (success) {
var cfg = packageJSON['gh-pages-deploy'] || {};
var buildCmd = deploy.getFullCmd(cfg);
deploy.displayCmds(deploy.getFullCmd(cfg));
deploy.execBuild(buildCmd, cfg);
}
})
})
})
Binary file added geo/.DS_Store
Binary file not shown.
162 changes: 162 additions & 0 deletions geo/SimpleApartmentBaseCorner.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# This file uses centimeters as units for non-parametric coordinates.

v -0.500000 1.000000 0.354000
v 0.354000 1.000000 0.354000
v -0.500000 2.000000 0.354000
v 0.354000 2.000000 0.354000
v -0.500000 2.000000 -0.500000
v 0.354000 2.000000 -0.500000
v 0.354000 1.000000 -0.500000
v 0.354000 1.763933 -0.500000
v -0.500000 1.763933 0.354000
v 0.354000 1.763933 0.354000
v 0.354000 1.763933 0.500000
v 0.354000 2.000000 0.500000
v -0.500000 1.763933 0.500000
v -0.500000 2.000000 0.500000
v 0.500000 1.763933 -0.500000
v 0.500000 1.763933 0.354000
v 0.500000 2.000000 -0.500000
v 0.500000 2.000000 0.354000
v 0.500000 2.000000 0.500000
v 0.500000 1.763933 0.500000
v -0.500000 1.000000 0.354000
v 0.354000 1.000000 0.354000
v 0.354000 1.000000 -0.500000
v -0.500000 0.382000 0.354000
v 0.354000 0.382000 0.354000
v 0.354000 0.382000 -0.500000
v -0.500000 0.000000 0.444233
v 0.354000 0.000000 0.444233
v 0.354000 0.382000 0.444233
v -0.500000 0.382000 0.444233
v 0.444000 0.000000 -0.500000
v 0.444000 0.000000 0.354000
v 0.444000 0.382000 -0.500000
v 0.444000 0.382000 0.354000
v 0.444000 0.382000 0.444233
v 0.444000 0.000000 0.444233
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.875000 0.000000
vt 0.875000 0.250000
vt 0.875000 0.190983
vt 0.375000 0.190983
vt 0.625000 0.190983
vt 0.625000 0.190983
vt 0.625000 0.250000
vt 0.375000 0.190983
vt 0.375000 0.250000
vt 0.625000 0.190983
vt 0.875000 0.190983
vt 0.875000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.190983
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.095500
vt 0.375000 0.095500
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.000000
vt 0.875000 0.000000
vt 0.875000 0.095500
vt 0.625000 0.095500
vt 0.375000 0.095500
vt 0.625000 0.095500
vt 0.875000 0.095500
vt 0.875000 0.250000
vt 0.625000 0.095500
vt 0.625000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
f 2/2/1 7/7/2 8/9/3 10/11/4
f 5/5/5 3/3/6 4/4/7 6/6/8
f 9/10/9 1/1/10 2/2/11 10/11/12
f 16/16/13 15/17/14 17/18/15 18/19/16
f 14/15/17 13/14/18 11/12/19 12/13/20
f 16/16/13 18/19/16 19/20/21 20/21/22
f 14/15/23 12/13/24 4/4/7 3/3/6
f 13/14/25 9/10/26 10/11/27 11/12/28
f 10/11/27 8/9/29 15/17/30 16/16/31
f 6/8/8 4/4/7 18/19/32 17/18/33
f 4/4/7 12/13/24 19/20/34 18/19/32
f 12/13/20 11/12/19 20/21/35 19/20/36
f 11/12/28 10/11/27 16/16/31 20/21/37
f 27/22/38 28/23/39 29/24/40 30/25/41
f 32/28/42 31/29/43 33/30/44 34/31/45
f 24/32/46 25/33/47 22/27/48 21/26/49
f 25/33/50 26/34/51 23/35/52 22/27/53
f 32/28/42 34/31/45 35/36/54 36/37/55
f 25/33/56 24/32/57 30/25/58 29/24/59
f 26/34/60 25/33/56 34/31/61 33/30/62
f 25/33/56 29/24/59 35/36/63 34/31/61
f 29/24/40 28/23/39 36/37/64 35/36/65
80 changes: 80 additions & 0 deletions geo/SimpleApartmentBaseSide.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# This file uses centimeters as units for non-parametric coordinates.

v -0.500000 1.000000 0.354000
v 0.500000 1.000000 0.354000
v -0.500000 2.000000 0.354000
v 0.500000 2.000000 0.354000
v -0.500000 2.000000 -0.500000
v 0.500000 2.000000 -0.500000
v -0.500000 1.763933 0.354000
v 0.500000 1.763933 0.354000
v 0.500000 1.763933 0.500000
v 0.500000 2.000000 0.500000
v -0.500000 1.763933 0.500000
v -0.500000 2.000000 0.500000
v -0.500000 1.000000 0.354000
v 0.500000 1.000000 0.354000
v -0.500000 0.382000 0.354000
v 0.500000 0.382000 0.354000
v -0.500000 0.000000 0.444233
v 0.500000 0.000000 0.444233
v 0.500000 0.382000 0.444233
v -0.500000 0.382000 0.444233
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.375000 0.190983
vt 0.625000 0.190983
vt 0.625000 0.190983
vt 0.625000 0.250000
vt 0.375000 0.190983
vt 0.375000 0.250000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.095500
vt 0.375000 0.095500
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.625000 0.095500
vt 0.375000 0.095500
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
f 5/5/1 3/3/2 4/4/3 6/6/4
f 7/7/5 1/1/6 2/2/7 8/8/8
f 12/12/9 11/11/10 9/9/11 10/10/12
f 12/12/13 10/10/14 4/4/3 3/3/2
f 11/11/15 7/7/16 8/8/17 9/9/18
f 17/13/19 18/14/20 19/15/21 20/16/22
f 15/20/23 16/19/24 14/18/25 13/17/26
f 16/19/27 15/20/28 20/16/29 19/15/30
Loading