diff options
| -rw-r--r-- | Spear.lkshs | 12 | ||||
| -rw-r--r-- | Spear.lkshw | 2 | ||||
| -rw-r--r-- | Spear/Assets/Model.hsc | 378 | ||||
| -rw-r--r-- | Spear/Assets/Model/Model.c | 56 | ||||
| -rw-r--r-- | Spear/Assets/Model/Model.h | 6 | ||||
| -rw-r--r-- | Spear/Render/Model.hsc | 4 | ||||
| -rw-r--r-- | Spear/Scene/Loader.hs | 37 |
7 files changed, 211 insertions, 284 deletions
diff --git a/Spear.lkshs b/Spear.lkshs index afbce39..d69e4f9 100644 --- a/Spear.lkshs +++ b/Spear.lkshs | |||
| @@ -1,18 +1,18 @@ | |||
| 1 | Version of session file format: | 1 | Version of session file format: |
| 2 | 1 | 2 | 1 |
| 3 | Time of storage: | 3 | Time of storage: |
| 4 | "Thu Aug 9 13:31:29 CEST 2012" | 4 | "Fri Aug 10 15:19:04 CEST 2012" |
| 5 | Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 6, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [("Browser",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 266) 197)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 702) 954 | 5 | Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 4, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [("Browser",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 255) 201)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 707) 954 |
| 6 | Population: [(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/GameObject.hs" 259)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/GameState.hs" 670)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Sys/Store/ID.hs" 96)),[SplitP LeftP]),(Just (InfoSt (InfoState (Just (Real (RealDescr {dscName' = "storeFree", dscMbTypeStr' = Just "storeFree :: Index -> Store a -> Store a", dscMbModu' = Just (PM {pack = PackageIdentifier {pkgName = PackageName "Spear", pkgVersion = Version {versionBranch = [0,1], versionTags = []}}, modu = ModuleName ["Spear","Sys","Store"]}), dscMbLocation' = Just (Location {locationSLine = 101, locationSCol = 1, locationELine = 108, locationECol = 32}), dscMbComment' = Just " Free the given slot.", dscTypeHint' = VariableDescr, dscExported' = True}))))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Just (ModuleName ["Spear","Sys","Store"]),Just "storeFree") (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([[0,9],[0]],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([[5]],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics.hs" 207)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics/Rigid.hs" 2175)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Sys/Store.hs" 4136)),[SplitP LeftP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics/World.hs" 287)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs" 204)),[SplitP LeftP])] | 6 | Population: [(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (InfoSt (InfoState Nothing)),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/Loader.hs" 6686)),[SplitP LeftP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/MD2/MD2_load.c" 13934)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/Model.c" 433)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/Model.h" 1424)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Assets/Model.hsc" 12957)),[SplitP LeftP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Nothing,Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([[0,2],[0]],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/OBJ/OBJ_load.cc" 266)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/OBJ/OBJ_load.h" 0)),[SplitP LeftP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP])] |
| 7 | Window size: (1841,964) | 7 | Window size: (1841,964) |
| 8 | Completion size: | 8 | Completion size: |
| 9 | (750,400) | 9 | (750,400) |
| 10 | Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" | 10 | Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" |
| 11 | Active pane: Just "World.hs" | 11 | Active pane: Just "Model.hsc" |
| 12 | Toolbar visible: | 12 | Toolbar visible: |
| 13 | True | 13 | True |
| 14 | FindbarState: (False,FindState {entryStr = "asda", entryHist = ["assigned","Triangle","transforma","gravity","asdad","rotSpeed","azimuth","mandatory","mandao","col","forward","MouseButton"], replaceStr = "objects", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1}) | 14 | FindbarState: (False,FindState {entryStr = "asd", entryHist = ["allocaBytes","copyArray","allocaArray","allocaa","putStrLn","assigned","Triangle","transforma","gravity","asdad","rotSpeed","azimuth"], replaceStr = "objects", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1}) |
| 15 | Recently opened files: | 15 | Recently opened files: |
| 16 | ["/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/Model.h","/home/jeanne/programming/haskell/Spear/Spear/Assets/Model.hsc","/home/jeanne/programming/haskell/Spear/Spear/Math/Spatial.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/Triangle.hs","/home/jeanne/programming/haskell/Spear/Spear/Render/Triangle.hs","/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/Model.c","/home/jeanne/programming/haskell/Spear/Spear/Scene/Loader.hs","/home/jeanne/programming/haskell/Spear/Spear/IDStore.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Spear/IDStore.hs","/home/jeanne/programming/haskell/Spear/Spear/Physics/Types.hs","/home/jeanne/programming/haskell/Spear/Spear/Collision/Collision.hs","/home/jeanne/programming/haskell/Spear/Spear/Collision/Collisioner.hs"] | 16 | ["/home/jeanne/programming/haskell/Spear/Spear/Assets/Image.hsc","/home/jeanne/programming/haskell/Spear/Spear/Render/Model.hsc","/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Player.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameMessage.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Factory.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Animation/Ogro.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/AnimatedGO.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/StaticGO.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Render.hs"] |
| 17 | Recently opened workspaces: | 17 | Recently opened workspaces: |
| 18 | ["/home/jeanne/leksah.lkshw"] \ No newline at end of file | 18 | ["/home/jeanne/leksah.lkshw"] \ No newline at end of file |
diff --git a/Spear.lkshw b/Spear.lkshw index 2291729..143acdc 100644 --- a/Spear.lkshw +++ b/Spear.lkshw | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | Version of workspace file format: | 1 | Version of workspace file format: |
| 2 | 1 | 2 | 1 |
| 3 | Time of storage: | 3 | Time of storage: |
| 4 | "Wed Aug 8 21:04:06 CEST 2012" | 4 | "Fri Aug 10 15:56:20 CEST 2012" |
| 5 | Name of the workspace: | 5 | Name of the workspace: |
| 6 | "Spear" | 6 | "Spear" |
| 7 | File paths of contained packages: | 7 | File paths of contained packages: |
diff --git a/Spear/Assets/Model.hsc b/Spear/Assets/Model.hsc index cb0ef3f..b7cb90d 100644 --- a/Spear/Assets/Model.hsc +++ b/Spear/Assets/Model.hsc | |||
| @@ -3,28 +3,20 @@ | |||
| 3 | module Spear.Assets.Model | 3 | module Spear.Assets.Model |
| 4 | ( | 4 | ( |
| 5 | -- * Data types | 5 | -- * Data types |
| 6 | ModelErrorCode | 6 | Vec3(..) |
| 7 | , Vec3(..) | ||
| 8 | , TexCoord(..) | 7 | , TexCoord(..) |
| 9 | , CModel | 8 | , CTriangle(..) |
| 9 | , Skin(..) | ||
| 10 | , Animation(..) | 10 | , Animation(..) |
| 11 | , Triangle(..) | 11 | , Triangle(..) |
| 12 | , Model | 12 | , Model(..) |
| 13 | -- * Loading and unloading | 13 | -- * Loading |
| 14 | , loadModel | 14 | , loadModel |
| 15 | , releaseModel | ||
| 16 | -- * Accessors | 15 | -- * Accessors |
| 17 | , animated | 16 | , animated |
| 18 | , numFrames | ||
| 19 | , numVertices | ||
| 20 | , numTriangles | ||
| 21 | , numTexCoords | ||
| 22 | , numSkins | ||
| 23 | , cmodel | ||
| 24 | , animation | 17 | , animation |
| 25 | , animationByName | 18 | , animationByName |
| 26 | , numAnimations | 19 | , triangles' |
| 27 | , triangles | ||
| 28 | -- * Manipulation | 20 | -- * Manipulation |
| 29 | , transformVerts | 21 | , transformVerts |
| 30 | , transformNormals | 22 | , transformNormals |
| @@ -34,15 +26,12 @@ where | |||
| 34 | 26 | ||
| 35 | 27 | ||
| 36 | import Spear.Setup | 28 | import Spear.Setup |
| 37 | import qualified Spear.Math.Matrix4 as M4 | ||
| 38 | import qualified Spear.Math.Matrix3 as M3 | ||
| 39 | import Spear.Math.MatrixUtils | ||
| 40 | 29 | ||
| 41 | 30 | ||
| 42 | import qualified Data.ByteString.Char8 as B | 31 | import qualified Data.ByteString.Char8 as B |
| 43 | import Data.Char (toLower) | 32 | import Data.Char (toLower) |
| 44 | import Data.List (splitAt, elemIndex) | 33 | import Data.List (splitAt, elemIndex) |
| 45 | import qualified Data.Vector as V | 34 | import qualified Data.Vector.Storable as V |
| 46 | import Foreign.Ptr | 35 | import Foreign.Ptr |
| 47 | import Foreign.Storable | 36 | import Foreign.Storable |
| 48 | import Foreign.C.Types | 37 | import Foreign.C.Types |
| @@ -69,10 +58,11 @@ data ModelErrorCode | |||
| 69 | 58 | ||
| 70 | 59 | ||
| 71 | sizeFloat = #{size float} | 60 | sizeFloat = #{size float} |
| 61 | sizePtr = #{size int*} | ||
| 72 | 62 | ||
| 73 | 63 | ||
| 74 | -- | A 3D vector. | 64 | -- | A 3D vector. |
| 75 | data Vec3 = Vec3 !CFloat !CFloat !CFloat | 65 | data Vec3 = Vec3 !Float !Float !Float |
| 76 | 66 | ||
| 77 | 67 | ||
| 78 | instance Storable Vec3 where | 68 | instance Storable Vec3 where |
| @@ -92,7 +82,7 @@ instance Storable Vec3 where | |||
| 92 | 82 | ||
| 93 | 83 | ||
| 94 | -- | A 2D texture coordinate. | 84 | -- | A 2D texture coordinate. |
| 95 | data TexCoord = TexCoord !CFloat !CFloat | 85 | data TexCoord = TexCoord !Float !Float |
| 96 | 86 | ||
| 97 | 87 | ||
| 98 | instance Storable TexCoord where | 88 | instance Storable TexCoord where |
| @@ -109,97 +99,154 @@ instance Storable TexCoord where | |||
| 109 | pokeByteOff ptr sizeFloat f1 | 99 | pokeByteOff ptr sizeFloat f1 |
| 110 | 100 | ||
| 111 | 101 | ||
| 112 | data CTriangle = CTriangle !CUShort !CUShort !CUShort !CUShort !CUShort !CUShort | 102 | -- | A raw triangle holding vertex/normal and texture indices. |
| 103 | data CTriangle = CTriangle | ||
| 104 | { vertexIndex0 :: !CUShort | ||
| 105 | , vertexIndex1 :: !CUShort | ||
| 106 | , vertexIndex2 :: !CUShort | ||
| 107 | , textureIndex1 :: !CUShort | ||
| 108 | , textureIndex2 :: !CUShort | ||
| 109 | , textureIndex3 :: !CUShort | ||
| 110 | } | ||
| 113 | 111 | ||
| 114 | 112 | ||
| 115 | data Skin = Skin !(Ptr Char) | 113 | instance Storable CTriangle where |
| 114 | sizeOf _ = #{size triangle} | ||
| 115 | alignment _ = alignment (undefined :: CUShort) | ||
| 116 | |||
| 117 | peek ptr = do | ||
| 118 | v0 <- #{peek triangle, vertexIndices[0]} ptr | ||
| 119 | v1 <- #{peek triangle, vertexIndices[1]} ptr | ||
| 120 | v2 <- #{peek triangle, vertexIndices[2]} ptr | ||
| 121 | |||
| 122 | t0 <- #{peek triangle, textureIndices[0]} ptr | ||
| 123 | t1 <- #{peek triangle, textureIndices[1]} ptr | ||
| 124 | t2 <- #{peek triangle, textureIndices[2]} ptr | ||
| 125 | |||
| 126 | return $ CTriangle v0 v1 v2 t0 t1 t2 | ||
| 127 | |||
| 128 | poke ptr (CTriangle v0 v1 v2 t0 t1 t2) = do | ||
| 129 | #{poke triangle, vertexIndices[0]} ptr v0 | ||
| 130 | #{poke triangle, vertexIndices[1]} ptr v1 | ||
| 131 | #{poke triangle, vertexIndices[2]} ptr v2 | ||
| 132 | |||
| 133 | #{poke triangle, textureIndices[0]} ptr t0 | ||
| 134 | #{poke triangle, textureIndices[1]} ptr t1 | ||
| 135 | #{poke triangle, textureIndices[2]} ptr t2 | ||
| 116 | 136 | ||
| 117 | 137 | ||
| 118 | data CAnimation = CAnimation !B.ByteString !CUInt !CUInt | 138 | -- | A model skin. |
| 139 | newtype Skin = Skin { skinName :: B.ByteString } | ||
| 119 | 140 | ||
| 120 | 141 | ||
| 121 | -- | The model's underlying representation. | 142 | instance Storable Skin where |
| 122 | data CModel = CModel | 143 | sizeOf (Skin s) = 64 |
| 123 | { cVerts :: Ptr Vec3 -- ^ Pointer to an array of 'cnFrames' * 'cnVerts' vertices. | 144 | alignment _ = 1 |
| 124 | , cNormals :: Ptr Vec3 -- ^ Pointer to an array of 'cnFrames' * cnVerts normals. | 145 | |
| 125 | , cTexCoords :: Ptr TexCoord -- ^ Pointer to an array of 'cnTris' texture coordinates. | 146 | peek ptr = do |
| 126 | , cTris :: Ptr CTriangle -- ^ Pointer to an array of 'cnTris' triangles. | 147 | s <- B.packCString $ unsafeCoerce ptr |
| 127 | , cSkins :: Ptr Skin -- ^ Pointer to an array of 'cnSkins' skins. | 148 | return $ Skin s |
| 128 | , cAnimations :: Ptr CAnimation -- ^ Pointer to an array of 'cnAnimations' animations. | 149 | |
| 129 | , cnFrames :: CUInt -- ^ Number of frames. | 150 | poke ptr (Skin s) = do |
| 130 | , cnVerts :: CUInt -- ^ Number of vertices per frame. | 151 | B.useAsCStringLen s $ \(sptr, len) -> copyArray (unsafeCoerce ptr) sptr len |
| 131 | , cnTris :: CUInt -- ^ Number of triangles in one frame. | ||
| 132 | , cnTexCoords :: CUInt -- ^ Number of texture coordinates in one frame. | ||
| 133 | , cnSkins :: CUInt -- ^ Number of skins. | ||
| 134 | , cnAnimations :: CUInt -- ^ Number of animations. | ||
| 135 | } | ||
| 136 | 152 | ||
| 137 | 153 | ||
| 138 | instance Storable CModel where | 154 | -- | A model animation. |
| 139 | sizeOf _ = #{size Model} | 155 | -- |
| 140 | alignment _ = alignment (undefined :: CUInt) | 156 | -- See also: 'animation', 'animationByName', 'numAnimations'. |
| 157 | data Animation = Animation | ||
| 158 | { name :: B.ByteString | ||
| 159 | , start :: Int | ||
| 160 | , end :: Int | ||
| 161 | } | ||
| 141 | 162 | ||
| 142 | peek ptr = do | ||
| 143 | vertices <- #{peek Model, vertices} ptr | ||
| 144 | normals <- #{peek Model, normals} ptr | ||
| 145 | texCoords <- #{peek Model, texCoords} ptr | ||
| 146 | triangles <- #{peek Model, triangles} ptr | ||
| 147 | skins <- #{peek Model, skins} ptr | ||
| 148 | animations <- #{peek Model, animations} ptr | ||
| 149 | numFrames <- #{peek Model, numFrames} ptr | ||
| 150 | numVertices <- #{peek Model, numVertices} ptr | ||
| 151 | numTriangles <- #{peek Model, numTriangles} ptr | ||
| 152 | numTexCoords <- #{peek Model, numTexCoords} ptr | ||
| 153 | numSkins <- #{peek Model, numSkins} ptr | ||
| 154 | numAnimations <- #{peek Model, numAnimations} ptr | ||
| 155 | return $ | ||
| 156 | CModel vertices normals texCoords triangles skins animations | ||
| 157 | numFrames numVertices numTriangles numTexCoords numSkins numAnimations | ||
| 158 | 163 | ||
| 159 | poke ptr | 164 | instance Storable Animation where |
| 160 | (CModel verts normals texCoords tris skins animations | ||
| 161 | numFrames numVerts numTris numTex numSkins numAnimations) = do | ||
| 162 | #{poke Model, vertices} ptr verts | ||
| 163 | #{poke Model, normals} ptr normals | ||
| 164 | #{poke Model, texCoords} ptr texCoords | ||
| 165 | #{poke Model, triangles} ptr tris | ||
| 166 | #{poke Model, skins} ptr skins | ||
| 167 | #{poke Model, animations} ptr animations | ||
| 168 | #{poke Model, numFrames} ptr numFrames | ||
| 169 | #{poke Model, numVertices} ptr numVerts | ||
| 170 | #{poke Model, numTriangles} ptr numTris | ||
| 171 | #{poke Model, numTexCoords} ptr numTex | ||
| 172 | #{poke Model, numSkins} ptr numSkins | ||
| 173 | #{poke Model, numAnimations} ptr numAnimations | ||
| 174 | |||
| 175 | |||
| 176 | -- data CAnimation = CAnimation !(Ptr CChar) !CUInt !CUInt | ||
| 177 | instance Storable CAnimation where | ||
| 178 | sizeOf _ = #{size animation} | 165 | sizeOf _ = #{size animation} |
| 179 | alignment _ = alignment (undefined :: CUInt) | 166 | alignment _ = alignment (undefined :: CUInt) |
| 180 | 167 | ||
| 181 | peek ptr = do | 168 | peek ptr = do |
| 182 | name <- B.packCString (unsafeCoerce ptr) | 169 | name <- B.packCString (unsafeCoerce ptr) |
| 183 | start <- #{peek animation, start} ptr | 170 | start <- #{peek animation, start} ptr |
| 184 | end <- #{peek animation, end} ptr | 171 | end <- #{peek animation, end} ptr |
| 185 | return $ CAnimation name start end | 172 | return $ Animation name start end |
| 186 | 173 | ||
| 187 | poke ptr (CAnimation name start end) = do | 174 | poke ptr (Animation name start end) = do |
| 188 | B.useAsCStringLen name $ \(sptr, len) -> copyArray (unsafeCoerce ptr) sptr len | 175 | B.useAsCStringLen name $ \(sptr, len) -> copyArray (unsafeCoerce ptr) sptr len |
| 189 | #{poke animation, start} ptr start | 176 | #{poke animation, start} ptr start |
| 190 | #{poke animation, end} ptr end | 177 | #{poke animation, end} ptr end |
| 191 | 178 | ||
| 192 | 179 | ||
| 193 | -- | A model's animation. | 180 | -- | A 3D model. |
| 194 | -- | 181 | data Model = Model |
| 195 | -- See also: 'animation', 'animationByName', 'numAnimations'. | 182 | { vertices :: V.Vector Vec3 -- ^ Array of 'numFrames' * 'numVerts' vertices. |
| 196 | data Animation = Animation | 183 | , normals :: V.Vector Vec3 -- ^ Array of 'numFrames' * 'numVerts' normals. |
| 197 | { name :: String | 184 | , texCoords :: V.Vector TexCoord -- ^ Array of 'numTexCoords' texture coordinates. |
| 198 | , start :: Int | 185 | , triangles :: V.Vector CTriangle -- ^ Array of 'numTriangles' triangles. |
| 199 | , end :: Int | 186 | , skins :: V.Vector Skin -- ^ Array of 'numSkins' skins. |
| 187 | , animations :: V.Vector Animation -- ^ Array of 'numAnimations' animations. | ||
| 188 | , numFrames :: Int -- ^ Number of frames. | ||
| 189 | , numVerts :: Int -- ^ Number of vertices (and normals) per frame. | ||
| 190 | , numTriangles :: Int -- ^ Number of triangles in one frame. | ||
| 191 | , numTexCoords :: Int -- ^ Number of texture coordinates in one frame. | ||
| 192 | , numSkins :: Int -- ^ Number of skins. | ||
| 193 | , numAnimations :: Int -- ^ Number of animations. | ||
| 200 | } | 194 | } |
| 201 | 195 | ||
| 202 | 196 | ||
| 197 | instance Storable Model where | ||
| 198 | sizeOf _ = #{size Model} | ||
| 199 | alignment _ = alignment (undefined :: CUInt) | ||
| 200 | |||
| 201 | peek ptr = do | ||
| 202 | numFrames <- #{peek Model, numFrames} ptr | ||
| 203 | numVertices <- #{peek Model, numVertices} ptr | ||
| 204 | numTriangles <- #{peek Model, numTriangles} ptr | ||
| 205 | numTexCoords <- #{peek Model, numTexCoords} ptr | ||
| 206 | numSkins <- #{peek Model, numSkins} ptr | ||
| 207 | numAnimations <- #{peek Model, numAnimations} ptr | ||
| 208 | pVerts <- peek (unsafeCoerce ptr) | ||
| 209 | pNormals <- peekByteOff ptr sizePtr | ||
| 210 | pTexCoords <- peekByteOff ptr (2*sizePtr) | ||
| 211 | pTriangles <- peekByteOff ptr (3*sizePtr) | ||
| 212 | pSkins <- peekByteOff ptr (4*sizePtr) | ||
| 213 | pAnimations <- peekByteOff ptr (5*sizePtr) | ||
| 214 | vertices <- fmap V.fromList $ peekArray (numVertices*numFrames) pVerts | ||
| 215 | normals <- fmap V.fromList $ peekArray (numVertices*numFrames) pNormals | ||
| 216 | texCoords <- fmap V.fromList $ peekArray numTexCoords pTexCoords | ||
| 217 | triangles <- fmap V.fromList $ peekArray numTriangles pTriangles | ||
| 218 | skins <- fmap V.fromList $ peekArray numSkins pSkins | ||
| 219 | animations <- fmap V.fromList $ peekArray numAnimations pAnimations | ||
| 220 | return $ | ||
| 221 | Model vertices normals texCoords triangles skins animations | ||
| 222 | numFrames numVertices numTriangles numTexCoords numSkins numAnimations | ||
| 223 | |||
| 224 | poke ptr | ||
| 225 | (Model verts normals texCoords tris skins animations | ||
| 226 | numFrames numVerts numTris numTex numSkins numAnimations) = | ||
| 227 | V.unsafeWith verts $ \pVerts -> | ||
| 228 | V.unsafeWith normals $ \pNormals -> | ||
| 229 | V.unsafeWith texCoords $ \pTexCoords -> | ||
| 230 | V.unsafeWith tris $ \pTris -> | ||
| 231 | V.unsafeWith skins $ \pSkins -> | ||
| 232 | V.unsafeWith animations $ \pAnimations -> do | ||
| 233 | #{poke Model, vertices} ptr pVerts | ||
| 234 | #{poke Model, normals} ptr pNormals | ||
| 235 | #{poke Model, texCoords} ptr pTexCoords | ||
| 236 | #{poke Model, triangles} ptr pTris | ||
| 237 | #{poke Model, skins} ptr pSkins | ||
| 238 | #{poke Model, animations} ptr pAnimations | ||
| 239 | #{poke Model, numFrames} ptr numFrames | ||
| 240 | #{poke Model, numVertices} ptr numVerts | ||
| 241 | #{poke Model, numTriangles} ptr numTris | ||
| 242 | #{poke Model, numTexCoords} ptr numTex | ||
| 243 | #{poke Model, numSkins} ptr numSkins | ||
| 244 | #{poke Model, numAnimations} ptr numAnimations | ||
| 245 | |||
| 246 | |||
| 247 | -- | A model triangle. | ||
| 248 | -- | ||
| 249 | -- See also: 'triangles''. | ||
| 203 | data Triangle = Triangle | 250 | data Triangle = Triangle |
| 204 | { v0 :: Vec3 | 251 | { v0 :: Vec3 |
| 205 | , v1 :: Vec3 | 252 | , v1 :: Vec3 |
| @@ -241,87 +288,58 @@ instance Storable Triangle where | |||
| 241 | #{poke model_triangle, t2} ptr t2 | 288 | #{poke model_triangle, t2} ptr t2 |
| 242 | 289 | ||
| 243 | 290 | ||
| 244 | -- | A model 'Resource'. | ||
| 245 | data Model = Model | ||
| 246 | { modelData :: CModel | ||
| 247 | , mAnimations :: V.Vector Animation | ||
| 248 | , rkey :: Resource | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | foreign import ccall "Model.h model_free" | 291 | foreign import ccall "Model.h model_free" |
| 253 | model_free :: Ptr CModel -> IO () | 292 | model_free :: Ptr Model -> IO () |
| 254 | 293 | ||
| 255 | 294 | ||
| 256 | foreign import ccall "MD2_load.h MD2_load" | 295 | foreign import ccall "MD2_load.h MD2_load" |
| 257 | md2_load' :: Ptr CChar -> CChar -> CChar -> Ptr CModel -> IO Int | 296 | md2_load' :: Ptr CChar -> CChar -> CChar -> Ptr Model -> IO Int |
| 258 | 297 | ||
| 259 | 298 | ||
| 260 | foreign import ccall "OBJ_load.h OBJ_load" | 299 | foreign import ccall "OBJ_load.h OBJ_load" |
| 261 | obj_load' :: Ptr CChar -> CChar -> CChar -> Ptr CModel -> IO Int | 300 | obj_load' :: Ptr CChar -> CChar -> CChar -> Ptr Model -> IO Int |
| 262 | 301 | ||
| 263 | 302 | ||
| 264 | md2_load :: Ptr CChar -> CChar -> CChar -> Ptr CModel -> IO ModelErrorCode | 303 | md2_load :: Ptr CChar -> CChar -> CChar -> Ptr Model -> IO ModelErrorCode |
| 265 | md2_load file clockwise leftHanded model = | 304 | md2_load file clockwise leftHanded model = |
| 266 | md2_load' file clockwise leftHanded model >>= \code -> return . toEnum $ code | 305 | md2_load' file clockwise leftHanded model >>= \code -> return . toEnum $ code |
| 267 | 306 | ||
| 268 | 307 | ||
| 269 | obj_load :: Ptr CChar -> CChar -> CChar -> Ptr CModel -> IO ModelErrorCode | 308 | obj_load :: Ptr CChar -> CChar -> CChar -> Ptr Model -> IO ModelErrorCode |
| 270 | obj_load file clockwise leftHanded model = | 309 | obj_load file clockwise leftHanded model = |
| 271 | obj_load' file clockwise leftHanded model >>= \code -> return . toEnum $ code | 310 | obj_load' file clockwise leftHanded model >>= \code -> return . toEnum $ code |
| 272 | 311 | ||
| 273 | 312 | ||
| 274 | -- | Load the model specified by the given 'FilePath'. | 313 | -- | Load the model specified by the given file. |
| 275 | loadModel :: FilePath -> Setup Model | 314 | loadModel :: FilePath -> Setup Model |
| 276 | loadModel file = do | 315 | loadModel file = do |
| 277 | dotPos <- case elemIndex '.' file of | 316 | dotPos <- case elemIndex '.' file of |
| 278 | Nothing -> setupError $ "file name has no extension: " ++ file | 317 | Nothing -> setupError $ "file name has no extension: " ++ file |
| 279 | Just p -> return p | 318 | Just p -> return p |
| 280 | 319 | ||
| 281 | let ext = map toLower . tail . snd $ splitAt dotPos file | 320 | let ext = map toLower . tail . snd $ splitAt dotPos file |
| 282 | 321 | ||
| 283 | result <- setupIO . alloca $ \ptr -> do | 322 | result <- setupIO . alloca $ \ptr -> do |
| 284 | status <- withCString file $ \fileCstr -> do | 323 | status <- withCString file $ \fileCstr -> do |
| 285 | case ext of | 324 | case ext of |
| 286 | "md2" -> md2_load fileCstr 0 0 ptr | 325 | "md2" -> md2_load fileCstr 0 0 ptr |
| 287 | "obj" -> obj_load fileCstr 0 0 ptr | 326 | "obj" -> obj_load fileCstr 0 0 ptr |
| 288 | _ -> return ModelNoSuitableLoader | 327 | _ -> return ModelNoSuitableLoader |
| 289 | 328 | ||
| 290 | case status of | 329 | case status of |
| 291 | ModelSuccess -> peek ptr >>= return . Right | 330 | ModelSuccess -> do |
| 331 | model <- peek ptr | ||
| 332 | model_free ptr | ||
| 333 | return . Right $ model | ||
| 292 | ModelReadError -> return . Left $ "read error" | 334 | ModelReadError -> return . Left $ "read error" |
| 293 | ModelMemoryAllocationError -> return . Left $ "memory allocation error" | 335 | ModelMemoryAllocationError -> return . Left $ "memory allocation error" |
| 294 | ModelFileNotFound -> return . Left $ "file not found" | 336 | ModelFileNotFound -> return . Left $ "file not found" |
| 295 | ModelFileMismatch -> return . Left $ "file mismatch" | 337 | ModelFileMismatch -> return . Left $ "file mismatch" |
| 296 | ModelNoSuitableLoader -> return . Left $ "no suitable loader for extension " ++ ext | 338 | ModelNoSuitableLoader -> return . Left $ "no suitable loader for extension " ++ ext |
| 297 | 339 | ||
| 298 | case result of | 340 | case result of |
| 299 | Right model -> | 341 | Right model -> return model |
| 300 | let numAnimations = fromIntegral $ cnAnimations model | 342 | Left err -> setupError $ "loadModel: " ++ err |
| 301 | in register (freeModel model) >>= | ||
| 302 | case numAnimations of | ||
| 303 | 0 -> return . Model model V.empty | ||
| 304 | _ -> \key -> setupIO $ do | ||
| 305 | canims <- peekArray numAnimations $ cAnimations model | ||
| 306 | let animations = V.fromList $ fmap fromCAnimation canims | ||
| 307 | return $ Model model animations key | ||
| 308 | |||
| 309 | Left err -> setupError $ "loadModel: " ++ err | ||
| 310 | |||
| 311 | |||
| 312 | fromCAnimation :: CAnimation -> Animation | ||
| 313 | fromCAnimation (CAnimation cname start end) = | ||
| 314 | Animation (B.unpack cname) (fromIntegral start) (fromIntegral end) | ||
| 315 | |||
| 316 | |||
| 317 | -- | Release the model. | ||
| 318 | releaseModel :: Model -> Setup () | ||
| 319 | releaseModel = release . rkey | ||
| 320 | |||
| 321 | |||
| 322 | -- | Free the C model. | ||
| 323 | freeModel :: CModel -> IO () | ||
| 324 | freeModel model = Foreign.with model model_free | ||
| 325 | 343 | ||
| 326 | 344 | ||
| 327 | -- | Return 'True' if the model is animated, 'False' otherwise. | 345 | -- | Return 'True' if the model is animated, 'False' otherwise. |
| @@ -329,55 +347,21 @@ animated :: Model -> Bool | |||
| 329 | animated = (>1) . numFrames | 347 | animated = (>1) . numFrames |
| 330 | 348 | ||
| 331 | 349 | ||
| 332 | -- | Return the model's number of frames. | ||
| 333 | numFrames :: Model -> Int | ||
| 334 | numFrames = fromIntegral . cnFrames . modelData | ||
| 335 | |||
| 336 | |||
| 337 | -- | Return the model's number of vertices. | ||
| 338 | numVertices :: Model -> Int | ||
| 339 | numVertices = fromIntegral . cnVerts . modelData | ||
| 340 | |||
| 341 | |||
| 342 | -- | Return the model's number of triangles. | ||
| 343 | numTriangles :: Model -> Int | ||
| 344 | numTriangles = fromIntegral . cnTris . modelData | ||
| 345 | |||
| 346 | |||
| 347 | -- | Return the model's number of texture coordinates. | ||
| 348 | numTexCoords :: Model -> Int | ||
| 349 | numTexCoords = fromIntegral . cnTexCoords . modelData | ||
| 350 | |||
| 351 | |||
| 352 | -- | Return the model's number of skins. | ||
| 353 | numSkins :: Model -> Int | ||
| 354 | numSkins = fromIntegral . cnSkins . modelData | ||
| 355 | |||
| 356 | |||
| 357 | -- | Return the underlying C model. | ||
| 358 | cmodel :: Model -> CModel | ||
| 359 | cmodel = modelData | ||
| 360 | |||
| 361 | |||
| 362 | -- | Return the model's ith animation. | 350 | -- | Return the model's ith animation. |
| 363 | animation :: Model -> Int -> Animation | 351 | animation :: Model -> Int -> Animation |
| 364 | animation model i = mAnimations model V.! i | 352 | animation model i = animations model V.! i |
| 365 | 353 | ||
| 366 | 354 | ||
| 367 | -- | Return the animation specified by the given string. | 355 | -- | Return the animation specified by the given string. |
| 368 | animationByName :: Model -> String -> Maybe Animation | 356 | animationByName :: Model -> String -> Maybe Animation |
| 369 | animationByName model anim = V.find ((==) anim . name) $ mAnimations model | 357 | animationByName model anim = |
| 370 | 358 | let anim' = B.pack anim in V.find ((==) anim' . name) $ animations model | |
| 371 | |||
| 372 | -- | Return the number of animations of the given model. | ||
| 373 | numAnimations :: Model -> Int | ||
| 374 | numAnimations = V.length . mAnimations | ||
| 375 | 359 | ||
| 376 | 360 | ||
| 377 | -- | Return a copy of the model's triangles. | 361 | -- | Return a copy of the model's triangles. |
| 378 | triangles :: Model -> IO [Triangle] | 362 | triangles' :: Model -> IO [Triangle] |
| 379 | triangles m@(Model model _ _) = | 363 | triangles' model = |
| 380 | let n = numVertices m * numFrames m | 364 | let n = numVerts model * numFrames model |
| 381 | in with model $ \modelPtr -> | 365 | in with model $ \modelPtr -> |
| 382 | allocaArray n $ \arrayPtr -> do | 366 | allocaArray n $ \arrayPtr -> do |
| 383 | model_copy_triangles modelPtr arrayPtr | 367 | model_copy_triangles modelPtr arrayPtr |
| @@ -386,39 +370,35 @@ triangles m@(Model model _ _) = | |||
| 386 | 370 | ||
| 387 | 371 | ||
| 388 | foreign import ccall "Model.h model_copy_triangles" | 372 | foreign import ccall "Model.h model_copy_triangles" |
| 389 | model_copy_triangles :: Ptr CModel -> Ptr Triangle -> IO () | 373 | model_copy_triangles :: Ptr Model -> Ptr Triangle -> IO () |
| 390 | |||
| 391 | |||
| 392 | -- | Transform the model's vertices with the given matrix. | ||
| 393 | transformVerts :: M4.Matrix4 -> Model -> IO () | ||
| 394 | transformVerts mat (Model model _ _) = | ||
| 395 | allocaBytes (16*sizeFloat) $ \matPtr -> | ||
| 396 | with model $ \modelPtr -> do | ||
| 397 | poke matPtr mat | ||
| 398 | model_transform_vertices modelPtr matPtr | ||
| 399 | |||
| 400 | |||
| 401 | -- | Transform the model's normals with the given matrix. | ||
| 402 | transformNormals :: M3.Matrix3 -> Model -> IO () | ||
| 403 | transformNormals mat (Model model _ _) = | ||
| 404 | allocaBytes (9*sizeFloat) $ \normalPtr -> | ||
| 405 | with model $ \modelPtr -> do | ||
| 406 | poke normalPtr mat | ||
| 407 | model_transform_normals modelPtr normalPtr | ||
| 408 | 374 | ||
| 409 | 375 | ||
| 410 | foreign import ccall "Model.h model_transform_vertices" | 376 | -- | Transform the model's vertices. |
| 411 | model_transform_vertices :: Ptr CModel -> Ptr M4.Matrix4 -> IO () | 377 | transformVerts :: Model -> (Vec3 -> Vec3) -> Model |
| 378 | transformVerts model f = model { vertices = vertices' } | ||
| 379 | where | ||
| 380 | n = numVerts model * numFrames model | ||
| 381 | vertices' = V.generate n f' | ||
| 382 | f' i = f $ vertices model V.! i | ||
| 412 | 383 | ||
| 413 | 384 | ||
| 414 | foreign import ccall "Model.h model_transform_normals" | 385 | -- | Transform the model's normals. |
| 415 | model_transform_normals :: Ptr CModel -> Ptr M3.Matrix3 -> IO () | 386 | transformNormals :: Model -> (Vec3 -> Vec3) -> Model |
| 387 | transformNormals model f = model { normals = normals' } | ||
| 388 | where | ||
| 389 | n = numVerts model * numFrames model | ||
| 390 | normals' = V.generate n f' | ||
| 391 | f' i = f $ normals model V.! i | ||
| 416 | 392 | ||
| 417 | 393 | ||
| 418 | -- | Transform the model such that its lowest point has y = 0. | 394 | -- | Translate the model such that its lowest point has y = 0. |
| 419 | toGround :: Model -> IO () | 395 | toGround :: Model -> IO Model |
| 420 | toGround (Model model _ _) = with model model_to_ground | 396 | toGround model = |
| 397 | let model' = model { vertices = V.generate n $ \i -> vertices model V.! i } | ||
| 398 | n = numVerts model * numFrames model | ||
| 399 | in | ||
| 400 | with model' model_to_ground >> return model' | ||
| 421 | 401 | ||
| 422 | 402 | ||
| 423 | foreign import ccall "Model.h model_to_ground" | 403 | foreign import ccall "Model.h model_to_ground" |
| 424 | model_to_ground :: Ptr CModel -> IO () | 404 | model_to_ground :: Ptr Model -> IO () |
diff --git a/Spear/Assets/Model/Model.c b/Spear/Assets/Model/Model.c index eb955de..4942566 100644 --- a/Spear/Assets/Model/Model.c +++ b/Spear/Assets/Model/Model.c | |||
| @@ -27,62 +27,6 @@ void model_free (Model* model) | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | static void mul (float m[16], vec3* v) | ||
| 31 | { | ||
| 32 | float x = v->x; | ||
| 33 | float y = v->y; | ||
| 34 | float z = v->z; | ||
| 35 | v->x = x*m[0] + y*m[4] + z*m[8] + m[12]; | ||
| 36 | v->y = x*m[1] + y*m[5] + z*m[9] + m[13]; | ||
| 37 | v->z = x*m[2] + y*m[6] + z*m[10] + m[14]; | ||
| 38 | } | ||
| 39 | |||
| 40 | |||
| 41 | static void mul_normal (float m[9], vec3* n) | ||
| 42 | { | ||
| 43 | float x = n->x; | ||
| 44 | float y = n->y; | ||
| 45 | float z = n->z; | ||
| 46 | n->x = x*m[0] + y*m[3] + z*m[6]; | ||
| 47 | n->y = x*m[1] + y*m[4] + z*m[7]; | ||
| 48 | n->z = x*m[2] + y*m[5] + z*m[8]; | ||
| 49 | x = n->x; | ||
| 50 | y = n->y; | ||
| 51 | z = n->z; | ||
| 52 | float mag = sqrt(x*x + y*y + z*z); | ||
| 53 | mag = mag == 0.0 ? 1.0 : mag; | ||
| 54 | n->x /= mag; | ||
| 55 | n->y /= mag; | ||
| 56 | n->z /= mag; | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | void model_transform_vertices (Model* model, float mat[16]) | ||
| 61 | { | ||
| 62 | unsigned i = 0; | ||
| 63 | unsigned j = model->numVertices * model->numFrames; | ||
| 64 | vec3* v = model->vertices; | ||
| 65 | |||
| 66 | for (; i < j; ++i, ++v) | ||
| 67 | { | ||
| 68 | mul (mat, v); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | void model_transform_normals (Model* model, float normal[9]) | ||
| 74 | { | ||
| 75 | unsigned i = 0; | ||
| 76 | unsigned j = model->numVertices * model->numFrames; | ||
| 77 | vec3* n = model->normals; | ||
| 78 | |||
| 79 | for (; i < j; ++i, ++n) | ||
| 80 | { | ||
| 81 | mul_normal (normal, n); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | |||
| 86 | void model_to_ground (Model* model) | 30 | void model_to_ground (Model* model) |
| 87 | { | 31 | { |
| 88 | unsigned i, f; | 32 | unsigned i, f; |
diff --git a/Spear/Assets/Model/Model.h b/Spear/Assets/Model/Model.h index 275b040..0532322 100644 --- a/Spear/Assets/Model/Model.h +++ b/Spear/Assets/Model/Model.h | |||
| @@ -84,12 +84,6 @@ extern "C" { | |||
| 84 | /// The 'model' pointer itself is not freed. | 84 | /// The 'model' pointer itself is not freed. |
| 85 | void model_free (Model* model); | 85 | void model_free (Model* model); |
| 86 | 86 | ||
| 87 | /// Transform the Model's vertices by the given matrix. | ||
| 88 | void model_transform_verts (Model* model, float mat[16]); | ||
| 89 | |||
| 90 | /// Transform the Model's normals by the given matrix. | ||
| 91 | void model_transform_normals (Model* model, float normal[9]); | ||
| 92 | |||
| 93 | /// Translate the Model such that its lowest point has y = 0. | 87 | /// Translate the Model such that its lowest point has y = 0. |
| 94 | void model_to_ground (Model* model); | 88 | void model_to_ground (Model* model); |
| 95 | 89 | ||
diff --git a/Spear/Render/Model.hsc b/Spear/Render/Model.hsc index 02a37ae..b6c561b 100644 --- a/Spear/Render/Model.hsc +++ b/Spear/Render/Model.hsc | |||
| @@ -51,11 +51,11 @@ instance Storable RenderModel where | |||
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | foreign import ccall "RenderModel.h render_model_from_model_asset" | 53 | foreign import ccall "RenderModel.h render_model_from_model_asset" |
| 54 | render_model_from_model_asset :: Ptr Assets.CModel -> Ptr RenderModel -> IO Int | 54 | render_model_from_model_asset :: Ptr Assets.Model -> Ptr RenderModel -> IO Int |
| 55 | 55 | ||
| 56 | 56 | ||
| 57 | -- | Convert the given 'Model' to a 'ModelData' instance. | 57 | -- | Convert the given 'Model' to a 'ModelData' instance. |
| 58 | renderModelFromModel :: Assets.Model -> IO RenderModel | 58 | renderModelFromModel :: Assets.Model -> IO RenderModel |
| 59 | renderModelFromModel m = with (Assets.cmodel m) $ \mPtr -> alloca $ \mdPtr -> do | 59 | renderModelFromModel m = with m $ \mPtr -> alloca $ \mdPtr -> do |
| 60 | render_model_from_model_asset mPtr mdPtr | 60 | render_model_from_model_asset mPtr mdPtr |
| 61 | peek mdPtr | 61 | peek mdPtr |
diff --git a/Spear/Scene/Loader.hs b/Spear/Scene/Loader.hs index 06e0aa9..64e81f1 100644 --- a/Spear/Scene/Loader.hs +++ b/Spear/Scene/Loader.hs | |||
| @@ -19,6 +19,7 @@ where | |||
| 19 | 19 | ||
| 20 | import Spear.Assets.Model as Model | 20 | import Spear.Assets.Model as Model |
| 21 | import qualified Spear.GLSL as GLSL | 21 | import qualified Spear.GLSL as GLSL |
| 22 | import qualified Spear.Math.Matrix3 as M3 | ||
| 22 | import Spear.Math.Matrix4 as M4 | 23 | import Spear.Math.Matrix4 as M4 |
| 23 | import Spear.Math.MatrixUtils (fastNormalMatrix) | 24 | import Spear.Math.MatrixUtils (fastNormalMatrix) |
| 24 | import Spear.Math.Vector3 as V3 | 25 | import Spear.Math.Vector3 as V3 |
| @@ -188,19 +189,21 @@ newModel (SceneLeaf _ props) = do | |||
| 188 | 189 | ||
| 189 | loadModel' :: FilePath -> Maybe Rotation -> Maybe Vector3 -> Setup Model | 190 | loadModel' :: FilePath -> Maybe Rotation -> Maybe Vector3 -> Setup Model |
| 190 | loadModel' file rotation scale = do | 191 | loadModel' file rotation scale = do |
| 191 | model <- Model.loadModel file | 192 | let transform = |
| 192 | case rotation of | 193 | (case rotation of |
| 193 | Just rot -> setupIO $ rotateModel model rot | 194 | Nothing -> Prelude.id |
| 194 | Nothing -> return () | 195 | Just rot -> rotateModel rot) . |
| 195 | case scale of | 196 | |
| 196 | Just s -> setupIO $ Model.transformVerts (scalev s) model | 197 | (case scale of |
| 197 | Nothing -> return () | 198 | Nothing -> Prelude.id |
| 198 | setupIO $ toGround model | 199 | Just s -> flip Model.transformVerts $ |
| 199 | return model | 200 | \(Vec3 x' y' z') -> Vec3 (V3.x s * x') (V3.y s * y') (V3.z s * z')) |
| 200 | 201 | ||
| 201 | 202 | (fmap transform $ Model.loadModel file) >>= setupIO . toGround | |
| 202 | rotateModel :: Model -> Rotation -> IO () | 203 | |
| 203 | rotateModel model (Rotation x y z order) = | 204 | |
| 205 | rotateModel :: Rotation -> Model -> Model | ||
| 206 | rotateModel (Rotation x y z order) model = | ||
| 204 | let mat = case order of | 207 | let mat = case order of |
| 205 | XYZ -> rotZ z * rotY y * rotX x | 208 | XYZ -> rotZ z * rotY y * rotX x |
| 206 | XZY -> rotY y * rotZ z * rotX x | 209 | XZY -> rotY y * rotZ z * rotX x |
| @@ -209,8 +212,14 @@ rotateModel model (Rotation x y z order) = | |||
| 209 | ZXY -> rotY y * rotX x * rotZ z | 212 | ZXY -> rotY y * rotX x * rotZ z |
| 210 | ZYX -> rotX x * rotY y * rotZ z | 213 | ZYX -> rotX x * rotY y * rotZ z |
| 211 | normalMat = fastNormalMatrix mat | 214 | normalMat = fastNormalMatrix mat |
| 215 | |||
| 216 | vTransform (Vec3 x' y' z') = | ||
| 217 | let v = mat `mulp` (vec3 x' y' z') in Vec3 (V3.x v) (V3.y v) (V3.z v) | ||
| 218 | |||
| 219 | nTransform (Vec3 x' y' z') = | ||
| 220 | let v = normalMat `M3.mul` (vec3 x' y' z') in Vec3 (V3.x v) (V3.y v) (V3.z v) | ||
| 212 | in | 221 | in |
| 213 | Model.transformVerts mat model >> Model.transformNormals normalMat model | 222 | flip Model.transformVerts vTransform . flip Model.transformNormals nTransform $ model |
| 214 | 223 | ||
| 215 | 224 | ||
| 216 | loadTexture :: FilePath -> Loader GLSL.Texture | 225 | loadTexture :: FilePath -> Loader GLSL.Texture |
