Skip to content

Instantly share code, notes, and snippets.

@alecperkins
Last active August 29, 2015 14:07
Show Gist options
  • Select an option

  • Save alecperkins/54e63051921ab501404d to your computer and use it in GitHub Desktop.

Select an option

Save alecperkins/54e63051921ab501404d to your computer and use it in GitHub Desktop.

Revisions

  1. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 21 additions and 6 deletions.
    27 changes: 21 additions & 6 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -33,7 +33,7 @@ scene.add(camera)

    renderer = new WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(0xAACDE5,1)
    renderer.setClearColor(0xD8E6F7,1)
    document.body.appendChild(renderer.domElement)

    origin =
    @@ -117,15 +117,30 @@ generateBuilding = (width_n=2) ->


    base = new BoxGeometry(width, height, depth)


    base_materal = new MeshLambertMaterial(color: 0xFFFFFF)
    base_mesh = new Mesh(base)
    base_bsp = new ThreeBSP(base_mesh)

    window_bsps.forEach (w) -> base_bsp = base_bsp.subtract(w)
    sill_bsps.forEach (s) -> base_bsp = base_bsp.union(s)

    if width_n > 2
    chimney_mesh = new Mesh(new BoxGeometry(10, 100, 20))
    chimney_mesh.position.x = -1 * (width / 2) + 5 + 0.1
    chimney_mesh.position.y = height / 2 + 50
    chimney_mesh.position.z = depth / 5
    console.log 'chimney_mesh', chimney_mesh
    chimney_bsp = new ThreeBSP(chimney_mesh)
    base_bsp = base_bsp.union(chimney_bsp)
    if Math.random() > 0.5
    chimney_mesh = new Mesh(new BoxGeometry(10, 100, 20))
    chimney_mesh.position.x = (width / 2) - 5 - 0.1
    chimney_mesh.position.y = height / 2 + 50
    chimney_mesh.position.z = depth / 5
    chimney_bsp = new ThreeBSP(chimney_mesh)
    base_bsp = base_bsp.union(chimney_bsp)

    base_mesh = base_bsp.toMesh(base_materal)
    # base_mesh.geometry.computeVertexNormals()
    base_mesh.receiveShadow = true

    roof_section = new Shape()
    @@ -171,7 +186,7 @@ buildings.forEach (b, i) ->
    _direction = if i % 2 is 0 then 1 else -1
    console.log previous_center, previous_width / 2, b.width / 2, total_width / 2
    _x = previous_center + previous_width / 2 + b.width / 2
    _y = -300 + _direction * Math.floor(Math.random() * 50)
    _y = -300 + _direction * Math.floor(Math.random() * 25 + 20)
    previous_width = b.width
    previous_center = _x

    @@ -269,7 +284,7 @@ generatePerson = ->


    sun = new DirectionalLight(0xffffff, 1)
    sun.position.set(-200, 100, 200)
    sun.position.set(-220, 150, 200)
    sun.castShadow = true
    scene.add(sun)

  2. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 15 additions and 1 deletion.
    16 changes: 15 additions & 1 deletion script.coffee
    Original file line number Diff line number Diff line change
    @@ -58,20 +58,31 @@ WINDOW_X_SPACING = 1.5 * WINDOW_WIDTH
    WINDOW_Y_SPACING = 1 * WINDOW_WIDTH
    WINDOW_X_MARGIN = WINDOW_WIDTH
    WINDOW_Y_MARGIN = WINDOW_WIDTH
    SILL_WIDTH = WINDOW_WIDTH * 1.25
    SILL_HEIGHT = 10
    SILL_DEPTH = 5
    generateWindow = ->
    space = new Mesh(
    new BoxGeometry(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_DEPTH * 2)
    )
    sill = new Mesh(
    new BoxGeometry(SILL_WIDTH, SILL_HEIGHT, SILL_DEPTH)
    )
    sill.position.y -= WINDOW_HEIGHT / 2 + SILL_HEIGHT / 2
    sill.position.z += SILL_DEPTH
    # Custom set position to keep the window components together.
    _setPosition = (x,y,z) ->
    space.position.x = x
    space.position.y = y
    space.position.z = z
    sill.position.x = x
    sill.position.y = y - (WINDOW_HEIGHT / 2)
    sill.position.z = z + SILL_DEPTH / 2
    return {
    # The space is used to subtract the gap for the window from the building.
    space: space
    frame: null
    sill: null
    sill: sill
    setPosition: _setPosition
    }

    @@ -89,6 +100,7 @@ generateBuilding = (width_n=2) ->

    # Generate the windows for the given unit width.
    window_bsps = []
    sill_bsps = []
    # window_meshes = []
    [0...width_n].forEach (col) ->
    [0...num_window_rows].forEach (row) ->
    @@ -100,6 +112,7 @@ generateBuilding = (width_n=2) ->
    _window.setPosition(_x, _y, _z)
    # window_meshes.push(_window.)
    window_bsps.push(new ThreeBSP(_window.space))
    sill_bsps.push(new ThreeBSP(_window.sill))



    @@ -110,6 +123,7 @@ generateBuilding = (width_n=2) ->
    base_mesh = new Mesh(base)
    base_bsp = new ThreeBSP(base_mesh)
    window_bsps.forEach (w) -> base_bsp = base_bsp.subtract(w)
    sill_bsps.forEach (s) -> base_bsp = base_bsp.union(s)
    base_mesh = base_bsp.toMesh(base_materal)
    # base_mesh.geometry.computeVertexNormals()
    base_mesh.receiveShadow = true
  3. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -185,7 +185,7 @@ PERSON_Z_SPACING = 200
    person_clothing_material = new MeshLambertMaterial(color: 0x111111)
    person_head_material = new MeshLambertMaterial(color: 0xd3af8e)
    # shoe_material = new MeshPhongMaterial(color: 0x000000)
    person_torso = new CylinderGeometry(4.5, 4.5, 26, 32)
    person_torso = new CylinderGeometry(4.5, 4.5, 24, 32)
    person_shoulders = new CylinderGeometry(1, 4.5, 2, 32)
    person_leg = new CylinderGeometry(1.25, 1.25, 8, 32)
    person_head = new SphereGeometry(2)
    @@ -198,7 +198,7 @@ generatePerson = ->
    person_clothing_material
    )
    _person_shoulders = new Mesh(person_shoulders, person_clothing_material)
    _person_shoulders.position.y += 13 + 1
    _person_shoulders.position.y += 12 + 1
    _person.add(_person_shoulders)
    _person.scale.set(1,1,0.5)
    _person_head = new Mesh(
    @@ -215,22 +215,22 @@ generatePerson = ->
    _person_hat.add(_person_hat_brim)
    _person_hat.position.y += 1
    _person_head.add(_person_hat)
    _person_head.position.y += 16
    _person_head.position.y += 15
    _person.add(_person_head)

    _person_leg_1 = new Mesh(
    person_leg
    person_clothing_material
    )
    _person_leg_1.position.y += -17
    _person_leg_1.position.y += -16
    _person_leg_1.position.x += 1.3
    _person.add(_person_leg_1)

    _person_leg_2 = new Mesh(
    person_leg
    person_clothing_material
    )
    _person_leg_2.position.y += -17
    _person_leg_2.position.y += -16
    _person_leg_2.position.x += -1.3
    _person.add(_person_leg_2)

  4. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion script.coffee
    Original file line number Diff line number Diff line change
    @@ -255,7 +255,7 @@ generatePerson = ->


    sun = new DirectionalLight(0xffffff, 1)
    sun.position.set(-300, 200, 200)
    sun.position.set(-200, 100, 200)
    sun.castShadow = true
    scene.add(sun)

  5. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion script.coffee
    Original file line number Diff line number Diff line change
    @@ -124,7 +124,7 @@ generateBuilding = (width_n=2) ->
    steps: 1
    amount: width
    bevelEnabled: false
    roof_material = new MeshLambertMaterial(color: 0xFF0000)
    roof_material = new MeshLambertMaterial(color: 0x7C4F55)
    roof_mesh = new Mesh(roof, roof_material)
    roof_mesh.receiveShadow = true
    roof_mesh.rotation.y = 0.5 * Math.PI
  6. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 79 additions and 10 deletions.
    89 changes: 79 additions & 10 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,20 @@
    DEBUG = false

    { Shape, DirectionalLight, AmbientLight, MeshLambertMaterial, Mesh, BoxGeometry, mergeGeometry, WebGLRenderer, Scene, PerspectiveCamera } = THREE
    {
    Shape
    DirectionalLight
    AmbientLight
    MeshLambertMaterial
    MeshPhongMaterial
    Mesh
    BoxGeometry
    mergeGeometry
    CylinderGeometry
    SphereGeometry
    WebGLRenderer
    Scene
    PerspectiveCamera
    } = THREE

    scene = new Scene()
    camera = new PerspectiveCamera(
    @@ -163,36 +177,91 @@ close_building.addToScene(scene)

    # Add the abducted/invading people

    person_geometry = new BoxGeometry(15, 40, 1)
    person_material = new MeshLambertMaterial(color: 0x00FF00)

    PERSON_X_SPACING = 100
    PERSON_Y_SPACING = 100
    PERSON_Z_SPACING = 200


    person_clothing_material = new MeshLambertMaterial(color: 0x111111)
    person_head_material = new MeshLambertMaterial(color: 0xd3af8e)
    # shoe_material = new MeshPhongMaterial(color: 0x000000)
    person_torso = new CylinderGeometry(4.5, 4.5, 26, 32)
    person_shoulders = new CylinderGeometry(1, 4.5, 2, 32)
    person_leg = new CylinderGeometry(1.25, 1.25, 8, 32)
    person_head = new SphereGeometry(2)
    person_hat = new CylinderGeometry(2, 2, 0.5, 32)
    person_hat_bowl = new SphereGeometry(2)
    person_hat_brim = new CylinderGeometry(3, 3, 0.1, 32)
    generatePerson = ->
    _person = new Mesh(
    person_torso
    person_clothing_material
    )
    _person_shoulders = new Mesh(person_shoulders, person_clothing_material)
    _person_shoulders.position.y += 13 + 1
    _person.add(_person_shoulders)
    _person.scale.set(1,1,0.5)
    _person_head = new Mesh(
    person_head
    person_head_material
    )

    _person_hat = new Mesh(person_hat, person_clothing_material)
    _person_hat_bowl = new Mesh(person_hat_bowl, person_clothing_material)
    _person_hat_brim = new Mesh(person_hat_brim, person_clothing_material)
    _person_hat_bowl.position.y += 0.25
    _person_hat_brim.position.y -= 0.25 + 0.1
    _person_hat.add(_person_hat_bowl)
    _person_hat.add(_person_hat_brim)
    _person_hat.position.y += 1
    _person_head.add(_person_hat)
    _person_head.position.y += 16
    _person.add(_person_head)

    _person_leg_1 = new Mesh(
    person_leg
    person_clothing_material
    )
    _person_leg_1.position.y += -17
    _person_leg_1.position.x += 1.3
    _person.add(_person_leg_1)

    _person_leg_2 = new Mesh(
    person_leg
    person_clothing_material
    )
    _person_leg_2.position.y += -17
    _person_leg_2.position.x += -1.3
    _person.add(_person_leg_2)

    return _person

    [-10..10].forEach (x) ->
    [-10..10].forEach (y) ->
    [0...3].forEach (z) ->
    person = new Mesh(
    person_geometry
    person_material
    )
    person = generatePerson()
    offset = if y % 2 then 0.5 else 0
    person.position.set(
    (x + offset) * PERSON_X_SPACING
    y * PERSON_Y_SPACING
    z * PERSON_Z_SPACING
    )
    _dir = if Math.random() > 0.5 then 1 else -1
    person.rotation.y += Math.random() * 0.2 * _dir
    # Only have the one layer cast shadows, to avoid needing a more
    # expensive lighting system that would correctly fade shadows.
    person.castShadow = z is 1
    scene.add(person)


    sun = new DirectionalLight(0xffffff, 1)
    sun.position.set(-400, 300, 200)
    sun.position.set(-300, 200, 200)
    sun.castShadow = true
    scene.add(sun)

    scene.add( new THREE.AmbientLight( 0x222222) )
    sky_light = new THREE.AmbientLight( 0x222222)
    sky_light.castShadow = true
    scene.add( sky_light )

    renderer.shadowMapEnabled = true
    renderer.shadowMapSoft = true
  7. Alec Perkins revised this gist Nov 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion script.coffee
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@ scene.add(camera)

    renderer = new WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(0xffffff,1)
    renderer.setClearColor(0xAACDE5,1)
    document.body.appendChild(renderer.domElement)

    origin =
  8. Alec Perkins revised this gist Nov 9, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion script.coffee
    Original file line number Diff line number Diff line change
    @@ -131,7 +131,7 @@ generateBuilding = (width_n=2) ->

    total_width = 0
    buildings = [0...6].map (i) ->
    b = generateBuilding(Math.floor(Math.random() * 4) + 1)
    b = generateBuilding(Math.floor(Math.random() * 4) + 2)
    total_width += b.width
    return b
    console.log 'total_width', total_width
  9. Alec Perkins revised this gist Nov 9, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -109,6 +109,7 @@ generateBuilding = (width_n=2) ->
    curveSegments: 1
    steps: 1
    amount: width
    bevelEnabled: false
    roof_material = new MeshLambertMaterial(color: 0xFF0000)
    roof_mesh = new Mesh(roof, roof_material)
    roof_mesh.receiveShadow = true
  10. Alec Perkins revised this gist Nov 9, 2014. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -153,6 +153,13 @@ buildings.forEach (b, i) ->
    b.addToScene(scene)


    close_building = generateBuilding(2)
    close_building.adjustPosition(250,0,510)
    close_building.mesh.rotation.y -= Math.PI / 3 * 1.5
    close_building.addToScene(scene)



    # Add the abducted/invading people

    person_geometry = new BoxGeometry(15, 40, 1)
  11. Alec Perkins revised this gist Nov 9, 2014. 1 changed file with 6 additions and 8 deletions.
    14 changes: 6 additions & 8 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -115,18 +115,16 @@ generateBuilding = (width_n=2) ->
    roof_mesh.rotation.y = 0.5 * Math.PI
    roof_mesh.position.x = width / -2

    _meshes = [base_mesh, roof_mesh]
    base_mesh.add(roof_mesh)
    building =
    width: width
    meshes: _meshes
    mesh: base_mesh
    adjustPosition: (_x, _y, _z) ->
    _meshes.forEach (mesh) ->
    mesh.position.x += _x
    mesh.position.y += _y
    mesh.position.z += _z
    base_mesh.position.x += _x
    base_mesh.position.y += _y
    base_mesh.position.z += _z
    addToScene: (_scene) ->
    _meshes.forEach (mesh) ->
    _scene.add(mesh)
    _scene.add(base_mesh)

    return building

  12. Alec Perkins revised this gist Nov 9, 2014. 1 changed file with 12 additions and 7 deletions.
    19 changes: 12 additions & 7 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -66,7 +66,7 @@ generateBuilding = (width_n=2) ->
    num_window_rows = 3
    # Dimensions of the base. The width is based on the window width and spacing.
    height = 400
    depth = 200
    depth = 180
    width = width_n * WINDOW_WIDTH + 2 * WINDOW_X_MARGIN + (width_n - 1) * WINDOW_X_SPACING
    roof_height = 80

    @@ -78,12 +78,9 @@ generateBuilding = (width_n=2) ->
    # window_meshes = []
    [0...width_n].forEach (col) ->
    [0...num_window_rows].forEach (row) ->
    console.log "row: #{ row }, col: #{ col }"
    console.log WINDOW_WIDTH, WINDOW_X_MARGIN, WINDOW_X_SPACING
    _y = win_origin_y - WINDOW_Y_MARGIN - (WINDOW_HEIGHT / 2) * (row + 1) - (WINDOW_Y_SPACING + (WINDOW_HEIGHT / 2)) * row
    _x = win_origin_x - WINDOW_X_MARGIN - (WINDOW_WIDTH / 2) * (col + 1) - (WINDOW_X_SPACING + (WINDOW_WIDTH / 2)) * col
    _z = depth / 2
    console.log win_origin_x, _x

    _window = generateWindow()
    _window.setPosition(_x, _y, _z)
    @@ -136,17 +133,25 @@ generateBuilding = (width_n=2) ->
    total_width = 0
    buildings = [0...6].map (i) ->
    b = generateBuilding(Math.floor(Math.random() * 4) + 1)
    console.log 'b.width', b.width
    total_width += b.width
    return b
    console.log 'total_width', total_width


    previous_center = 0
    previous_width = 0
    buildings.forEach (b, i) ->
    _direction = if i % 2 is 0 then 1 else -1
    _x = -1 * total_width / 2 + previous_width
    console.log previous_center, previous_width / 2, b.width / 2, total_width / 2
    _x = previous_center + previous_width / 2 + b.width / 2
    _y = -300 + _direction * Math.floor(Math.random() * 50)
    previous_width = b.width
    previous_center = _x

    # Apply offset after to avoid a mess with signs.
    _x -= total_width / 2

    b.adjustPosition(_x, _y, 100)
    previous_width += b.width
    b.addToScene(scene)


  13. Alec Perkins revised this gist Oct 27, 2014. 1 changed file with 36 additions and 7 deletions.
    43 changes: 36 additions & 7 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -63,9 +63,9 @@ generateWindow = ->


    generateBuilding = (width_n=2) ->
    num_window_rows = 2
    num_window_rows = 3
    # Dimensions of the base. The width is based on the window width and spacing.
    height = 300
    height = 400
    depth = 200
    width = width_n * WINDOW_WIDTH + 2 * WINDOW_X_MARGIN + (width_n - 1) * WINDOW_X_SPACING
    roof_height = 80
    @@ -117,11 +117,40 @@ generateBuilding = (width_n=2) ->
    roof_mesh.receiveShadow = true
    roof_mesh.rotation.y = 0.5 * Math.PI
    roof_mesh.position.x = width / -2
    return [base_mesh, roof_mesh]

    generateBuilding(3).forEach (geom) ->
    geom.position.y -= 200
    scene.add(geom)
    _meshes = [base_mesh, roof_mesh]
    building =
    width: width
    meshes: _meshes
    adjustPosition: (_x, _y, _z) ->
    _meshes.forEach (mesh) ->
    mesh.position.x += _x
    mesh.position.y += _y
    mesh.position.z += _z
    addToScene: (_scene) ->
    _meshes.forEach (mesh) ->
    _scene.add(mesh)

    return building

    total_width = 0
    buildings = [0...6].map (i) ->
    b = generateBuilding(Math.floor(Math.random() * 4) + 1)
    console.log 'b.width', b.width
    total_width += b.width
    return b
    console.log 'total_width', total_width
    previous_width = 0
    buildings.forEach (b, i) ->
    _direction = if i % 2 is 0 then 1 else -1
    _x = -1 * total_width / 2 + previous_width
    _y = -300 + _direction * Math.floor(Math.random() * 50)
    b.adjustPosition(_x, _y, 100)
    previous_width += b.width
    b.addToScene(scene)


    # Add the abducted/invading people

    person_geometry = new BoxGeometry(15, 40, 1)
    person_material = new MeshLambertMaterial(color: 0x00FF00)
    @@ -155,7 +184,7 @@ scene.add(sun)
    scene.add( new THREE.AmbientLight( 0x222222) )

    renderer.shadowMapEnabled = true
    renderer.shadowMapSoft = false
    renderer.shadowMapSoft = true

    renderer.shadowCameraNear = 3
    renderer.shadowCameraFar = camera.far
  14. Alec Perkins revised this gist Oct 27, 2014. 1 changed file with 38 additions and 18 deletions.
    56 changes: 38 additions & 18 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -39,10 +39,14 @@ unless DEBUG

    WINDOW_WIDTH = 40
    WINDOW_HEIGHT = 80
    WINDOW_DEPTH = 10
    WINDOW_DEPTH = 10 # Depth of window from surface of facade.
    WINDOW_X_SPACING = 1.5 * WINDOW_WIDTH
    WINDOW_Y_SPACING = 1 * WINDOW_WIDTH
    WINDOW_X_MARGIN = WINDOW_WIDTH
    WINDOW_Y_MARGIN = WINDOW_WIDTH
    generateWindow = ->
    space = new Mesh(
    new BoxGeometry(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_DEPTH * 3)
    new BoxGeometry(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_DEPTH * 2)
    )
    # Custom set position to keep the window components together.
    _setPosition = (x,y,z) ->
    @@ -57,30 +61,46 @@ generateWindow = ->
    setPosition: _setPosition
    }

    generateBuilding = (width_multi=2) ->

    generateBuilding = (width_n=2) ->
    num_window_rows = 2
    # Dimensions of the base. The width is based on the window width and spacing.
    height = 300
    width = 1300
    depth = 200
    roof_height = 120
    width = width_n * WINDOW_WIDTH + 2 * WINDOW_X_MARGIN + (width_n - 1) * WINDOW_X_SPACING
    roof_height = 80

    win_origin_x = width / 2
    win_origin_y = height / 2

    # Generate the windows for the given unit width.
    window_bsps = []
    # window_meshes = []
    [0...width_n].forEach (col) ->
    [0...num_window_rows].forEach (row) ->
    console.log "row: #{ row }, col: #{ col }"
    console.log WINDOW_WIDTH, WINDOW_X_MARGIN, WINDOW_X_SPACING
    _y = win_origin_y - WINDOW_Y_MARGIN - (WINDOW_HEIGHT / 2) * (row + 1) - (WINDOW_Y_SPACING + (WINDOW_HEIGHT / 2)) * row
    _x = win_origin_x - WINDOW_X_MARGIN - (WINDOW_WIDTH / 2) * (col + 1) - (WINDOW_X_SPACING + (WINDOW_WIDTH / 2)) * col
    _z = depth / 2
    console.log win_origin_x, _x

    _window = generateWindow()
    _window.setPosition(_x, _y, _z)
    # window_meshes.push(_window.)
    window_bsps.push(new ThreeBSP(_window.space))



    base = new BoxGeometry(width, height, depth)

    # var sphere_bsp = new ThreeBSP( sphere_mesh );

    # var subtract_bsp = cube_bsp.subtract( sphere_bsp );
    # var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('texture.png') }) );
    # result.geometry.computeVertexNormals();

    base_materal = new MeshLambertMaterial(color: 0xFFFFFF)
    base_mesh = new Mesh(base)

    windows = (generateWindow() for i in [0..3])
    console.log 'windows', windows
    win = windows[0]
    win.setPosition(0,0,100)
    base_bsp = new ThreeBSP(base_mesh)
    win_bsp = new ThreeBSP(win.space)
    base_mesh = base_bsp.subtract(win_bsp).toMesh(base_materal)
    window_bsps.forEach (w) -> base_bsp = base_bsp.subtract(w)
    base_mesh = base_bsp.toMesh(base_materal)
    # base_mesh.geometry.computeVertexNormals()
    base_mesh.receiveShadow = true

    roof_section = new Shape()
    @@ -99,7 +119,7 @@ generateBuilding = (width_multi=2) ->
    roof_mesh.position.x = width / -2
    return [base_mesh, roof_mesh]

    generateBuilding().forEach (geom) ->
    generateBuilding(3).forEach (geom) ->
    geom.position.y -= 200
    scene.add(geom)

  15. Alec Perkins revised this gist Oct 27, 2014. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ DEBUG = false

    scene = new Scene()
    camera = new PerspectiveCamera(
    75
    70
    window.innerWidth / window.innerHeight
    0.1
    1000
    @@ -14,7 +14,7 @@ if DEBUG
    camera.position.set(400,200,400)
    camera.lookAt(x:0,y:0,z:0)
    else
    camera.position.z = 400
    camera.position.z = 600
    scene.add(camera)

    renderer = new WebGLRenderer()
    @@ -108,7 +108,7 @@ person_material = new MeshLambertMaterial(color: 0x00FF00)

    PERSON_X_SPACING = 100
    PERSON_Y_SPACING = 100
    PERSON_Z_SPACING = 100
    PERSON_Z_SPACING = 200

    [-10..10].forEach (x) ->
    [-10..10].forEach (y) ->
  16. Alec Perkins revised this gist Oct 26, 2014. 1 changed file with 41 additions and 6 deletions.
    47 changes: 41 additions & 6 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -37,13 +37,52 @@ unless DEBUG
    camera.position.y = rel_y * SCALE_FACTOR
    requestAnimationFrame(render)


    generateBuilding = ->
    WINDOW_WIDTH = 40
    WINDOW_HEIGHT = 80
    WINDOW_DEPTH = 10
    generateWindow = ->
    space = new Mesh(
    new BoxGeometry(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_DEPTH * 3)
    )
    # Custom set position to keep the window components together.
    _setPosition = (x,y,z) ->
    space.position.x = x
    space.position.y = y
    space.position.z = z
    return {
    # The space is used to subtract the gap for the window from the building.
    space: space
    frame: null
    sill: null
    setPosition: _setPosition
    }

    generateBuilding = (width_multi=2) ->
    height = 300
    width = 1300
    depth = 200
    roof_height = 120

    base = new BoxGeometry(width, height, depth)

    # var sphere_bsp = new ThreeBSP( sphere_mesh );

    # var subtract_bsp = cube_bsp.subtract( sphere_bsp );
    # var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('texture.png') }) );
    # result.geometry.computeVertexNormals();

    base_materal = new MeshLambertMaterial(color: 0xFFFFFF)
    base_mesh = new Mesh(base)

    windows = (generateWindow() for i in [0..3])
    console.log 'windows', windows
    win = windows[0]
    win.setPosition(0,0,100)
    base_bsp = new ThreeBSP(base_mesh)
    win_bsp = new ThreeBSP(win.space)
    base_mesh = base_bsp.subtract(win_bsp).toMesh(base_materal)
    base_mesh.receiveShadow = true

    roof_section = new Shape()
    roof_section.moveTo(depth / -2, height / 2)
    roof_section.lineTo(0, height / 2 + roof_height)
    @@ -53,12 +92,8 @@ generateBuilding = ->
    curveSegments: 1
    steps: 1
    amount: width
    building = []
    base_materal = new MeshLambertMaterial(color: 0xFFFFFF)
    roof_material = new MeshLambertMaterial(color: 0xFF0000)
    base_mesh = new Mesh(base, base_materal)
    roof_mesh = new Mesh(roof, roof_material)
    base_mesh.receiveShadow = true
    roof_mesh.receiveShadow = true
    roof_mesh.rotation.y = 0.5 * Math.PI
    roof_mesh.position.x = width / -2
  17. Alec Perkins revised this gist Oct 26, 2014. 1 changed file with 553 additions and 0 deletions.
    553 changes: 553 additions & 0 deletions markup.jade
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,553 @@
    script.
    // https://github.com/chandlerprall/ThreeCSG/
    window.ThreeBSP = (function() {

    var ThreeBSP,
    EPSILON = 1e-5,
    COPLANAR = 0,
    FRONT = 1,
    BACK = 2,
    SPANNING = 3;

    ThreeBSP = function( geometry ) {
    // Convert THREE.Geometry to ThreeBSP
    var i, _length_i,
    face, vertex, faceVertexUvs, uvs,
    polygon,
    polygons = [],
    tree;

    if ( geometry instanceof THREE.Geometry ) {
    this.matrix = new THREE.Matrix4;
    } else if ( geometry instanceof THREE.Mesh ) {
    // #todo: add hierarchy support
    geometry.updateMatrix();
    this.matrix = geometry.matrix.clone();
    geometry = geometry.geometry;
    } else if ( geometry instanceof ThreeBSP.Node ) {
    this.tree = geometry;
    this.matrix = new THREE.Matrix4;
    return this;
    } else {
    throw 'ThreeBSP: Given geometry is unsupported';
    }

    for ( i = 0, _length_i = geometry.faces.length; i < _length_i; i++ ) {
    face = geometry.faces[i];
    faceVertexUvs = geometry.faceVertexUvs[0][i];
    polygon = new ThreeBSP.Polygon;

    if ( face instanceof THREE.Face3 ) {
    vertex = geometry.vertices[ face.a ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[0].x, faceVertexUvs[0].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );

    vertex = geometry.vertices[ face.b ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[1].x, faceVertexUvs[1].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );

    vertex = geometry.vertices[ face.c ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[2].x, faceVertexUvs[2].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );
    } else if ( typeof THREE.Face4 ) {
    vertex = geometry.vertices[ face.a ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[0].x, faceVertexUvs[0].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );

    vertex = geometry.vertices[ face.b ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[1].x, faceVertexUvs[1].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );

    vertex = geometry.vertices[ face.c ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[2].x, faceVertexUvs[2].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );

    vertex = geometry.vertices[ face.d ];
    uvs = faceVertexUvs ? new THREE.Vector2( faceVertexUvs[3].x, faceVertexUvs[3].y ) : null;
    vertex = new ThreeBSP.Vertex( vertex.x, vertex.y, vertex.z, face.vertexNormals[3], uvs );
    vertex.applyMatrix4(this.matrix);
    polygon.vertices.push( vertex );
    } else {
    throw 'Invalid face type at index ' + i;
    }

    polygon.calculateProperties();
    polygons.push( polygon );
    };

    this.tree = new ThreeBSP.Node( polygons );
    };
    ThreeBSP.prototype.subtract = function( other_tree ) {
    var a = this.tree.clone(),
    b = other_tree.tree.clone();

    a.invert();
    a.clipTo( b );
    b.clipTo( a );
    b.invert();
    b.clipTo( a );
    b.invert();
    a.build( b.allPolygons() );
    a.invert();
    a = new ThreeBSP( a );
    a.matrix = this.matrix;
    return a;
    };
    ThreeBSP.prototype.union = function( other_tree ) {
    var a = this.tree.clone(),
    b = other_tree.tree.clone();

    a.clipTo( b );
    b.clipTo( a );
    b.invert();
    b.clipTo( a );
    b.invert();
    a.build( b.allPolygons() );
    a = new ThreeBSP( a );
    a.matrix = this.matrix;
    return a;
    };
    ThreeBSP.prototype.intersect = function( other_tree ) {
    var a = this.tree.clone(),
    b = other_tree.tree.clone();

    a.invert();
    b.clipTo( a );
    b.invert();
    a.clipTo( b );
    b.clipTo( a );
    a.build( b.allPolygons() );
    a.invert();
    a = new ThreeBSP( a );
    a.matrix = this.matrix;
    return a;
    };
    ThreeBSP.prototype.toGeometry = function() {
    var i, j,
    matrix = new THREE.Matrix4().getInverse( this.matrix ),
    geometry = new THREE.Geometry(),
    polygons = this.tree.allPolygons(),
    polygon_count = polygons.length,
    polygon, polygon_vertice_count,
    vertice_dict = {},
    vertex_idx_a, vertex_idx_b, vertex_idx_c,
    vertex, face,
    verticeUvs;

    for ( i = 0; i < polygon_count; i++ ) {
    polygon = polygons[i];
    polygon_vertice_count = polygon.vertices.length;

    for ( j = 2; j < polygon_vertice_count; j++ ) {
    verticeUvs = [];

    vertex = polygon.vertices[0];
    verticeUvs.push( new THREE.Vector2( vertex.uv.x, vertex.uv.y ) );
    vertex = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
    vertex.applyMatrix4(matrix);

    if ( typeof vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] !== 'undefined' ) {
    vertex_idx_a = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
    } else {
    geometry.vertices.push( vertex );
    vertex_idx_a = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = geometry.vertices.length - 1;
    }

    vertex = polygon.vertices[j-1];
    verticeUvs.push( new THREE.Vector2( vertex.uv.x, vertex.uv.y ) );
    vertex = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
    vertex.applyMatrix4(matrix);
    if ( typeof vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] !== 'undefined' ) {
    vertex_idx_b = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
    } else {
    geometry.vertices.push( vertex );
    vertex_idx_b = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = geometry.vertices.length - 1;
    }

    vertex = polygon.vertices[j];
    verticeUvs.push( new THREE.Vector2( vertex.uv.x, vertex.uv.y ) );
    vertex = new THREE.Vector3( vertex.x, vertex.y, vertex.z );
    vertex.applyMatrix4(matrix);
    if ( typeof vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] !== 'undefined' ) {
    vertex_idx_c = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
    } else {
    geometry.vertices.push( vertex );
    vertex_idx_c = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = geometry.vertices.length - 1;
    }

    face = new THREE.Face3(
    vertex_idx_a,
    vertex_idx_b,
    vertex_idx_c,
    new THREE.Vector3( polygon.normal.x, polygon.normal.y, polygon.normal.z )
    );

    geometry.faces.push( face );
    geometry.faceVertexUvs[0].push( verticeUvs );
    }

    }
    return geometry;
    };
    ThreeBSP.prototype.toMesh = function( material ) {
    var geometry = this.toGeometry(),
    mesh = new THREE.Mesh( geometry, material );

    mesh.position.setFromMatrixPosition( this.matrix );
    mesh.rotation.setFromRotationMatrix( this.matrix );

    return mesh;
    };


    ThreeBSP.Polygon = function( vertices, normal, w ) {
    if ( !( vertices instanceof Array ) ) {
    vertices = [];
    }

    this.vertices = vertices;
    if ( vertices.length > 0 ) {
    this.calculateProperties();
    } else {
    this.normal = this.w = undefined;
    }
    };
    ThreeBSP.Polygon.prototype.calculateProperties = function() {
    var a = this.vertices[0],
    b = this.vertices[1],
    c = this.vertices[2];

    this.normal = b.clone().subtract( a ).cross(
    c.clone().subtract( a )
    ).normalize();

    this.w = this.normal.clone().dot( a );

    return this;
    };
    ThreeBSP.Polygon.prototype.clone = function() {
    var i, vertice_count,
    polygon = new ThreeBSP.Polygon;

    for ( i = 0, vertice_count = this.vertices.length; i < vertice_count; i++ ) {
    polygon.vertices.push( this.vertices[i].clone() );
    };
    polygon.calculateProperties();

    return polygon;
    };

    ThreeBSP.Polygon.prototype.flip = function() {
    var i, vertices = [];

    this.normal.multiplyScalar( -1 );
    this.w *= -1;

    for ( i = this.vertices.length - 1; i >= 0; i-- ) {
    vertices.push( this.vertices[i] );
    };
    this.vertices = vertices;

    return this;
    };
    ThreeBSP.Polygon.prototype.classifyVertex = function( vertex ) {
    var side_value = this.normal.dot( vertex ) - this.w;

    if ( side_value < -EPSILON ) {
    return BACK;
    } else if ( side_value > EPSILON ) {
    return FRONT;
    } else {
    return COPLANAR;
    }
    };
    ThreeBSP.Polygon.prototype.classifySide = function( polygon ) {
    var i, vertex, classification,
    num_positive = 0,
    num_negative = 0,
    vertice_count = polygon.vertices.length;

    for ( i = 0; i < vertice_count; i++ ) {
    vertex = polygon.vertices[i];
    classification = this.classifyVertex( vertex );
    if ( classification === FRONT ) {
    num_positive++;
    } else if ( classification === BACK ) {
    num_negative++;
    }
    }

    if ( num_positive > 0 && num_negative === 0 ) {
    return FRONT;
    } else if ( num_positive === 0 && num_negative > 0 ) {
    return BACK;
    } else if ( num_positive === 0 && num_negative === 0 ) {
    return COPLANAR;
    } else {
    return SPANNING;
    }
    };
    ThreeBSP.Polygon.prototype.splitPolygon = function( polygon, coplanar_front, coplanar_back, front, back ) {
    var classification = this.classifySide( polygon );

    if ( classification === COPLANAR ) {

    ( this.normal.dot( polygon.normal ) > 0 ? coplanar_front : coplanar_back ).push( polygon );

    } else if ( classification === FRONT ) {

    front.push( polygon );

    } else if ( classification === BACK ) {

    back.push( polygon );

    } else {

    var vertice_count,
    i, j, ti, tj, vi, vj,
    t, v,
    f = [],
    b = [];

    for ( i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++ ) {

    j = (i + 1) % vertice_count;
    vi = polygon.vertices[i];
    vj = polygon.vertices[j];
    ti = this.classifyVertex( vi );
    tj = this.classifyVertex( vj );

    if ( ti != BACK ) f.push( vi );
    if ( ti != FRONT ) b.push( vi );
    if ( (ti | tj) === SPANNING ) {
    t = ( this.w - this.normal.dot( vi ) ) / this.normal.dot( vj.clone().subtract( vi ) );
    v = vi.interpolate( vj, t );
    f.push( v );
    b.push( v );
    }
    }


    if ( f.length >= 3 ) front.push( new ThreeBSP.Polygon( f ).calculateProperties() );
    if ( b.length >= 3 ) back.push( new ThreeBSP.Polygon( b ).calculateProperties() );
    }
    };

    ThreeBSP.Vertex = function( x, y, z, normal, uv ) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.normal = normal || new THREE.Vector3;
    this.uv = uv || new THREE.Vector2;
    };
    ThreeBSP.Vertex.prototype.clone = function() {
    return new ThreeBSP.Vertex( this.x, this.y, this.z, this.normal.clone(), this.uv.clone() );
    };
    ThreeBSP.Vertex.prototype.add = function( vertex ) {
    this.x += vertex.x;
    this.y += vertex.y;
    this.z += vertex.z;
    return this;
    };
    ThreeBSP.Vertex.prototype.subtract = function( vertex ) {
    this.x -= vertex.x;
    this.y -= vertex.y;
    this.z -= vertex.z;
    return this;
    };
    ThreeBSP.Vertex.prototype.multiplyScalar = function( scalar ) {
    this.x *= scalar;
    this.y *= scalar;
    this.z *= scalar;
    return this;
    };
    ThreeBSP.Vertex.prototype.cross = function( vertex ) {
    var x = this.x,
    y = this.y,
    z = this.z;

    this.x = y * vertex.z - z * vertex.y;
    this.y = z * vertex.x - x * vertex.z;
    this.z = x * vertex.y - y * vertex.x;

    return this;
    };
    ThreeBSP.Vertex.prototype.normalize = function() {
    var length = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );

    this.x /= length;
    this.y /= length;
    this.z /= length;

    return this;
    };
    ThreeBSP.Vertex.prototype.dot = function( vertex ) {
    return this.x * vertex.x + this.y * vertex.y + this.z * vertex.z;
    };
    ThreeBSP.Vertex.prototype.lerp = function( a, t ) {
    this.add(
    a.clone().subtract( this ).multiplyScalar( t )
    );

    this.normal.add(
    a.normal.clone().sub( this.normal ).multiplyScalar( t )
    );

    this.uv.add(
    a.uv.clone().sub( this.uv ).multiplyScalar( t )
    );

    return this;
    };
    ThreeBSP.Vertex.prototype.interpolate = function( other, t ) {
    return this.clone().lerp( other, t );
    };
    ThreeBSP.Vertex.prototype.applyMatrix4 = function ( m ) {

    // input: THREE.Matrix4 affine matrix

    var x = this.x, y = this.y, z = this.z;

    var e = m.elements;

    this.x = e[0] * x + e[4] * y + e[8] * z + e[12];
    this.y = e[1] * x + e[5] * y + e[9] * z + e[13];
    this.z = e[2] * x + e[6] * y + e[10] * z + e[14];

    return this;

    }


    ThreeBSP.Node = function( polygons ) {
    var i, polygon_count,
    front = [],
    back = [];

    this.polygons = [];
    this.front = this.back = undefined;

    if ( !(polygons instanceof Array) || polygons.length === 0 ) return;

    this.divider = polygons[0].clone();

    for ( i = 0, polygon_count = polygons.length; i < polygon_count; i++ ) {
    this.divider.splitPolygon( polygons[i], this.polygons, this.polygons, front, back );
    }

    if ( front.length > 0 ) {
    this.front = new ThreeBSP.Node( front );
    }

    if ( back.length > 0 ) {
    this.back = new ThreeBSP.Node( back );
    }
    };
    ThreeBSP.Node.isConvex = function( polygons ) {
    var i, j;
    for ( i = 0; i < polygons.length; i++ ) {
    for ( j = 0; j < polygons.length; j++ ) {
    if ( i !== j && polygons[i].classifySide( polygons[j] ) !== BACK ) {
    return false;
    }
    }
    }
    return true;
    };
    ThreeBSP.Node.prototype.build = function( polygons ) {
    var i, polygon_count,
    front = [],
    back = [];

    if ( !this.divider ) {
    this.divider = polygons[0].clone();
    }

    for ( i = 0, polygon_count = polygons.length; i < polygon_count; i++ ) {
    this.divider.splitPolygon( polygons[i], this.polygons, this.polygons, front, back );
    }

    if ( front.length > 0 ) {
    if ( !this.front ) this.front = new ThreeBSP.Node();
    this.front.build( front );
    }

    if ( back.length > 0 ) {
    if ( !this.back ) this.back = new ThreeBSP.Node();
    this.back.build( back );
    }
    };
    ThreeBSP.Node.prototype.allPolygons = function() {
    var polygons = this.polygons.slice();
    if ( this.front ) polygons = polygons.concat( this.front.allPolygons() );
    if ( this.back ) polygons = polygons.concat( this.back.allPolygons() );
    return polygons;
    };
    ThreeBSP.Node.prototype.clone = function() {
    var node = new ThreeBSP.Node();

    node.divider = this.divider.clone();
    node.polygons = this.polygons.map( function( polygon ) { return polygon.clone(); } );
    node.front = this.front && this.front.clone();
    node.back = this.back && this.back.clone();

    return node;
    };
    ThreeBSP.Node.prototype.invert = function() {
    var i, polygon_count, temp;

    for ( i = 0, polygon_count = this.polygons.length; i < polygon_count; i++ ) {
    this.polygons[i].flip();
    }

    this.divider.flip();
    if ( this.front ) this.front.invert();
    if ( this.back ) this.back.invert();

    temp = this.front;
    this.front = this.back;
    this.back = temp;

    return this;
    };
    ThreeBSP.Node.prototype.clipPolygons = function( polygons ) {
    var i, polygon_count,
    front, back;

    if ( !this.divider ) return polygons.slice();

    front = [], back = [];

    for ( i = 0, polygon_count = polygons.length; i < polygon_count; i++ ) {
    this.divider.splitPolygon( polygons[i], front, back, front, back );
    }

    if ( this.front ) front = this.front.clipPolygons( front );
    if ( this.back ) back = this.back.clipPolygons( back );
    else back = [];

    return front.concat( back );
    };

    ThreeBSP.Node.prototype.clipTo = function( node ) {
    this.polygons = node.clipPolygons( this.polygons );
    if ( this.front ) this.front.clipTo( node );
    if ( this.back ) this.back.clipTo( node );
    };


    return ThreeBSP;
    })();
  18. Alec Perkins revised this gist Oct 23, 2014. 1 changed file with 42 additions and 21 deletions.
    63 changes: 42 additions & 21 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,9 @@
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(
    DEBUG = false

    { Shape, DirectionalLight, AmbientLight, MeshLambertMaterial, Mesh, BoxGeometry, mergeGeometry, WebGLRenderer, Scene, PerspectiveCamera } = THREE

    scene = new Scene()
    camera = new PerspectiveCamera(
    75
    window.innerWidth / window.innerHeight
    0.1
    @@ -14,7 +17,7 @@ else
    camera.position.z = 400
    scene.add(camera)

    renderer = new THREE.WebGLRenderer()
    renderer = new WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(0xffffff,1)
    document.body.appendChild(renderer.domElement)
    @@ -23,14 +26,6 @@ origin =
    x: window.innerWidth / 2
    y: window.innerHeight / 2







    person_geometry = new THREE.BoxGeometry(15, 40, 1)
    person_material = new THREE.MeshLambertMaterial(color: 0x00FF00)
    unless DEBUG
    renderer.domElement.addEventListener 'mousemove', (e) ->
    # Convert the screen coordinates to world
    @@ -42,14 +37,48 @@ unless DEBUG
    camera.position.y = rel_y * SCALE_FACTOR
    requestAnimationFrame(render)


    generateBuilding = ->
    height = 300
    width = 1300
    depth = 200
    roof_height = 120
    base = new BoxGeometry(width, height, depth)
    roof_section = new Shape()
    roof_section.moveTo(depth / -2, height / 2)
    roof_section.lineTo(0, height / 2 + roof_height)
    roof_section.lineTo(depth / 2, height / 2)
    roof_section.lineTo(depth / -2, height / 2)
    roof = roof_section.extrude
    curveSegments: 1
    steps: 1
    amount: width
    building = []
    base_materal = new MeshLambertMaterial(color: 0xFFFFFF)
    roof_material = new MeshLambertMaterial(color: 0xFF0000)
    base_mesh = new Mesh(base, base_materal)
    roof_mesh = new Mesh(roof, roof_material)
    base_mesh.receiveShadow = true
    roof_mesh.receiveShadow = true
    roof_mesh.rotation.y = 0.5 * Math.PI
    roof_mesh.position.x = width / -2
    return [base_mesh, roof_mesh]

    generateBuilding().forEach (geom) ->
    geom.position.y -= 200
    scene.add(geom)

    person_geometry = new BoxGeometry(15, 40, 1)
    person_material = new MeshLambertMaterial(color: 0x00FF00)

    PERSON_X_SPACING = 100
    PERSON_Y_SPACING = 100
    PERSON_Z_SPACING = 100

    [-10..10].forEach (x) ->
    [-10..10].forEach (y) ->
    [0...3].forEach (z) ->
    person = new THREE.Mesh(
    person = new Mesh(
    person_geometry
    person_material
    )
    @@ -62,16 +91,8 @@ PERSON_Z_SPACING = 100
    person.castShadow = z is 1
    scene.add(person)

    building = new THREE.Mesh(
    new THREE.BoxGeometry(1400,300, 10)
    new THREE.MeshLambertMaterial(color: 0xffffff)
    )
    building.position.z = 90
    building.position.y = -180
    building.receiveShadow = true
    scene.add(building)

    sun = new THREE.DirectionalLight(0xffffff, 1)
    sun = new DirectionalLight(0xffffff, 1)
    sun.position.set(-400, 300, 200)
    sun.castShadow = true
    scene.add(sun)
  19. Alec Perkins revised this gist Oct 23, 2014. 1 changed file with 17 additions and 10 deletions.
    27 changes: 17 additions & 10 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,17 @@
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(
    DEBUG = false
    75
    window.innerWidth / window.innerHeight
    0.1
    1000
    )
    camera.position.z = 400

    if DEBUG
    camera.position.set(400,200,400)
    camera.lookAt(x:0,y:0,z:0)
    else
    camera.position.z = 400
    scene.add(camera)

    renderer = new THREE.WebGLRenderer()
    @@ -17,15 +23,6 @@ origin =
    x: window.innerWidth / 2
    y: window.innerHeight / 2

    renderer.domElement.addEventListener 'mousemove', (e) ->
    # Convert the screen coordinates to world
    rel_x = origin.x - e.pageX
    rel_y = e.pageY - origin.y
    # Adjust camera position
    SCALE_FACTOR = 0.05
    camera.position.x = rel_x * SCALE_FACTOR
    camera.position.y = rel_y * SCALE_FACTOR
    requestAnimationFrame(render)



    @@ -34,6 +31,16 @@ renderer.domElement.addEventListener 'mousemove', (e) ->

    person_geometry = new THREE.BoxGeometry(15, 40, 1)
    person_material = new THREE.MeshLambertMaterial(color: 0x00FF00)
    unless DEBUG
    renderer.domElement.addEventListener 'mousemove', (e) ->
    # Convert the screen coordinates to world
    rel_x = origin.x - e.pageX
    rel_y = e.pageY - origin.y
    # Adjust camera position
    SCALE_FACTOR = 0.05
    camera.position.x = rel_x * SCALE_FACTOR
    camera.position.y = rel_y * SCALE_FACTOR
    requestAnimationFrame(render)

    PERSON_X_SPACING = 100
    PERSON_Y_SPACING = 100
  20. Alec Perkins revised this gist Oct 20, 2014. 1 changed file with 0 additions and 0 deletions.
    Binary file added gonconda-1953.jpg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  21. Alec Perkins revised this gist Oct 20, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,7 @@ scene.add(camera)

    renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(0xffffff,1)
    document.body.appendChild(renderer.domElement)

    origin =
  22. Alec Perkins revised this gist Oct 20, 2014. 1 changed file with 46 additions and 29 deletions.
    75 changes: 46 additions & 29 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -1,23 +1,12 @@
    # Component = React.createClass
    # displayName: 'Component'
    # render: ->
    # <div className='Component'>
    # Component! {@props.time}
    # </div>

    # React.renderComponent(Component(time=new Date()), document.getElementById('app'))


    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(
    75
    window.innerWidth / window.innerHeight
    0.1
    1000
    )
    camera.position.z = 60


    camera.position.z = 400
    scene.add(camera)

    renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    @@ -32,39 +21,67 @@ renderer.domElement.addEventListener 'mousemove', (e) ->
    rel_x = origin.x - e.pageX
    rel_y = e.pageY - origin.y
    # Adjust camera position
    SCALE_FACTOR = 0.01
    SCALE_FACTOR = 0.05
    camera.position.x = rel_x * SCALE_FACTOR
    camera.position.y = rel_y * SCALE_FACTOR
    requestAnimationFrame(render)




    person = new THREE.BoxGeometry(1,2,0.1)
    material = new THREE.MeshLambertMaterial
    color: 0x00ff00

    PERSON_X_SPACING = 10
    PERSON_Y_SPACING = 10
    PERSON_Z_SPACING = 20

    [-10..10].forEach (x, i) ->
    [-10..10].forEach (y, j) ->
    [0...3].forEach (z, k) ->
    cube = new THREE.Mesh(person, material)
    scene.add(cube)
    person_geometry = new THREE.BoxGeometry(15, 40, 1)
    person_material = new THREE.MeshLambertMaterial(color: 0x00FF00)

    PERSON_X_SPACING = 100
    PERSON_Y_SPACING = 100
    PERSON_Z_SPACING = 100

    [-10..10].forEach (x) ->
    [-10..10].forEach (y) ->
    [0...3].forEach (z) ->
    person = new THREE.Mesh(
    person_geometry
    person_material
    )
    offset = if y % 2 then 0.5 else 0
    cube.position.set(
    person.position.set(
    (x + offset) * PERSON_X_SPACING
    y * PERSON_Y_SPACING
    z * PERSON_Z_SPACING
    )
    person.castShadow = z is 1
    scene.add(person)


    sun = new THREE.DirectionalLight( 0xffffff, 0.5 )
    sun.position.set(0,0,100)
    building = new THREE.Mesh(
    new THREE.BoxGeometry(1400,300, 10)
    new THREE.MeshLambertMaterial(color: 0xffffff)
    )
    building.position.z = 90
    building.position.y = -180
    building.receiveShadow = true
    scene.add(building)

    sun = new THREE.DirectionalLight(0xffffff, 1)
    sun.position.set(-400, 300, 200)
    sun.castShadow = true
    scene.add(sun)

    scene.add( new THREE.AmbientLight( 0x222222) )

    renderer.shadowMapEnabled = true
    renderer.shadowMapSoft = false

    renderer.shadowCameraNear = 3
    renderer.shadowCameraFar = camera.far
    renderer.shadowCameraFov = 50

    renderer.shadowMapBias = 0.0039
    renderer.shadowMapDarkness = 0.5
    renderer.shadowMapWidth = 1024
    renderer.shadowMapHeight = 1024

    render = ->
    renderer.render(scene, camera)
    render()
  23. Alec Perkins revised this gist Oct 20, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion script.coffee
    Original file line number Diff line number Diff line change
    @@ -35,6 +35,7 @@ renderer.domElement.addEventListener 'mousemove', (e) ->
    SCALE_FACTOR = 0.01
    camera.position.x = rel_x * SCALE_FACTOR
    camera.position.y = rel_y * SCALE_FACTOR
    requestAnimationFrame(render)



    @@ -65,6 +66,5 @@ sun.position.set(0,0,100)
    scene.add(sun)

    render = ->
    requestAnimationFrame(render)
    renderer.render(scene, camera)
    render()
  24. Alec Perkins revised this gist Oct 20, 2014. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -47,13 +47,14 @@ PERSON_X_SPACING = 10
    PERSON_Y_SPACING = 10
    PERSON_Z_SPACING = 20

    [-6..6].forEach (x, i) ->
    [-6..6].forEach (y, j) ->
    [-10..10].forEach (x, i) ->
    [-10..10].forEach (y, j) ->
    [0...3].forEach (z, k) ->
    cube = new THREE.Mesh(person, material)
    scene.add(cube)
    offset = if y % 2 then 0.5 else 0
    cube.position.set(
    x * PERSON_X_SPACING
    (x + offset) * PERSON_X_SPACING
    y * PERSON_Y_SPACING
    z * PERSON_Z_SPACING
    )
  25. Alec Perkins revised this gist Oct 20, 2014. 1 changed file with 15 additions and 7 deletions.
    22 changes: 15 additions & 7 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ camera = new THREE.PerspectiveCamera(
    0.1
    1000
    )
    camera.position.z = 100
    camera.position.z = 60



    @@ -39,16 +39,24 @@ renderer.domElement.addEventListener 'mousemove', (e) ->



    geometry = new THREE.BoxGeometry(4,4,4)
    person = new THREE.BoxGeometry(1,2,0.1)
    material = new THREE.MeshLambertMaterial
    color: 0x00ff00

    [-3..3].forEach (x, i) ->
    [-3..3].forEach (y, j) ->
    [-3..3].forEach (z, k) ->
    cube = new THREE.Mesh(geometry, material)
    PERSON_X_SPACING = 10
    PERSON_Y_SPACING = 10
    PERSON_Z_SPACING = 20

    [-6..6].forEach (x, i) ->
    [-6..6].forEach (y, j) ->
    [0...3].forEach (z, k) ->
    cube = new THREE.Mesh(person, material)
    scene.add(cube)
    cube.position.set(x * 10,y * 10,z * 10)
    cube.position.set(
    x * PERSON_X_SPACING
    y * PERSON_Y_SPACING
    z * PERSON_Z_SPACING
    )


    sun = new THREE.DirectionalLight( 0xffffff, 0.5 )
  26. Alec Perkins revised this gist Oct 20, 2014. 5 changed files with 67 additions and 19 deletions.
    1 change: 0 additions & 1 deletion markup.jade
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    #app
    3 changes: 2 additions & 1 deletion notes.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    # magritte-golconda


    http://www.wikiart.org/en/rene-magritte/gonconda-1953
    http://threejs.org/docs/
    69 changes: 61 additions & 8 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,61 @@
    Component = React.createClass
    displayName: 'Component'
    render: ->
    <div className='Component'>
    Component! {@props.time}
    </div>

    React.renderComponent(Component(time=new Date()), document.getElementById('app'))
    # Component = React.createClass
    # displayName: 'Component'
    # render: ->
    # <div className='Component'>
    # Component! {@props.time}
    # </div>

    # React.renderComponent(Component(time=new Date()), document.getElementById('app'))


    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(
    75
    window.innerWidth / window.innerHeight
    0.1
    1000
    )
    camera.position.z = 100



    renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)

    origin =
    x: window.innerWidth / 2
    y: window.innerHeight / 2

    renderer.domElement.addEventListener 'mousemove', (e) ->
    # Convert the screen coordinates to world
    rel_x = origin.x - e.pageX
    rel_y = e.pageY - origin.y
    # Adjust camera position
    SCALE_FACTOR = 0.01
    camera.position.x = rel_x * SCALE_FACTOR
    camera.position.y = rel_y * SCALE_FACTOR




    geometry = new THREE.BoxGeometry(4,4,4)
    material = new THREE.MeshLambertMaterial
    color: 0x00ff00

    [-3..3].forEach (x, i) ->
    [-3..3].forEach (y, j) ->
    [-3..3].forEach (z, k) ->
    cube = new THREE.Mesh(geometry, material)
    scene.add(cube)
    cube.position.set(x * 10,y * 10,z * 10)


    sun = new THREE.DirectionalLight( 0xffffff, 0.5 )
    sun.position.set(0,0,100)
    scene.add(sun)

    render = ->
    requestAnimationFrame(render)
    renderer.render(scene, camera)
    render()
    3 changes: 1 addition & 2 deletions settings.json
    Original file line number Diff line number Diff line change
    @@ -2,8 +2,7 @@
    "name": "magritte-golconda",
    "proto_version": "1.5.1",
    "script_libraries": [
    "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js",
    "https://cdnjs.cloudflare.com/ajax/libs/react/0.11.2/react.js"
    "https://cdnjs.cloudflare.com/ajax/libs/three.js/r68/three.min.js"
    ],
    "style_libraries": [
    ],
    10 changes: 3 additions & 7 deletions style.styl
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,3 @@
    @import 'nib'

    h1
    font-weight 300
    font-family Helvetica


    html,
    body
    margin: 0
  27. Alec Perkins created this gist Oct 19, 2014.
    1 change: 1 addition & 0 deletions markup.jade
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    #app
    3 changes: 3 additions & 0 deletions notes.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    # magritte-golconda


    8 changes: 8 additions & 0 deletions script.coffee
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    Component = React.createClass
    displayName: 'Component'
    render: ->
    <div className='Component'>
    Component! {@props.time}
    </div>

    React.renderComponent(Component(time=new Date()), document.getElementById('app'))
    11 changes: 11 additions & 0 deletions settings.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    {
    "name": "magritte-golconda",
    "proto_version": "1.5.1",
    "script_libraries": [
    "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js",
    "https://cdnjs.cloudflare.com/ajax/libs/react/0.11.2/react.js"
    ],
    "style_libraries": [
    ],
    "extra_head_markup": "<meta name='viewport' content='width=device-width'>"
    }
    7 changes: 7 additions & 0 deletions style.styl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    @import 'nib'

    h1
    font-weight 300
    font-family Helvetica