diff --git a/changelog.txt b/changelog.txt
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,9 @@
+0.7.6.5:
+- export LoadedObjModel data constructor
+
+0.7.6.4:
+- use matrix multiplication for DCM/quat rotations
+
 0.7.6.3:
 - support OpenGL 3
 
diff --git a/not-gloss.cabal b/not-gloss.cabal
--- a/not-gloss.cabal
+++ b/not-gloss.cabal
@@ -1,5 +1,5 @@
 name:                not-gloss
-version:             0.7.6.4
+version:             0.7.6.5
 stability:           Experimental
 synopsis:            Painless 3D graphics, no affiliation with gloss
 description:{
@@ -45,7 +45,7 @@
                        vector,
                        cereal,
                        binary,
-                       vector-binary-instances,
+                       vector-binary-instances == 0.2.1.0,
                        bytestring,
                        bmp
 
diff --git a/src/Vis/Vis.hs b/src/Vis/Vis.hs
--- a/src/Vis/Vis.hs
+++ b/src/Vis/Vis.hs
@@ -5,6 +5,7 @@
                , Antialiasing(..)
                , vis
                , visMovie
+               , visMovieImmediately
                , FullState
                ) where
 
@@ -296,7 +297,10 @@
       -- need to sleep longer
       else threadDelay usRemaining
 
-
+-- | Make a series of images, one from each 'VisObject'.
+-- When 'visMovie' is executed a window pops up and loops the animation
+-- until you are happy with the camera angle.
+-- Hit spacebar and the images will be created and saved to disk.
 visMovie
   :: forall b
      . Real b
@@ -306,7 +310,33 @@
      -> [VisObject b] -- ^ movie to draw
      -> Maybe Cursor -- ^ optional cursor
      -> IO ()
-visMovie opts toFilename ts objectsToDraw maybeCursor = do
+visMovie = visMovie' False
+
+-- | Make a series of images, one from each 'VisObject'.
+-- When 'visMovieImmediately' is executed a window is opened and without
+-- waiting the images are created and saved to disk.
+visMovieImmediately
+  :: forall b
+     . Real b
+     => Options -- ^ user options
+     -> (Int -> FilePath) -- ^ where to write the bitmaps
+     -> Double -- ^ sample time
+     -> [VisObject b] -- ^ movie to draw
+     -> Maybe Cursor -- ^ optional cursor
+     -> IO ()
+visMovieImmediately = visMovie' True
+
+visMovie'
+  :: forall b
+     . Real b
+     => Bool -- ^ start immediately
+     -> Options -- ^ user options
+     -> (Int -> FilePath) -- ^ where to write the bitmaps
+     -> Double -- ^ sample time
+     -> [VisObject b] -- ^ movie to draw
+     -> Maybe Cursor -- ^ optional cursor
+     -> IO ()
+visMovie' startImmediately opts toFilename ts objectsToDraw maybeCursor = do
   -- init glut/scene
   _ <- GLUT.getArgsAndInitialize
 
@@ -321,7 +351,7 @@
   -- create internal state
   areWeDrawingRef <- newIORef False
   stateMVar <- newMVar (objectsToDraw, cameraState0)
-  visReadyMVar <- newMVar False
+  visReadyMVar <- newMVar startImmediately
 
   -- start sim thread
   _ <- forkIO $ movieSimThread objectsToDraw stateMVar visReadyMVar ts
diff --git a/src/Vis/VisObject.hs b/src/Vis/VisObject.hs
--- a/src/Vis/VisObject.hs
+++ b/src/Vis/VisObject.hs
@@ -6,7 +6,7 @@
 
 module Vis.VisObject ( VisObject(..)
                      , drawObjects
-                     , LoadedObjModel
+                     , LoadedObjModel(..)
                      , loadObjModel
                      , setPerspectiveMode
                      ) where
@@ -14,14 +14,14 @@
 import GHC.Generics ( Generic )
 
 import Control.Monad ( when )
+import qualified Data.Binary as B
 import qualified Data.Foldable as F
 import Data.Maybe ( fromJust, isJust )
-import Data.Word ( Word8 )
-import qualified Data.Vector.Storable as VS
 import qualified Data.Serialize as S
-import qualified Data.Binary as B
-import Data.Vector.Cereal ()
 import Data.Vector.Binary ()
+import Data.Vector.Cereal ()
+import qualified Data.Vector.Storable as VS
+import Data.Word ( Word8 )
 import Graphics.GL
 import qualified Graphics.Rendering.OpenGL as GL
 import qualified Graphics.UI.GLUT as GLUT
