cal3d-examples (empty) → 0.1
raw patch · 35 files changed
+1082/−0 lines, 35 filesdep +OpenGLdep +SDLdep +basesetup-changedbinary-added
Dependencies added: OpenGL, SDL, base, cal3d, cal3d-opengl
Files
- CallyCommon.hs +314/−0
- CallyDump.hs +107/−0
- CallyOpenGL.hs +309/−0
- LICENSE +281/−0
- Setup.hs +3/−0
- cal3d-examples.cabal +40/−0
- data/cally.csf binary
- data/cally_calf_left.cmf binary
- data/cally_calf_right.cmf binary
- data/cally_chest.cmf binary
- data/cally_chest.xrf +7/−0
- data/cally_foot_left.cmf binary
- data/cally_foot_right.cmf binary
- data/cally_hand_left.cmf binary
- data/cally_hand_right.cmf binary
- data/cally_head.cmf binary
- data/cally_idle.caf binary
- data/cally_jog.caf binary
- data/cally_lowerarm_left.cmf binary
- data/cally_lowerarm_right.cmf binary
- data/cally_neck.cmf binary
- data/cally_pelvis.cmf binary
- data/cally_pelvis.xrf +7/−0
- data/cally_ponytail.cmf binary
- data/cally_ponytail.xrf +7/−0
- data/cally_shoot_arrow.caf binary
- data/cally_skin.xrf +7/−0
- data/cally_strut.caf binary
- data/cally_thigh_left.cmf binary
- data/cally_thigh_right.cmf binary
- data/cally_tornado_kick.caf binary
- data/cally_upperarm_left.cmf binary
- data/cally_upperarm_right.cmf binary
- data/cally_walk.caf binary
- data/cally_wave.caf binary
@@ -0,0 +1,314 @@+module CallyCommon+ (meshFiles+ , loadCallyCoreModel+ , newCallyInstance+ -- , skinThread+ , baseMatlSet+ , logging, loggingRequire, require -- at least temporarily+ , CallyCoreModel(..)+ , faceStride, vtxStride, normStride+ , renderModel, renderMesh, renderSubmesh+ , RenderInfo(..), riNormCount, RenderAction+ )++where++import Control.Monad+import Foreign++import Graphics.Rendering.OpenGL++import Graphics.Animation.Cal3D+import Graphics.Animation.Cal3D.OpenGL++import Paths_cal3d_examples (getDataDir) -- generated by Cabal+++skeletonFile = "cally.csf"++meshFiles :: [FilePath]+meshFiles = ["cally_calf_left.cmf",+ "cally_calf_right.cmf",+ "cally_chest.cmf",+ "cally_foot_left.cmf",+ "cally_foot_right.cmf",+ "cally_hand_left.cmf",+ "cally_hand_right.cmf",+ "cally_head.cmf",+ "cally_lowerarm_left.cmf",+ "cally_lowerarm_right.cmf",+ "cally_neck.cmf",+ "cally_pelvis.cmf",+ "cally_ponytail.cmf",+ "cally_thigh_left.cmf",+ "cally_thigh_right.cmf",+ "cally_upperarm_left.cmf",+ "cally_upperarm_right.cmf"]++materialFiles :: [FilePath]+materialFiles = ["cally_skin.xrf"+ , "cally_ponytail.xrf"+ , "cally_chest.xrf"+ , "cally_pelvis.xrf"]++animFiles :: [FilePath]+animFiles = ["cally_idle.caf"+ , "cally_tornado_kick.caf"+ , "cally_walk.caf"+ , "cally_strut.caf"+ , "cally_jog.caf"+ , "cally_shoot_arrow.caf"+ , "cally_wave.caf"]++-- skinThread = MaterialThreadId 0+baseMatlSet = MaterialSetId 0++data CallyCoreModel = + CallyCoreModel { callyCoreModel :: CoreModel+ , jogAnim, idleAnim :: AnimationId+ , meshes :: [MeshId]}++loadCallyCoreModel :: Bool -> IO CallyCoreModel+loadCallyCoreModel verbose = do+ {+ -- Find out where Cabal installed data files+ dataDir <- getDataDir+ ; let dataFile :: FilePath -> FilePath+ dataFile fileName = dataDir ++ "/data/" ++ fileName++ -- A. Create core model+ ; coreModel <- newCoreModel "basic coreModel"+ ; putStrLn "Created coreModel"++ -- Give it exactly one skeleton+ ; require 1 "load skeleton file" + (loadCoreSkeleton coreModel (dataFile skeletonFile))+ + -- Load some animations+ ; idle <- require 2 "load idle animation"+ (loadCoreAnimation coreModel (dataFile "cally_idle.caf"))+ ; jog <- require 3 "load jog animation"+ (loadCoreAnimation coreModel (dataFile "cally_jog.caf"))++ -- Load some meshes.+ -- *All* of these need to be loaded; otherwise we get segfault.+ ; coreMeshes <- (mapM (\ (n, file) ->+ require n ("load " ++ file)+ (loadCoreMesh coreModel (dataFile file)))+ (zip [10..] meshFiles))+ :: IO [MeshId]+ ; print ("core meshes:", coreMeshes)++ -- Load a material++ ; materials <- (mapM (\ (n, file) ->+ require n ("load " ++ file)+ (loadCoreMaterial coreModel + (dataFile file)))+ (zip [30..] materialFiles))+ :: IO [MaterialId]++ -- ***++ -- Skip all textures+ -- (actually, there aren't any in the data files)+ -- ...++ -- Create "material threads"+ -- ; require 27 "create material thread"+ -- (createCoreMaterialThread coreModel skinThread)+ -- Assign material to thread/set pair(s) + ; mapM (\ matl@(MaterialId id) -> do+ {+ let mthread = MaterialThreadId (fromIntegral id)+ ; createCoreMaterialThread coreModel mthread+ ; setCoreMaterialId coreModel mthread baseMatlSet matl+ })+ materials++ -- ; setCoreMaterialId coreModel skinThread baseMatlSet skinMatl++ ; return CallyCoreModel { callyCoreModel = coreModel+ , jogAnim = jog+ , idleAnim = idle+ , meshes = coreMeshes+ }+ }++newCallyInstance :: CallyCoreModel -> Bool -> IO Model+newCallyInstance callyCore verbose = do+ {+ -- B. Create model instance(s)++ model <- newModel (callyCoreModel callyCore)++ -- Attach meshes to model++ ; mapM_ (\ (n, meshId) -> require n + ("attach mesh " ++ show meshId ++ " to model")+ (attachMesh model meshId))+ (zip [30..] (meshes callyCore))++ -- Set level of detail.+ -- Expensive; don't redo unless it changes significantly.+ ; setLodLevel model 1.0++ -- Set the model's material set.+ -- You should be able to do this for a particular mesh, as well,+ -- but not yet implemented:+ -- setMaterialSet (getMesh model leftFootMesh) baseMatlSet++ ; setMaterialSet model baseMatlSet+ ; return model+}+++loggingRequire :: Bool -> Int -> String -> IO (Either String a) -> IO a+loggingRequire verbose errcode msg action = do+ {+ logging verbose putStr msg+ ; eresult <- action+ ; case eresult of+ Left msg -> + do+ {+ putStrLn ": FATAL ERROR"+ ; error $ "error " ++ (show errcode) ++ ": " ++ msg+ }+ Right result -> + do+ {+ logging verbose putStrLn ": success"+ ; return result+ }+ }++logging :: Bool -> (a -> IO ()) -> a -> IO ()+logging verbose action arg =+ when verbose (action arg)++require :: Int -> String -> IO (Either String a) -> IO a+require = loggingRequire False++data RenderInfo = + RenderInfo {riMeshId, riSubmeshId :: Int+ , riAmbient, riDiffuse, riSpecular :: Color4 GLfloat+ , riShininess :: Float+ , riFaceCount, riVtxCount :: Int+ , riFaceBuf :: Ptr CalIndex+ , riVtxBuf, riNormBuf :: Ptr Float}++-- Number of normals = number of vertices+riNormCount :: RenderInfo -> Int+riNormCount = riVtxCount++type RenderAction = RenderInfo -> IO ()++-- Render the model (big jog here)+renderModel :: Model -> RenderAction -> IO (Either String ())+renderModel model renderAction = do+ {+ renderer <- getRenderer model+ ; renderAnimation renderer $ do + {+ -- do here whatever per-frame initialization is needed+ -- by the graphics API+ -- ...++ -- A model has one or more meshes; render each one+ meshCount <- getMeshCount renderer+ ; forM_ [0 .. meshCount - 1] (renderMesh renderer model renderAction)+ }+ }++-- Render a single mesh+renderMesh :: Renderer -> Model -> RenderAction -> Int -> IO ()+renderMesh renderer model renderAction meshId = do+ {+ -- A mesh has one or more submeshes;+ -- in each submesh, all faces have the same material+ submeshCount <- getSubmeshCount renderer meshId+ ; forM_ [0 .. submeshCount - 1] + (renderSubmesh renderer model renderAction meshId)+ }++faceStride, vtxStride, normStride :: Int+faceStride = 3+vtxStride = 3+normStride = 3++renderSubmesh :: Renderer -> Model -> RenderAction -> Int -> Int -> IO ()+renderSubmesh renderer model renderAction meshId submeshId = do+ {++ selectMeshSubmesh renderer meshId submeshId+ + -- read the material colors+ ; ambient <- getAmbientColor renderer+ ; diffuse <- getDiffuseColor renderer+ ; specular <- getSpecularColor renderer+ ; shininess <- getShininess renderer++ -- Get face and vertex counts+ ; faceCount <- getFaceCount renderer+ ; vtxCount <- getVertexCount renderer+ ; let normCount = vtxCount++ -- Allocate and fill face buffer+ ; allocaArray (faceCount * faceStride)+ (\ faceBuf -> do+ {+ nfaces <- getFaces renderer faceBuf++ -- Allocate and fill vertex buffer+ ; allocaArray (vtxCount * vtxStride)+ (\ vtxBuf -> do+ { + -- only stride = 0 works here!+ nvtx <- getVertices renderer vtxBuf 0 ++ -- Allocate and fill normal buffer+ ; allocaArray (normCount * normStride)+ (\ normBuf -> do+ {+ -- only stride = 0 works here:+ nNormals <- getNormals renderer normBuf 0+ ; renderAction RenderInfo { riMeshId = meshId+ , riSubmeshId = submeshId+ , riAmbient = ambient+ , riDiffuse = diffuse+ , riSpecular = specular+ , riShininess = shininess+ , riFaceCount = faceCount+ , riVtxCount = vtxCount+ , riFaceBuf = faceBuf+ , riVtxBuf = vtxBuf+ , riNormBuf = normBuf}+ + }+ ) -- ends allocated normal buffer+ }+ ) -- ends allocated vertex buffer+ }+ ) -- ends allocated face buffer+ } -- ends renderSubmesh+++ {- ABOVE: + If there were any textures, then the rendering should also do this:+ + ; rendererGetTextureCoordinates renderer 0 texCoordBuf+ ; textureId <- rendererGetMapUserData renderer 0+ + -- set the material, vertex, normal, and texture states for the+ -- graphics API+ -- (to do)+ -- ...+ + -- read face (vertex index) data+ ; faces <- rendererGetFAces renderer indexBuf++ -- call graphics API to render the faces now+ -- (to do)+ -- ...+ -}
@@ -0,0 +1,107 @@+-- CallyDump.hs+-- CallyDump Cal3D example++module Main where++import Control.Monad+import Foreign++import Graphics.Rendering.OpenGL++import Graphics.Animation.Cal3D++import CallyCommon++main :: IO ()++main = do+ {++ coreModel <- loadCallyCoreModel True+ ; model <- newCallyInstance coreModel True++ -- Mix animations.+ -- NOTE: In real life, you would not want to do these three+ -- without some elapsed time!++ -- Set an animation mix, reaching 100% jog after 0.5 second+ ; mixer <- getMixer model+ ; require 50 "cycle jog animation" + (blendCycle mixer (jogAnim coreModel) 1.0 0.5)+ -- Use clearCycle to "fade out" the jog animation in 3 seconds+ ; require 51 "clear jog animation cycle" + (clearCycle mixer (jogAnim coreModel) 3.0)+ -- use executeAction to perform an action once, + -- with delayIn, delayOut, weightTarget, and autoLock arguments+ ; require 52 "execute idle action"+ (executeAction mixer (idleAnim coreModel) 2.5 7.5 0.95 True)++ -- Update model state for time = 0+ ; update model 0.0+ -- Update the model state, given 0.05 second elapsed time+ -- ; update model 0.05++ -- Render the model (big job here)++ ; require 53 "render model" (renderModel model dumpRenderInfo)++ -- Destroy the model+ -- Contrary to user guide, there is no "destroy" method.+ ; deleteModel model+ ; putStrLn "Model deleted."+ + -- Finish+ ; return ()++ }+++lshow :: (Show a) => String -> a -> IO ()+lshow label x = putStrLn $ label ++ " = " ++ show x++dumpRenderInfo :: RenderAction+dumpRenderInfo renderInfo = do + {+ lshow "Mesh, Submesh = " (riMeshId renderInfo, riSubmeshId renderInfo)++ -- show coloring+ ; lshow "ambient = " (riAmbient renderInfo)+ ; lshow "diffuse = " (riDiffuse renderInfo)+ ; lshow "specular = " (riSpecular renderInfo)+ ; lshow "shininess = " (riShininess renderInfo)++ ; let faceStride = 3+ vtxStride = 3+ normStride = 3++ -- show faces+ ; lshow "Number of faces" (riFaceCount renderInfo)+ ; showBuffer (riFaceBuf renderInfo) 0 (riFaceCount renderInfo) faceStride++ -- show vertices+ ; lshow "Number of vertex elements" (riVtxCount renderInfo)+ ; showBuffer (riVtxBuf renderInfo) 0 (riVtxCount renderInfo) vtxStride++ -- show normals+ ; lshow "Number of normal elements" (riNormCount renderInfo)+ ; showBuffer (riNormBuf renderInfo) 0 (riNormCount renderInfo) normStride+ }++showBuffer :: (Storable a, Show a) => Ptr a -> Int -> Int -> Int -> IO ()+showBuffer buf irow nrows ncols =+ -- nrows = number of rows, e.g., faces (3 ints) or vertices (3 floats)+ -- ncols = number of columns, e.g., 3 per face or 3 per vertex+ when (irow < nrows)+ (do+ {+ xs <- peekRow buf irow ncols+ ; print (irow, xs)+ ; showBuffer buf (irow + 1) nrows ncols+ }+ )++peekRow :: (Storable a) => Ptr a -> Int -> Int -> IO [a]+peekRow buf irow ncols =+ -- return a list of elements of row irow+ mapM (\ i -> peekElemOff buf (irow * ncols + i))+ [0 .. ncols - 1]
@@ -0,0 +1,309 @@+-- Cally1.hs+-- Cally1 Cal3D example++module Main where++import Foreign++import Control.Monad+import Data.IORef++import Graphics.Rendering.OpenGL as GL+import Graphics.UI.SDL as SDL hiding (flip, update)++import Graphics.Animation.Cal3D+import Graphics.Animation.Cal3D.OpenGL++import CallyCommon++renderScale = 1.0++main :: IO ()++main = do+ {+ coreModel <- loadCallyCoreModel False++ -- B. Create model instance(s)++ ; model <- newCallyInstance coreModel False++ ; initSDL initCfg+ ; initGL initCfg++ -- Mix animations.+ -- NOTE: In real life, you would not want to do these three+ -- without some elapsed time!++ -- Set an animation mix, reaching 100% jog after 0.5 second+ ; mixer <- getMixer model+ ; require 50 "cycle jog animation" + (blendCycle mixer (jogAnim coreModel) 1.0 0.5)+ -- Use clearCycle to "fade out" the jog animation in 3 seconds+ -- ; require 51 "clear jog animation cycle" + -- (clearCycle mixer (jogAnim coreModel) 3.0)+ -- use executeAction to perform an action once, + -- with delayIn, delayOut, weightTarget, and autoLock arguments+ -- ; require 52 "execute idle action"+ -- (executeAction mixer (idleAnim coreModel) 2.5 7.5 0.95 True)++ -- Initialize and render the model+ ; update model 0.0 -- time 0+ -- ; putStrLn $ "Where is Cally? " ++ (whereIsModel model)+ ; renderLoop model initCfg++ -- Destroy the model+ -- Contrary to user guide, there is no "destroy" method.+ ; deleteModel model+ ; putStrLn "Model deleted."++ ; SDL.quit++ -- Finish+ ; return ()++ }++-- SDL configuration and initialization++data Config = Config {width, height :: Int32}++initCfg = Config {width = 800, height = 600}++data SDLState = SDLState {sdlWidth, sdlHeight :: Int,+ sdlSurface :: Surface,+ sdlFullscreen :: Bool}++-- ------------------------------------------------------------------------+-- SDL state and initialization++videoDepth = 32++videoFlags :: Bool -> [SurfaceFlag]+videoFlags fullscreen = + let baseFlags = -- [SDL.OpenGL, Resizable]+ [SDL.OpenGL, SDL.SrcAlpha, HWAccel, HWSurface]+ -- No effect: DoubleBuf, SDL.SrcAlpha+ -- ??: HWAccel, SWSurface, HWSurface+ in if fullscreen then Fullscreen : baseFlags else baseFlags++initSDL :: Config -> IO (IORef SDLState)+initSDL cfg = do+ {+ SDL.init [InitVideo]+ ; SDL.setCaption "Haskell Cal3d Demo with SDL and OpenGL"+ "Cal3d Demo"+ -- Set reasonable GL attributes+ ; glSetAttribute glDoubleBuffer 1+ ; glSetAttribute glDepthSize 16+ ; mapM_ ((flip glSetAttribute) 8)+ [glRedSize, glGreenSize, glBlueSize, glAlphaSize]+ ; let w = fromIntegral (width cfg)+ h = fromIntegral (height cfg)+ ; surface <- + SDL.setVideoMode w h videoDepth (videoFlags False)++ -- ; enableUnicode True+ -- ; enableKeyRepeat 500 30 -- delay, interval+ ; newIORef (SDLState { sdlWidth = w+ , sdlHeight = h+ , sdlSurface = surface+ , sdlFullscreen = False})+ }++-- ------------------------------------------------------------------------+-- OpenGL initialization++initGL :: Config -> IO ()+initGL cfg = do+ {+ viewport $= (Position 0 0, + Size (fromIntegral (width cfg)) (fromIntegral (height cfg)))+ ; clearColor $= (Color4 0 0 0.2 1 :: Color4 GLfloat)+ ; clearDepth $= 1++ ; depthFunc $= Just Less -- enables depth test+ ; cullFace $= Just Back++ -- Projection+ ; matrixMode $= Projection+ ; loadIdentity+ ; perspective 45.0 -- vertical angle+ (fromIntegral (width cfg) / + fromIntegral (height cfg)) -- aspect+ 0.2 -- near+ 1000.0 -- far++ ; matrixMode $= Modelview 0+ ; loadIdentity+++ -- Lighting+ ; lighting $= Enabled+ ; frontFace $= CCW+ ; shadeModel $= Smooth++ ; lightModelAmbient $= Color4 0.15 0.15 0.15 1.0+ ; colorMaterial $= -- Just (FrontAndBack, Diffuse) + Just (Front, Diffuse) -- implies enabled++ -- Light 0+ ; light (Light 0) $= Enabled+ ; position (Light 0) $= lightPosition+ ; ambient (Light 0) $= Color4 0.3 0.3 0.3 1.0+ ; diffuse (Light 0) $= Color4 0.52 0.5 0.5 1.0+ ; specular (Light 0) $= Color4 0.1 0.1 0.1 1.0++ -- Anti-aliasing+ ; polygonSmooth $= Enabled+ ; hint PolygonSmooth $= Fastest++ -- Blending (alpha transparency)+ ; blend $= Enabled+ ; blendFunc $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)++ -- Vertex arrays+ ; clientState VertexArray $= Enabled+ ; clientState NormalArray $= Enabled+ }++camDist :: (Num a) => a+camDist = 250++cameraPosition :: Vertex3 GLdouble+cameraPosition = Vertex3 camDist (-camDist) (camDist / 10) ++lightPosition :: Vertex4 GLfloat+lightPosition = + Vertex4 (camDist + 1) (-camDist - 1) ((camDist / 10) + 1) 1.0++-- ------------------------------------------------------------------------+-- Actual rendering++beginFrame :: Config -> IO ()+beginFrame cfg = do + {+ matrixMode $= Modelview 0+ ; loadIdentity+ ; clear [ColorBuffer, DepthBuffer]+ ; let dist = 250+ ; lookAt cameraPosition (Vertex3 0 0 60) (Vector3 0 0 1)+ ; return ()+ }++endFrame :: IO ()+endFrame = glSwapBuffers++renderLoop :: Model -> Config -> IO ()+renderLoop model cfg = do+ {+ beginFrame cfg+ -- Update the model state, given 0.05 second elapsed time+ ; update model 0.005+ ; renderModel model renderBuffers+ -- sanity pyramid+ ; drawPyramidArrayed++ ; endFrame+ ; event <- pollEvent+ ; case event of+ KeyDown (Keysym {symKey = SDLK_ESCAPE}) -> return () -- quit+ Quit -> return () -- quit+ _ -> renderLoop model cfg -- continue+ }++renderBuffers :: RenderInfo -> IO ()+renderBuffers info = do+ {+ materialAmbient Front $= riAmbient info+ ; materialDiffuse Front $= riDiffuse info+ ; materialSpecular Front $= riSpecular info+ ; materialShininess Front $= riShininess info+ ; renderArrays (3 * (riFaceCount info))+ (riVtxBuf info)+ (riNormBuf info)+ (castPtr (riFaceBuf info)) -- from (Ptr CInt) to (Ptr Int)+ }+++-- ------------------------------------------------------------------------++-- Pyramid to check sanity++++drawPyramidArrayed :: IO ()+drawPyramidArrayed =+ let s = 25 -- scale+ a = [-s, -s, 0]+ b = [s, -s, 0]+ c = [s, s, 0]+ d = [-s, s, 0]+ e = [0, 0, s]+ + face v1 v2 v3 = concat [v1, v2, v3]++ -- vertex data: 6 faces x 3 vertices x 3 coords = 54 floats+ vertexData :: [GLfloat]+ vertexData = concat [face a b d,+ face d b c,+ face a b e,+ face b c e,+ face c d e,+ face d a e]++ -- normal data: 6 faces x 3 normals x 3 coords = 54 floats+ m = 0.5 * sqrt 2+ normals :: [[GLfloat]]+ normals = [ [0.0, 0.0, (-1.0)] -- normal down+ , [0.0, 0.0, (-1.0)]+ , [0.0, (-m), m]+ , [m, 0.0, m]+ , [0.0, m, m]+ , [(-m), 0.0, m]+ ]+ normalData = concatMap (normals !!) [0, 0, 0, -- d b a+ 1, 1, 1, -- c b d+ 2, 2, 2, -- a b e+ 3, 3, 3, -- b c e+ 4, 4, 4, -- c d e+ 5, 5, 5] -- d a e+ n = length vertexData+ indexData :: [Int]+ indexData = [0..n - 1]++ in if (n /= length normalData ||+ n /= length indexData)+ then error ("vertexData, normalData, indexData: " +++ "lengths must be equal: " +++ show (length vertexData, length normalData,+ length indexData))+ else do+ {+ materialAmbientAndDiffuse Front $=+ (Color4 0 0 1 0.10 :: Color4 GLfloat) -- trans-blue for debugging+ -- (Color4 0 0 0 1 :: Color4 GLfloat)+ ; materialSpecular Front $= Color4 0 0 0 1+ + ; withArray vertexData+ (\ vtxBuf -> + (withArray normalData+ (\ normBuf ->+ (withArray indexData+ (\ indexes -> + renderArrays n vtxBuf normBuf indexes)))))+ }++-- Keep++renderArrays :: Int -> Ptr GLfloat -> Ptr GLfloat -> Ptr Int -> IO ()+renderArrays n vtxBuf normBuf indexes = + let vad nc etype stride buf =+ VertexArrayDescriptor nc etype stride buf+ in do+ {+ arrayPointer VertexArray $= vad 3 Float 0 vtxBuf+ ; arrayPointer NormalArray $= vad 3 Float 0 normBuf+ ; drawElements Triangles (fromIntegral n) UnsignedInt indexes+ }+
@@ -0,0 +1,281 @@+ GNU GENERAL PUBLIC LICENSE+ Version 2, June 1991++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.+ 675 Mass Ave, Cambridge, MA 02139, USA+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The licenses for most software are designed to take away your+freedom to share and change it. By contrast, the GNU General Public+License is intended to guarantee your freedom to share and change free+software--to make sure the software is free for all its users. This+General Public License applies to most of the Free Software+Foundation's software and to any other program whose authors commit to+using it. (Some other Free Software Foundation software is covered by+the GNU Library General Public License instead.) You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+this service if you wish), that you receive source code or can get it+if you want it, that you can change the software or use pieces of it+in new free programs; and that you know you can do these things.++ To protect your rights, we need to make restrictions that forbid+anyone to deny you these rights or to ask you to surrender the rights.+These restrictions translate to certain responsibilities for you if you+distribute copies of the software, or if you modify it.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must give the recipients all the rights that+you have. You must make sure that they, too, receive or can get the+source code. And you must show them these terms so they know their+rights.++ We protect your rights with two steps: (1) copyright the software, and+(2) offer you this license which gives you legal permission to copy,+distribute and/or modify the software.++ Also, for each author's protection and ours, we want to make certain+that everyone understands that there is no warranty for this free+software. If the software is modified by someone else and passed on, we+want its recipients to know that what they have is not the original, so+that any problems introduced by others will not reflect on the original+authors' reputations.++ Finally, any free program is threatened constantly by software+patents. We wish to avoid the danger that redistributors of a free+program will individually obtain patent licenses, in effect making the+program proprietary. To prevent this, we have made it clear that any+patent must be licensed for everyone's free use or not licensed at all.++ The precise terms and conditions for copying, distribution and+modification follow.++ GNU GENERAL PUBLIC LICENSE+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++ 0. This License applies to any program or other work which contains+a notice placed by the copyright holder saying it may be distributed+under the terms of this General Public License. The "Program", below,+refers to any such program or work, and a "work based on the Program"+means either the Program or any derivative work under copyright law:+that is to say, a work containing the Program or a portion of it,+either verbatim or with modifications and/or translated into another+language. (Hereinafter, translation is included without limitation in+the term "modification".) Each licensee is addressed as "you".++Activities other than copying, distribution and modification are not+covered by this License; they are outside its scope. The act of+running the Program is not restricted, and the output from the Program+is covered only if its contents constitute a work based on the+Program (independent of having been made by running the Program).+Whether that is true depends on what the Program does.++ 1. You may copy and distribute verbatim copies of the Program's+source code as you receive it, in any medium, provided that you+conspicuously and appropriately publish on each copy an appropriate+copyright notice and disclaimer of warranty; keep intact all the+notices that refer to this License and to the absence of any warranty;+and give any other recipients of the Program a copy of this License+along with the Program.++You may charge a fee for the physical act of transferring a copy, and+you may at your option offer warranty protection in exchange for a fee.++ 2. You may modify your copy or copies of the Program or any portion+of it, thus forming a work based on the Program, and copy and+distribute such modifications or work under the terms of Section 1+above, provided that you also meet all of these conditions:++ a) You must cause the modified files to carry prominent notices+ stating that you changed the files and the date of any change.++ b) You must cause any work that you distribute or publish, that in+ whole or in part contains or is derived from the Program or any+ part thereof, to be licensed as a whole at no charge to all third+ parties under the terms of this License.++ c) If the modified program normally reads commands interactively+ when run, you must cause it, when started running for such+ interactive use in the most ordinary way, to print or display an+ announcement including an appropriate copyright notice and a+ notice that there is no warranty (or else, saying that you provide+ a warranty) and that users may redistribute the program under+ these conditions, and telling the user how to view a copy of this+ License. (Exception: if the Program itself is interactive but+ does not normally print such an announcement, your work based on+ the Program is not required to print an announcement.)++These requirements apply to the modified work as a whole. If+identifiable sections of that work are not derived from the Program,+and can be reasonably considered independent and separate works in+themselves, then this License, and its terms, do not apply to those+sections when you distribute them as separate works. But when you+distribute the same sections as part of a whole which is a work based+on the Program, the distribution of the whole must be on the terms of+this License, whose permissions for other licensees extend to the+entire whole, and thus to each and every part regardless of who wrote it.++Thus, it is not the intent of this section to claim rights or contest+your rights to work written entirely by you; rather, the intent is to+exercise the right to control the distribution of derivative or+collective works based on the Program.++In addition, mere aggregation of another work not based on the Program+with the Program (or with a work based on the Program) on a volume of+a storage or distribution medium does not bring the other work under+the scope of this License.++ 3. You may copy and distribute the Program (or a work based on it,+under Section 2) in object code or executable form under the terms of+Sections 1 and 2 above provided that you also do one of the following:++ a) Accompany it with the complete corresponding machine-readable+ source code, which must be distributed under the terms of Sections+ 1 and 2 above on a medium customarily used for software interchange; or,++ b) Accompany it with a written offer, valid for at least three+ years, to give any third party, for a charge no more than your+ cost of physically performing source distribution, a complete+ machine-readable copy of the corresponding source code, to be+ distributed under the terms of Sections 1 and 2 above on a medium+ customarily used for software interchange; or,++ c) Accompany it with the information you received as to the offer+ to distribute corresponding source code. (This alternative is+ allowed only for noncommercial distribution and only if you+ received the program in object code or executable form with such+ an offer, in accord with Subsection b above.)++The source code for a work means the preferred form of the work for+making modifications to it. For an executable work, complete source+code means all the source code for all modules it contains, plus any+associated interface definition files, plus the scripts used to+control compilation and installation of the executable. However, as a+special exception, the source code distributed need not include+anything that is normally distributed (in either source or binary+form) with the major components (compiler, kernel, and so on) of the+operating system on which the executable runs, unless that component+itself accompanies the executable.++If distribution of executable or object code is made by offering+access to copy from a designated place, then offering equivalent+access to copy the source code from the same place counts as+distribution of the source code, even though third parties are not+compelled to copy the source along with the object code.++ 4. You may not copy, modify, sublicense, or distribute the Program+except as expressly provided under this License. Any attempt+otherwise to copy, modify, sublicense or distribute the Program is+void, and will automatically terminate your rights under this License.+However, parties who have received copies, or rights, from you under+this License will not have their licenses terminated so long as such+parties remain in full compliance.++ 5. You are not required to accept this License, since you have not+signed it. However, nothing else grants you permission to modify or+distribute the Program or its derivative works. These actions are+prohibited by law if you do not accept this License. Therefore, by+modifying or distributing the Program (or any work based on the+Program), you indicate your acceptance of this License to do so, and+all its terms and conditions for copying, distributing or modifying+the Program or works based on it.++ 6. Each time you redistribute the Program (or any work based on the+Program), the recipient automatically receives a license from the+original licensor to copy, distribute or modify the Program subject to+these terms and conditions. You may not impose any further+restrictions on the recipients' exercise of the rights granted herein.+You are not responsible for enforcing compliance by third parties to+this License.++ 7. If, as a consequence of a court judgment or allegation of patent+infringement or for any other reason (not limited to patent issues),+conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot+distribute so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you+may not distribute the Program at all. For example, if a patent+license would not permit royalty-free redistribution of the Program by+all those who receive copies directly or indirectly through you, then+the only way you could satisfy both it and this License would be to+refrain entirely from distribution of the Program.++If any portion of this section is held invalid or unenforceable under+any particular circumstance, the balance of the section is intended to+apply and the section as a whole is intended to apply in other+circumstances.++It is not the purpose of this section to induce you to infringe any+patents or other property right claims or to contest validity of any+such claims; this section has the sole purpose of protecting the+integrity of the free software distribution system, which is+implemented by public license practices. Many people have made+generous contributions to the wide range of software distributed+through that system in reliance on consistent application of that+system; it is up to the author/donor to decide if he or she is willing+to distribute software through any other system and a licensee cannot+impose that choice.++This section is intended to make thoroughly clear what is believed to+be a consequence of the rest of this License.++ 8. If the distribution and/or use of the Program is restricted in+certain countries either by patents or by copyrighted interfaces, the+original copyright holder who places the Program under this License+may add an explicit geographical distribution limitation excluding+those countries, so that distribution is permitted only in or among+countries not thus excluded. In such case, this License incorporates+the limitation as if written in the body of this License.++ 9. The Free Software Foundation may publish revised and/or new versions+of the General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++Each version is given a distinguishing version number. If the Program+specifies a version number of this License which applies to it and "any+later version", you have the option of following the terms and conditions+either of that version or of any later version published by the Free+Software Foundation. If the Program does not specify a version number of+this License, you may choose any version ever published by the Free Software+Foundation.++ 10. If you wish to incorporate parts of the Program into other free+programs whose distribution conditions are different, write to the author+to ask for permission. For software which is copyrighted by the Free+Software Foundation, write to the Free Software Foundation; we sometimes+make exceptions for this. Our decision will be guided by the two goals+of preserving the free status of all derivatives of our free software and+of promoting the sharing and reuse of software generally.++ NO WARRANTY++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,+REPAIR OR CORRECTION.++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE+POSSIBILITY OF SUCH DAMAGES.++ END OF TERMS AND CONDITIONS+
@@ -0,0 +1,3 @@+-- Simple setup+import Distribution.Simple+main = defaultMain
@@ -0,0 +1,40 @@+name: cal3d-examples+version: 0.1+cabal-version: >= 1.6+build-type: Simple+-- The original Cally Demo is GLP'ed, so it makes sense to do this+-- the same way, especially as long as it uses data files from the original.+license: GPL+license-file: LICENSE+author: Gregory D. Weber+maintainer: let at = "@" in concat ["gdweber", at, "iue.edu"]+stability: experimental+homepage: http://haskell.org/haskellwiki/Cal3d_animation+category: Graphics, Animation+tested-with: GHC == 6.10.1+data-files: data/*.csf data/*.cmf data/*.caf data/*.xrf+synopsis: Examples for the Cal3d animation library.+description: + Cal3d animation examples for cal3d.++extra-source-files: CallyCommon.hs++executable cally-dump+ main-is: CallyDump.hs+ build-depends: + base >= 4.0.0.0 && < 5,+ OpenGL >= 2.2.3 && < 3,+ SDL >= 0.5 && < 1,+ cal3d >= 0.1 && < 0.2,+ cal3d-opengl >= 0.1 && < 0.2+ extensions: ForeignFunctionInterface++executable cally-gl+ main-is: CallyOpenGL.hs+ build-depends: + base >= 4.0.0.0 && < 5,+ OpenGL >= 2.2.3 && < 3,+ SDL >= 0.5 && < 1,+ cal3d >= 0.1 && < 0.2,+ cal3d-opengl >= 0.1 && < 0.2+ extensions: ForeignFunctionInterface
binary file changed (absent → 3216 bytes)
binary file changed (absent → 6400 bytes)
binary file changed (absent → 6464 bytes)
binary file changed (absent → 16968 bytes)
@@ -0,0 +1,7 @@+<HEADER MAGIC="XRF" VERSION="900" />+<MATERIAL NUMMAPS="0">+ <AMBIENT>22 16 46 0</AMBIENT>+ <DIFFUSE>49 49 49 0</DIFFUSE>+ <SPECULAR>229 229 229 0</SPECULAR>+ <SHININESS>0.8</SHININESS>+</MATERIAL>
binary file changed (absent → 4632 bytes)
binary file changed (absent → 4632 bytes)
binary file changed (absent → 11416 bytes)
binary file changed (absent → 11408 bytes)
binary file changed (absent → 22176 bytes)
binary file changed (absent → 2680 bytes)
binary file changed (absent → 28728 bytes)
binary file changed (absent → 3528 bytes)
binary file changed (absent → 3528 bytes)
binary file changed (absent → 2364 bytes)
binary file changed (absent → 8672 bytes)
@@ -0,0 +1,7 @@+<HEADER MAGIC="XRF" VERSION="900" />+<MATERIAL NUMMAPS="0">+ <AMBIENT>128 128 128 0</AMBIENT>+ <DIFFUSE>224 224 224 0</DIFFUSE>+ <SPECULAR>255 255 255 0</SPECULAR>+ <SHININESS>0.05</SHININESS>+</MATERIAL>
binary file changed (absent → 4836 bytes)
@@ -0,0 +1,7 @@+<HEADER MAGIC="XRF" VERSION="900" />+<MATERIAL NUMMAPS="0">+ <AMBIENT>82 85 128 0</AMBIENT>+ <DIFFUSE>163 169 255 0</DIFFUSE>+ <SPECULAR>229 229 229 0</SPECULAR>+ <SHININESS>0.05</SHININESS>+</MATERIAL>
binary file changed (absent → 181456 bytes)
@@ -0,0 +1,7 @@+<HEADER MAGIC="XRF" VERSION="900" />+<MATERIAL NUMMAPS="0">+ <AMBIENT>128 98 98 0</AMBIENT>+ <DIFFUSE>240 184 184 0</DIFFUSE>+ <SPECULAR>229 229 229 0</SPECULAR>+ <SHININESS>0.05</SHININESS>+</MATERIAL>
binary file changed (absent → 50040 bytes)
binary file changed (absent → 7688 bytes)
binary file changed (absent → 7688 bytes)
binary file changed (absent → 145944 bytes)
binary file changed (absent → 4560 bytes)
binary file changed (absent → 4560 bytes)
binary file changed (absent → 37016 bytes)
binary file changed (absent → 45376 bytes)