aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Spear/Assets/Model.hsc146
-rw-r--r--Spear/Assets/Model/Model.c28
-rw-r--r--Spear/Assets/Model/Model.h20
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
41import qualified Spear.Math.Matrix3 as M3 38import qualified Spear.Math.Matrix3 as M3
42import Spear.Math.MatrixUtils 39import Spear.Math.MatrixUtils
43 40
41
44import qualified Data.ByteString.Char8 as B 42import qualified Data.ByteString.Char8 as B
45import Data.Char (toLower) 43import Data.Char (toLower)
46import Data.List (splitAt, elemIndex) 44import Data.List (splitAt, elemIndex)
@@ -51,7 +49,7 @@ import Foreign.C.Types
51import Foreign.C.String 49import Foreign.C.String
52import Foreign.Marshal.Utils as Foreign (with) 50import Foreign.Marshal.Utils as Foreign (with)
53import Foreign.Marshal.Alloc (alloca, allocaBytes) 51import Foreign.Marshal.Alloc (alloca, allocaBytes)
54import Foreign.Marshal.Array (copyArray, peekArray) 52import Foreign.Marshal.Array (allocaArray, copyArray, peekArray)
55import Unsafe.Coerce (unsafeCoerce) 53import 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
71sizeFloat = #{size float}
72
73
74-- | A 3D vector.
73data Vec3 = Vec3 !CFloat !CFloat !CFloat 75data Vec3 = Vec3 !CFloat !CFloat !CFloat
74 76
77
78instance 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.
75data TexCoord = TexCoord !CFloat !CFloat 95data TexCoord = TexCoord !CFloat !CFloat
76 96
77data Triangle = Triangle !CUShort !CUShort !CUShort !CUShort !CUShort !CUShort 97
98instance 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
112data CTriangle = CTriangle !CUShort !CUShort !CUShort !CUShort !CUShort !CUShort
113
78 114
79data Skin = Skin !(Ptr Char) 115data Skin = Skin !(Ptr Char)
80 116
117
81data CAnimation = CAnimation !B.ByteString !CUInt !CUInt 118data 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'.
156data Animation = Animation 196data 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
203data 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
216instance 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'.
164data Model = Model 245data Model = Model
165 { modelData :: CModel 246 { modelData :: CModel
@@ -248,31 +329,6 @@ animated :: Model -> Bool
248animated = (>1) . numFrames 329animated = (>1) . numFrames
249 330
250 331
251-- | Return the model's vertices.
252vertices :: Model -> Ptr Vec3
253vertices = cVerts . modelData
254
255
256-- | Return the model's normals.
257normals :: Model -> Ptr Vec3
258normals = cNormals . modelData
259
260
261-- | Return the model's texCoords.
262texCoords :: Model -> Ptr TexCoord
263texCoords = cTexCoords . modelData
264
265
266-- | Return the model's triangles.
267triangles :: Model -> Ptr Triangle
268triangles = cTris . modelData
269
270
271-- | Return the model's skins.
272skins :: Model -> Ptr Skin
273skins = cSkins . modelData
274
275
276-- | Return the model's number of frames. 332-- | Return the model's number of frames.
277numFrames :: Model -> Int 333numFrames :: Model -> Int
278numFrames = fromIntegral . cnFrames . modelData 334numFrames = fromIntegral . cnFrames . modelData
@@ -318,6 +374,21 @@ numAnimations :: Model -> Int
318numAnimations = V.length . mAnimations 374numAnimations = V.length . mAnimations
319 375
320 376
377-- | Return a copy of the model's triangles.
378triangles :: Model -> IO [Triangle]
379triangles 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
388foreign 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.
322transformVerts :: M4.Matrix4 -> Model -> IO () 393transformVerts :: M4.Matrix4 -> Model -> IO ()
323transformVerts mat (Model model _ _) = 394transformVerts mat (Model model _ _) =
@@ -351,6 +422,3 @@ toGround (Model model _ _) = with model model_to_ground
351 422
352foreign import ccall "Model.h model_to_ground" 423foreign import ccall "Model.h model_to_ground"
353 model_to_ground :: Ptr CModel -> IO () 424 model_to_ground :: Ptr CModel -> IO ()
354
355
356sizeFloat = #{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
111void 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
61Model; 61Model;
62 62
63 63
64typedef 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}
76model_triangle;
77
78
64#ifdef __cplusplus 79#ifdef __cplusplus
65extern "C" { 80extern "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.
79void model_to_ground (Model* model); 94void model_to_ground (Model* model);
80 95
96/// Copy the triangles of the given frame from the Model into the given array.
97void model_copy_triangles (Model* model, unsigned frame, model_triangle* tris);
98
81#ifdef __cplusplus 99#ifdef __cplusplus
82} 100}
83#endif 101#endif