 
             @_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) =>
+            format = (num) ->
+                Number(num.toFixed 2).toString()
+
+            add_label = (loc, text) =>
                 @_frame_labels.push(
                     @add_text
-                        pos           : [x,y,z]
+                        loc           : loc
                         text          : text
                         fontsize      : opts.fontsize
                         color         : opts.color
                         constant_size : false
+                        in_frame      : 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
+
+            e = (max.y - min.y)*offset
+            add_label [max.x, min.y-e, min.z], format(min.z)
+            add_label [max.x, min.y-e, avg.z], "z = #{format avg.z}"
+            add_label [max.x, min.y-e, max.z], format(max.z)
+
+            e = (max.x - min.x)*offset
+            add_label [max.x+e, min.y, min.z], format(min.y)
+            add_label [max.x+e, avg.y, min.z], "y = #{format avg.y}"
+            add_label [max.x+e, max.y, min.z], format(max.y)
+
+            e = (max.y - min.y)*offset
+            add_label [max.x, max.y+e, min.z], format(max.x)
+            add_label [avg.x, max.y+e, min.z], "x = #{format avg.x}"
+            add_label [min.x, max.y+e, min.z], format(min.x)
+
+        @camera.lookAt @_center
         if @controls?
             @controls.target = @_center
         @render_scene()
 
-    add_3dgraphics_obj: (opts) ->
+    add_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}"
+        switch opts.obj.type
+            when 'group'
+                for obj in opts.obj.subobjs
+                    opts.obj = obj
+                    @add_obj opts
+            when 'text'
+                delete opts.obj.type
+                @add_text opts.obj
+            when 'index_face_set'
+                delete opts.obj.type
+                if opts.wireframe?
+                    opts.obj.wireframe = opts.wireframe
+                @add_index_face_set opts.obj
+                if opts.obj.mesh and not opts.obj.wireframe
+                    # draw a wireframe mesh on top of the surface we just drew.
+                    opts.obj.material.color = [0, 0, 0]
+                    opts.obj.wireframe = opts.obj.mesh
+                    @add_index_face_set opts.obj
+            when 'line'
+                delete opts.obj.type
+                @add_line opts.obj
+            when 'point'
+                delete opts.obj.type
+                @add_point opts.obj
+            else
+                console.log "ERROR: bad object type #{opts.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 = opts.color
                context.fill()

                texture = new THREE.Texture canvas

        sprite = new THREE.Sprite spriteMaterial

        # Move the sprite to its position
        position = @aspect_ratio_scale opts.loc...
        sprite.position.set position...

        # If the text is supposed to stay constant size, add it to the list of constant size text,
