diff options
| author | Marc Sunet <jeannekamikaze@gmail.com> | 2012-08-08 19:14:22 +0200 |
|---|---|---|
| committer | Marc Sunet <jeannekamikaze@gmail.com> | 2012-08-08 19:14:22 +0200 |
| commit | 5bd3c77b0e75051a5e9ae0490cef5b8abc167838 (patch) | |
| tree | f2754cf15a318a6d75b0d98637351434077ee0c8 | |
| parent | aa904e7367159bc1ec138826af0683a11e7df8ff (diff) | |
Hid CModel. Removed low level API. Added triangles function
| -rw-r--r-- | Spear/Assets/Model.hsc | 146 | ||||
| -rw-r--r-- | Spear/Assets/Model/Model.c | 28 | ||||
| -rw-r--r-- | Spear/Assets/Model/Model.h | 20 |
3 files changed, 154 insertions, 40 deletions
diff --git a/Spear/Assets/Model.hsc b/Spear/Assets/Model.hsc index 9e718c7..cb0ef3f 100644 --- a/Spear/Assets/Model.hsc +++ b/Spear/Assets/Model.hsc | |||
| @@ -4,21 +4,17 @@ module Spear.Assets.Model | |||
| 4 | ( | 4 | ( |
| 5 | -- * Data types | 5 | -- * Data types |
| 6 | ModelErrorCode | 6 | ModelErrorCode |
| 7 | , Vec3 | 7 | , Vec3(..) |
| 8 | , TexCoord | 8 | , TexCoord(..) |
| 9 | , CModel(..) | 9 | , CModel |
| 10 | , Animation(..) | 10 | , Animation(..) |
| 11 | , Triangle(..) | ||
| 11 | , Model | 12 | , Model |
| 12 | -- * Loading and unloading | 13 | -- * Loading and unloading |
| 13 | , loadModel | 14 | , loadModel |
| 14 | , releaseModel | 15 | , releaseModel |
| 15 | -- * Accessors | 16 | -- * Accessors |
| 16 | , animated | 17 | , animated |
| 17 | , vertices | ||
| 18 | , normals | ||
| 19 | , texCoords | ||
| 20 | , triangles | ||
| 21 | , skins | ||
| 22 | , numFrames | 18 | , numFrames |
| 23 | , numVertices | 19 | , numVertices |
| 24 | , numTriangles | 20 | , numTriangles |
| @@ -28,6 +24,7 @@ module Spear.Assets.Model | |||
| 28 | , animation | 24 | , animation |
| 29 | , animationByName | 25 | , animationByName |
| 30 | , numAnimations | 26 | , numAnimations |
| 27 | , triangles | ||
| 31 | -- * Manipulation | 28 | -- * Manipulation |
| 32 | , transformVerts | 29 | , transformVerts |
| 33 | , transformNormals | 30 | , transformNormals |
| @@ -41,6 +38,7 @@ import qualified Spear.Math.Matrix4 as M4 | |||
| 41 | import qualified Spear.Math.Matrix3 as M3 | 38 | import qualified Spear.Math.Matrix3 as M3 |
| 42 | import Spear.Math.MatrixUtils | 39 | import Spear.Math.MatrixUtils |
| 43 | 40 | ||
| 41 | |||
| 44 | import qualified Data.ByteString.Char8 as B | 42 | import qualified Data.ByteString.Char8 as B |
| 45 | import Data.Char (toLower) | 43 | import Data.Char (toLower) |
| 46 | import Data.List (splitAt, elemIndex) | 44 | import Data.List (splitAt, elemIndex) |
| @@ -51,7 +49,7 @@ import Foreign.C.Types | |||
| 51 | import Foreign.C.String | 49 | import Foreign.C.String |
| 52 | import Foreign.Marshal.Utils as Foreign (with) | 50 | import Foreign.Marshal.Utils as Foreign (with) |
| 53 | import Foreign.Marshal.Alloc (alloca, allocaBytes) | 51 | import Foreign.Marshal.Alloc (alloca, allocaBytes) |
| 54 | import Foreign.Marshal.Array (copyArray, peekArray) | 52 | import Foreign.Marshal.Array (allocaArray, copyArray, peekArray) |
| 55 | import Unsafe.Coerce (unsafeCoerce) | 53 | import Unsafe.Coerce (unsafeCoerce) |
| 56 | 54 | ||
| 57 | 55 | ||
| @@ -70,14 +68,53 @@ data ModelErrorCode | |||
| 70 | deriving (Eq, Enum, Show) | 68 | deriving (Eq, Enum, Show) |
| 71 | 69 | ||
| 72 | 70 | ||
| 71 | sizeFloat = #{size float} | ||
| 72 | |||
| 73 | |||
| 74 | -- | A 3D vector. | ||
| 73 | data Vec3 = Vec3 !CFloat !CFloat !CFloat | 75 | data Vec3 = Vec3 !CFloat !CFloat !CFloat |
| 74 | 76 | ||
| 77 | |||
| 78 | instance Storable Vec3 where | ||
| 79 | sizeOf _ = 3*sizeFloat | ||
| 80 | alignment _ = alignment (undefined :: CFloat) | ||
| 81 | |||
| 82 | peek ptr = do | ||
| 83 | f0 <- peekByteOff ptr 0 | ||
| 84 | f1 <- peekByteOff ptr sizeFloat | ||
| 85 | f2 <- peekByteOff ptr (2*sizeFloat) | ||
| 86 | return $ Vec3 f0 f1 f2 | ||
| 87 | |||
| 88 | poke ptr (Vec3 f0 f1 f2) = do | ||
| 89 | pokeByteOff ptr 0 f0 | ||
| 90 | pokeByteOff ptr sizeFloat f1 | ||
| 91 | pokeByteOff ptr (2*sizeFloat) f2 | ||
| 92 | |||
| 93 | |||
| 94 | -- | A 2D texture coordinate. | ||
| 75 | data TexCoord = TexCoord !CFloat !CFloat | 95 | data TexCoord = TexCoord !CFloat !CFloat |
| 76 | 96 | ||
| 77 | data Triangle = Triangle !CUShort !CUShort !CUShort !CUShort !CUShort !CUShort | 97 | |
| 98 | instance Storable TexCoord where | ||
| 99 | sizeOf _ = 2*sizeFloat | ||
| 100 | alignment _ = alignment (undefined :: CFloat) | ||
| 101 | |||
| 102 | peek ptr = do | ||
| 103 | f0 <- peekByteOff ptr 0 | ||
| 104 | f1 <- peekByteOff ptr sizeFloat | ||
| 105 | return $ TexCoord f0 f1 | ||
| 106 | |||
| 107 | poke ptr (TexCoord f0 f1) = do | ||
| 108 | pokeByteOff ptr 0 f0 | ||
| 109 | pokeByteOff ptr sizeFloat f1 | ||
| 110 | |||
| 111 | |||
| 112 | data CTriangle = CTriangle !CUShort !CUShort !CUShort !CUShort !CUShort !CUShort | ||
| 113 | |||
| 78 | 114 | ||
| 79 | data Skin = Skin !(Ptr Char) | 115 | data Skin = Skin !(Ptr Char) |
| 80 | 116 | ||
| 117 | |||
| 81 | data CAnimation = CAnimation !B.ByteString !CUInt !CUInt | 118 | data CAnimation = CAnimation !B.ByteString !CUInt !CUInt |
| 82 | 119 | ||
| 83 | 120 | ||
| @@ -86,7 +123,7 @@ data CModel = CModel | |||
| 86 | { cVerts :: Ptr Vec3 -- ^ Pointer to an array of 'cnFrames' * 'cnVerts' vertices. | 123 | { cVerts :: Ptr Vec3 -- ^ Pointer to an array of 'cnFrames' * 'cnVerts' vertices. |
| 87 | , cNormals :: Ptr Vec3 -- ^ Pointer to an array of 'cnFrames' * cnVerts normals. | 124 | , cNormals :: Ptr Vec3 -- ^ Pointer to an array of 'cnFrames' * cnVerts normals. |
| 88 | , cTexCoords :: Ptr TexCoord -- ^ Pointer to an array of 'cnTris' texture coordinates. | 125 | , cTexCoords :: Ptr TexCoord -- ^ Pointer to an array of 'cnTris' texture coordinates. |
| 89 | , cTris :: Ptr Triangle -- ^ Pointer to an array of 'cnTris' triangles. | 126 | , cTris :: Ptr CTriangle -- ^ Pointer to an array of 'cnTris' triangles. |
| 90 | , cSkins :: Ptr Skin -- ^ Pointer to an array of 'cnSkins' skins. | 127 | , cSkins :: Ptr Skin -- ^ Pointer to an array of 'cnSkins' skins. |
| 91 | , cAnimations :: Ptr CAnimation -- ^ Pointer to an array of 'cnAnimations' animations. | 128 | , cAnimations :: Ptr CAnimation -- ^ Pointer to an array of 'cnAnimations' animations. |
| 92 | , cnFrames :: CUInt -- ^ Number of frames. | 129 | , cnFrames :: CUInt -- ^ Number of frames. |
| @@ -153,6 +190,9 @@ instance Storable CAnimation where | |||
| 153 | #{poke animation, end} ptr end | 190 | #{poke animation, end} ptr end |
| 154 | 191 | ||
| 155 | 192 | ||
| 193 | -- | A model's animation. | ||
| 194 | -- | ||
| 195 | -- See also: 'animation', 'animationByName', 'numAnimations'. | ||
| 156 | data Animation = Animation | 196 | data Animation = Animation |
| 157 | { name :: String | 197 | { name :: String |
| 158 | , start :: Int | 198 | , start :: Int |
| @@ -160,6 +200,47 @@ data Animation = Animation | |||
| 160 | } | 200 | } |
| 161 | 201 | ||
| 162 | 202 | ||
| 203 | data Triangle = Triangle | ||
| 204 | { v0 :: Vec3 | ||
| 205 | , v1 :: Vec3 | ||
| 206 | , v2 :: Vec3 | ||
| 207 | , n0 :: Vec3 | ||
| 208 | , n1 :: Vec3 | ||
| 209 | , n2 :: Vec3 | ||
| 210 | , t0 :: TexCoord | ||
| 211 | , t1 :: TexCoord | ||
| 212 | , t2 :: TexCoord | ||
| 213 | } | ||
| 214 | |||
| 215 | |||
| 216 | instance Storable Triangle where | ||
| 217 | sizeOf _ = #{size model_triangle} | ||
| 218 | alignment _ = alignment (undefined :: Float) | ||
| 219 | |||
| 220 | peek ptr = do | ||
| 221 | v0 <- #{peek model_triangle, v0} ptr | ||
| 222 | v1 <- #{peek model_triangle, v1} ptr | ||
| 223 | v2 <- #{peek model_triangle, v2} ptr | ||
| 224 | n0 <- #{peek model_triangle, n0} ptr | ||
| 225 | n1 <- #{peek model_triangle, n1} ptr | ||
| 226 | n2 <- #{peek model_triangle, n2} ptr | ||
| 227 | t0 <- #{peek model_triangle, t0} ptr | ||
| 228 | t1 <- #{peek model_triangle, t1} ptr | ||
| 229 | t2 <- #{peek model_triangle, t2} ptr | ||
| 230 | return $ Triangle v0 v1 v2 n0 n1 n2 t0 t1 t2 | ||
| 231 | |||
| 232 | poke ptr (Triangle v0 v1 v2 n0 n1 n2 t0 t1 t2) = do | ||
| 233 | #{poke model_triangle, v0} ptr v0 | ||
| 234 | #{poke model_triangle, v1} ptr v1 | ||
| 235 | #{poke model_triangle, v2} ptr v2 | ||
| 236 | #{poke model_triangle, n0} ptr n0 | ||
| 237 | #{poke model_triangle, n1} ptr n1 | ||
| 238 | #{poke model_triangle, n2} ptr n2 | ||
| 239 | #{poke model_triangle, t0} ptr t0 | ||
| 240 | #{poke model_triangle, t1} ptr t1 | ||
| 241 | #{poke model_triangle, t2} ptr t2 | ||
| 242 | |||
| 243 | |||
| 163 | -- | A model 'Resource'. | 244 | -- | A model 'Resource'. |
| 164 | data Model = Model | 245 | data Model = Model |
| 165 | { modelData :: CModel | 246 | { modelData :: CModel |
| @@ -248,31 +329,6 @@ animated :: Model -> Bool | |||
| 248 | animated = (>1) . numFrames | 329 | animated = (>1) . numFrames |
| 249 | 330 | ||
| 250 | 331 | ||
| 251 | -- | Return the model's vertices. | ||
| 252 | vertices :: Model -> Ptr Vec3 | ||
| 253 | vertices = cVerts . modelData | ||
| 254 | |||
| 255 | |||
| 256 | -- | Return the model's normals. | ||
| 257 | normals :: Model -> Ptr Vec3 | ||
| 258 | normals = cNormals . modelData | ||
| 259 | |||
| 260 | |||
| 261 | -- | Return the model's texCoords. | ||
| 262 | texCoords :: Model -> Ptr TexCoord | ||
| 263 | texCoords = cTexCoords . modelData | ||
| 264 | |||
| 265 | |||
| 266 | -- | Return the model's triangles. | ||
| 267 | triangles :: Model -> Ptr Triangle | ||
| 268 | triangles = cTris . modelData | ||
| 269 | |||
| 270 | |||
| 271 | -- | Return the model's skins. | ||
| 272 | skins :: Model -> Ptr Skin | ||
| 273 | skins = cSkins . modelData | ||
| 274 | |||
| 275 | |||
| 276 | -- | Return the model's number of frames. | 332 | -- | Return the model's number of frames. |
| 277 | numFrames :: Model -> Int | 333 | numFrames :: Model -> Int |
| 278 | numFrames = fromIntegral . cnFrames . modelData | 334 | numFrames = fromIntegral . cnFrames . modelData |
| @@ -318,6 +374,21 @@ numAnimations :: Model -> Int | |||
| 318 | numAnimations = V.length . mAnimations | 374 | numAnimations = V.length . mAnimations |
| 319 | 375 | ||
| 320 | 376 | ||
| 377 | -- | Return a copy of the model's triangles. | ||
| 378 | triangles :: Model -> IO [Triangle] | ||
| 379 | triangles m@(Model model _ _) = | ||
| 380 | let n = numVertices m * numFrames m | ||
| 381 | in with model $ \modelPtr -> | ||
| 382 | allocaArray n $ \arrayPtr -> do | ||
| 383 | model_copy_triangles modelPtr arrayPtr | ||
| 384 | tris <- peekArray n arrayPtr | ||
| 385 | return tris | ||
| 386 | |||
| 387 | |||
| 388 | foreign import ccall "Model.h model_copy_triangles" | ||
| 389 | model_copy_triangles :: Ptr CModel -> Ptr Triangle -> IO () | ||
| 390 | |||
| 391 | |||
| 321 | -- | Transform the model's vertices with the given matrix. | 392 | -- | Transform the model's vertices with the given matrix. |
| 322 | transformVerts :: M4.Matrix4 -> Model -> IO () | 393 | transformVerts :: M4.Matrix4 -> Model -> IO () |
| 323 | transformVerts mat (Model model _ _) = | 394 | transformVerts mat (Model model _ _) = |
| @@ -351,6 +422,3 @@ toGround (Model model _ _) = with model model_to_ground | |||
| 351 | 422 | ||
| 352 | foreign import ccall "Model.h model_to_ground" | 423 | foreign import ccall "Model.h model_to_ground" |
| 353 | model_to_ground :: Ptr CModel -> IO () | 424 | model_to_ground :: Ptr CModel -> IO () |
| 354 | |||
| 355 | |||
| 356 | sizeFloat = #{size float} | ||
diff --git a/Spear/Assets/Model/Model.c b/Spear/Assets/Model/Model.c index f6b2f1f..a682991 100644 --- a/Spear/Assets/Model/Model.c +++ b/Spear/Assets/Model/Model.c | |||
| @@ -106,3 +106,31 @@ void model_to_ground (Model* model) | |||
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | |||
| 110 | |||
| 111 | void model_copy_triangles (Model* model, unsigned frame, model_triangle* tris) | ||
| 112 | { | ||
| 113 | int i; | ||
| 114 | int j = model->numVertices; | ||
| 115 | |||
| 116 | vec3* v = model->vertices + j * frame; | ||
| 117 | vec3* n = model->normals + j * frame; | ||
| 118 | texCoord* t = model->texCoords; | ||
| 119 | triangle* tri = model->triangles; | ||
| 120 | |||
| 121 | |||
| 122 | for (i = 0; i < j; ++i, ++tri, ++tris) | ||
| 123 | { | ||
| 124 | tris->v0 = v[tri->vertexIndices[0]]; | ||
| 125 | tris->v1 = v[tri->vertexIndices[1]]; | ||
| 126 | tris->v2 = v[tri->vertexIndices[2]]; | ||
| 127 | |||
| 128 | tris->n0 = n[tri->vertexIndices[0]]; | ||
| 129 | tris->n1 = n[tri->vertexIndices[1]]; | ||
| 130 | tris->n2 = n[tri->vertexIndices[2]]; | ||
| 131 | |||
| 132 | tris->t0 = t[tri->textureIndices[0]]; | ||
| 133 | tris->t1 = t[tri->textureIndices[1]]; | ||
| 134 | tris->t2 = t[tri->textureIndices[2]]; | ||
| 135 | } | ||
| 136 | } | ||
diff --git a/Spear/Assets/Model/Model.h b/Spear/Assets/Model/Model.h index 84be6aa..275b040 100644 --- a/Spear/Assets/Model/Model.h +++ b/Spear/Assets/Model/Model.h | |||
| @@ -49,7 +49,7 @@ typedef struct | |||
| 49 | texCoord* texCoords; // One array for all frames. | 49 | texCoord* texCoords; // One array for all frames. |
| 50 | triangle* triangles; // One array for all frames. | 50 | triangle* triangles; // One array for all frames. |
| 51 | skin* skins; // Holds the model's texture files. | 51 | skin* skins; // Holds the model's texture files. |
| 52 | animation* animations; // Holds the model's animations. | 52 | animation* animations; // Holds the model's animations. |
| 53 | 53 | ||
| 54 | unsigned int numFrames; | 54 | unsigned int numFrames; |
| 55 | unsigned int numVertices; // Number of vertices per frame. | 55 | unsigned int numVertices; // Number of vertices per frame. |
| @@ -61,6 +61,21 @@ typedef struct | |||
| 61 | Model; | 61 | Model; |
| 62 | 62 | ||
| 63 | 63 | ||
| 64 | typedef struct | ||
| 65 | { | ||
| 66 | vec3 v0; | ||
| 67 | vec3 v1; | ||
| 68 | vec3 v2; | ||
| 69 | vec3 n0; | ||
| 70 | vec3 n1; | ||
| 71 | vec3 n2; | ||
| 72 | texCoord t0; | ||
| 73 | texCoord t1; | ||
| 74 | texCoord t2; | ||
| 75 | } | ||
| 76 | model_triangle; | ||
| 77 | |||
| 78 | |||
| 64 | #ifdef __cplusplus | 79 | #ifdef __cplusplus |
| 65 | extern "C" { | 80 | extern "C" { |
| 66 | #endif | 81 | #endif |
| @@ -78,6 +93,9 @@ void model_transform_normals (Model* model, float normal[9]); | |||
| 78 | /// Translate the Model such that its lowest point has y = 0. | 93 | /// Translate the Model such that its lowest point has y = 0. |
| 79 | void model_to_ground (Model* model); | 94 | void model_to_ground (Model* model); |
| 80 | 95 | ||
| 96 | /// Copy the triangles of the given frame from the Model into the given array. | ||
| 97 | void model_copy_triangles (Model* model, unsigned frame, model_triangle* tris); | ||
| 98 | |||
| 81 | #ifdef __cplusplus | 99 | #ifdef __cplusplus |
| 82 | } | 100 | } |
| 83 | #endif | 101 | #endif |
