Loading 3D models in and putting them right on this webpage here right now via Three.js. It’s pretty limited in what it can do presently, but hopefully I can add some stuff to allow for better customization.

### Ben Scott # 2015-10-26 # Viewer ###

'use strict' # just like JavaScript

### Constants & Aliases ###
{abs,floor,random,sqrt} = Math # destructuring fun

### DOM ###
dir = "/js/assets/" # directory
divID = "CoffeeCode" # id of parent
container = null # parent in the HTML document

### WebGL ###
renderers = [] # list of objects to render
loader = new T.JSONLoader()
textureLoader = new T.TextureLoader()


This is the program entrypoint, and it initializes all of the Three.js objects.

  • @scene: An object representing everything in the environment, including cameras, 3D models, etc.
  • @camera: The main rendering viewpoint, typically uses perspective rather than orthogonal rendering.
  • @renderer: … I’ll… get back to you about exactly what it is that this one does!
class Main
    constructor: (filename) ->
        @scene = new T.Scene()
        @scene.fog = new T.Fog(0x00,2**12,2**16)
        @camera = new T.PerspectiveCamera(
        @renderer = new T.WebGLRenderer {
            antialias: true, alpha: true }
        @ambient = new T.AmbientLight(0x404040)
        @scene.add @ambient
        @light = new T.DirectionalLight(0xEFEFED,1)
        @scene.add @light

    init: (distance = 1024) ->
        @camera.position.z = distance

    initDOM: ->
        container = document.getElementById(divID)

    initControls: ->
        @controls = new T.OrbitControls(
        @controls.userZoom = false

    update: ->


This needs to be a bound function, and is the callback used by requestAnimationFrame, which does a bunch of stuff, e.g., calling render at the proper framerate.

    render: =>
        rend.render() for rend in renderers


This needs to be a bound function, and is the callback used by the JSONLoader to initialize geometry from the provided filename.

    import3D: (filename) =>
            (geo) =>
                mat = new T.MeshPhongMaterial {
                    color: 0xAEAEAE
                    specular: 0x282828 }
                mesh = new T.Mesh(geo, mat)
                @scene.add mesh)


This is a global function, callable from other scripts, and will be used with another script on the page to load an arbitrary 3D model into a basic scene.

@initViewer = (filename, distance=1024) =>
    main = new Main(filename)

Finally, the page needs to start the program and provide a filename for the 3D model (from which other data like textures will be inferred).

<script language="javascript">

In this case, the argument to initViewer is a template variable, defined in the post’s Jekyll Frontmatter. I require a filename, but the camera render distance is optional. In the future, I hope to have more parameters / a better way to pass more complicated data to the function.