                 @_text.push sprite
 
         # Finally add the sprite to our scene
+        if opts.in_frame
+            @update_bounding_box sprite
         @scene.add sprite
 
-        return sprite
-
-    add_line : (opts) ->
+    add_line: (opts) ->
         opts = defaults opts,
             points     : required
             thickness  : 1
-            color      : "#000000"
             arrow_head : false  # TODO
+            material   : required
+            in_frame   : true
 
         geometry = new THREE.Geometry()
         for a in opts.points
             geometry.vertices.push @vector a...
-        line = new THREE.Line geometry, new THREE.LineBasicMaterial(color:opts.color, linewidth:opts.thickness)
+
+        line = new THREE.Line geometry, new THREE.LineBasicMaterial(linewidth:opts.thickness)
+        line.material.color.setRGB opts.material.color
+
+        if opts.in_frame
+            @update_bounding_box line
         @scene.add line
 
     add_point: (opts) ->
         opts = defaults opts,
             loc  : [0,0,0]
             size : 5
-            color: "#000000"
+            material: required
+            in_frame: true
 
         if not @_points?
             @_points = []


            @_frame_labels = []

            l = (a, b) ->
                if not b?
                    z = a
                else
                    z = (a+b)/2
                z = z.toFixed 2
                return (z*1).toString()

            txt = (x, y, z, text) =>
                @_frame_labels.push(
                    @add_text
                        pos           : [x,y,z]
                        text          : text
                        fontsize      : opts.fontsize
                        color         : opts.color
                        constant_size : false
                    )

            offset = 0.075
            if opts.draw
                e = (y1 - y0)*offset
                txt x1, y0-e, z0, l z0
                txt x1, y0-e, mz, "z=#{l z0, z1}"
                txt x1, y0-e, z1, l z1

                e = (x1 - x0)*offset
                txt x1+e, y0, z0, l y0
                txt x1+e, my, z0, "y=#{l y0, y1}"
                txt x1+e, y1, z0, l y1

                e = (y1 - y0)*offset
                txt x1, y1+e, z0, l x1
                txt mx, y1+e, z0, "x=#{l x0, x1}"
                txt x0, y1+e, z0, l x0

        v = @vector mx, my, mz
        @camera.lookAt v
        if @controls?
            @controls.target = @_center
        @render_scene()

    add_3dgraphics_obj: (opts) ->
        opts = defaults opts,
            obj       : required
            wireframe : undefined
            set_frame : undefined

        for obj in opts.obj
            switch obj.type
                when 'text'
                    delete obj.type
                    @add_text obj
                when 'index_face_set'
                    delete obj.type
                    if opts.wireframe?
                        obj.wireframe = opts.wireframe
                    @add_index_face_set obj
                    if obj.mesh and not obj.wireframe  # draw a wireframe mesh on top of the surface we just drew.
                        obj.material.color = [0, 0, 0]
                        obj.wireframe = obj.mesh
                        @add_index_face_set obj
                when 'line'
                    delete obj.type
                    @add_line obj
                when 'point'
                    delete obj.type
                    @add_point obj
                else
                    console.log "ERROR: bad object type #{obj.type}"

        if opts.set_frame?
            @set_frame opts.set_frame


                context.beginPath()
                context.arc centerX, centerY, radius, 0, 2*Math.PI, false
                context.fillStyle = rgb_to_hex opts.material.color...
                context.fill()

                texture = new THREE.Texture canvas
