Merge branch 'iqm' into tessallation
Conflicts: Pioneers.cabal src/Map/StaticMaps.hs
This commit is contained in:
		@@ -16,14 +16,15 @@ executable Pioneers
 | 
				
			|||||||
                   Map.Graphics,
 | 
					                   Map.Graphics,
 | 
				
			||||||
                   Map.Creation,
 | 
					                   Map.Creation,
 | 
				
			||||||
                   Map.StaticMaps,
 | 
					                   Map.StaticMaps,
 | 
				
			||||||
                   IQM.Types,
 | 
					                   Importer.IQM.Types,
 | 
				
			||||||
                   IQM.TestMain,
 | 
					                   Importer.IQM.TestMain,
 | 
				
			||||||
                   IQM.Parser,
 | 
					                   Importer.IQM.Parser,
 | 
				
			||||||
                   Render.Misc,
 | 
					                   Render.Misc,
 | 
				
			||||||
                   Render.Render,
 | 
					                   Render.Render,
 | 
				
			||||||
                   Render.RenderObject,
 | 
					                   Render.RenderObject,
 | 
				
			||||||
 | 
					                   Render.Types,
 | 
				
			||||||
                   UI.Callbacks,
 | 
					                   UI.Callbacks,
 | 
				
			||||||
                   Types,
 | 
					                   UI.Types,
 | 
				
			||||||
                   UI.SurfaceOverlay
 | 
					                   UI.SurfaceOverlay
 | 
				
			||||||
                   Types
 | 
					                   Types
 | 
				
			||||||
  main-is:         Main.hs
 | 
					  main-is:         Main.hs
 | 
				
			||||||
@@ -45,7 +46,7 @@ executable Pioneers
 | 
				
			|||||||
                   SDL2 >= 0.1.0,
 | 
					                   SDL2 >= 0.1.0,
 | 
				
			||||||
                   time >=1.4.0,
 | 
					                   time >=1.4.0,
 | 
				
			||||||
                   GLUtil >= 0.7,
 | 
					                   GLUtil >= 0.7,
 | 
				
			||||||
                   attoparsec >= 0.11.2
 | 
					                   attoparsec >= 0.11.2,
 | 
				
			||||||
  other-modules:   Render.Types
 | 
					                   attoparsec-binary >= 0.1
 | 
				
			||||||
  Default-Language: Haskell2010
 | 
					  Default-Language: Haskell2010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,101 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#extension GL_ARB_tessellation_shader : require
 | 
					#extension GL_ARB_tessellation_shader : require
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#include "shaders/3rdParty/noise.glsl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3 mod289(vec3 x) {
 | 
				
			||||||
 | 
					  return x - floor(x * (1.0 / 289.0)) * 289.0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec4 mod289(vec4 x) {
 | 
				
			||||||
 | 
					  return x - floor(x * (1.0 / 289.0)) * 289.0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec4 permute(vec4 x) {
 | 
				
			||||||
 | 
					     return mod289(((x*34.0)+1.0)*x);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec4 taylorInvSqrt(vec4 r)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return 1.79284291400159 - 0.85373472095314 * r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float snoise(vec3 v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					  const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
 | 
				
			||||||
 | 
					  const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// First corner
 | 
				
			||||||
 | 
					  vec3 i  = floor(v + dot(v, C.yyy) );
 | 
				
			||||||
 | 
					  vec3 x0 =   v - i + dot(i, C.xxx) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Other corners
 | 
				
			||||||
 | 
					  vec3 g = step(x0.yzx, x0.xyz);
 | 
				
			||||||
 | 
					  vec3 l = 1.0 - g;
 | 
				
			||||||
 | 
					  vec3 i1 = min( g.xyz, l.zxy );
 | 
				
			||||||
 | 
					  vec3 i2 = max( g.xyz, l.zxy );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //   x0 = x0 - 0.0 + 0.0 * C.xxx;
 | 
				
			||||||
 | 
					  //   x1 = x0 - i1  + 1.0 * C.xxx;
 | 
				
			||||||
 | 
					  //   x2 = x0 - i2  + 2.0 * C.xxx;
 | 
				
			||||||
 | 
					  //   x3 = x0 - 1.0 + 3.0 * C.xxx;
 | 
				
			||||||
 | 
					  vec3 x1 = x0 - i1 + C.xxx;
 | 
				
			||||||
 | 
					  vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
 | 
				
			||||||
 | 
					  vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Permutations
 | 
				
			||||||
 | 
					  i = mod289(i);
 | 
				
			||||||
 | 
					  vec4 p = permute( permute( permute(
 | 
				
			||||||
 | 
					             i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
 | 
				
			||||||
 | 
					           + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
 | 
				
			||||||
 | 
					           + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Gradients: 7x7 points over a square, mapped onto an octahedron.
 | 
				
			||||||
 | 
					// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
 | 
				
			||||||
 | 
					  float n_ = 0.142857142857; // 1.0/7.0
 | 
				
			||||||
 | 
					  vec3  ns = n_ * D.wyz - D.xzx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p,7*7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vec4 x_ = floor(j * ns.z);
 | 
				
			||||||
 | 
					  vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vec4 x = x_ *ns.x + ns.yyyy;
 | 
				
			||||||
 | 
					  vec4 y = y_ *ns.x + ns.yyyy;
 | 
				
			||||||
 | 
					  vec4 h = 1.0 - abs(x) - abs(y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vec4 b0 = vec4( x.xy, y.xy );
 | 
				
			||||||
 | 
					  vec4 b1 = vec4( x.zw, y.zw );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
 | 
				
			||||||
 | 
					  //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
 | 
				
			||||||
 | 
					  vec4 s0 = floor(b0)*2.0 + 1.0;
 | 
				
			||||||
 | 
					  vec4 s1 = floor(b1)*2.0 + 1.0;
 | 
				
			||||||
 | 
					  vec4 sh = -step(h, vec4(0.0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
 | 
				
			||||||
 | 
					  vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vec3 p0 = vec3(a0.xy,h.x);
 | 
				
			||||||
 | 
					  vec3 p1 = vec3(a0.zw,h.y);
 | 
				
			||||||
 | 
					  vec3 p2 = vec3(a1.xy,h.z);
 | 
				
			||||||
 | 
					  vec3 p3 = vec3(a1.zw,h.w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Normalise gradients
 | 
				
			||||||
 | 
					  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
 | 
				
			||||||
 | 
					  p0 *= norm.x;
 | 
				
			||||||
 | 
					  p1 *= norm.y;
 | 
				
			||||||
 | 
					  p2 *= norm.z;
 | 
				
			||||||
 | 
					  p3 *= norm.w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Mix final noise value
 | 
				
			||||||
 | 
					  vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
 | 
				
			||||||
 | 
					  m = m * m;
 | 
				
			||||||
 | 
					  return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
 | 
				
			||||||
 | 
					                                dot(p2,x2), dot(p3,x3) ) );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
layout(triangles, equal_spacing, cw) in;
 | 
					layout(triangles, equal_spacing, cw) in;
 | 
				
			||||||
in vec3 tcPosition[];
 | 
					in vec3 tcPosition[];
 | 
				
			||||||
in vec4 tcColor[];
 | 
					in vec4 tcColor[];
 | 
				
			||||||
@@ -38,6 +133,7 @@ void main()
 | 
				
			|||||||
    float i2 = (1-gl_TessCoord.z)*gl_TessCoord.z * length(cross(tcNormal[2],tessNormal));
 | 
					    float i2 = (1-gl_TessCoord.z)*gl_TessCoord.z * length(cross(tcNormal[2],tessNormal));
 | 
				
			||||||
    float standout = i0+i1+i2;
 | 
					    float standout = i0+i1+i2;
 | 
				
			||||||
    tePosition = tePosition+tessNormal*standout;
 | 
					    tePosition = tePosition+tessNormal*standout;
 | 
				
			||||||
 | 
					    tePosition = tePosition+0.05*snoise(tePosition);
 | 
				
			||||||
    gl_Position = ProjectionMatrix * ViewMatrix * vec4(tePosition, 1);
 | 
					    gl_Position = ProjectionMatrix * ViewMatrix * vec4(tePosition, 1);
 | 
				
			||||||
    fogDist = gl_Position.z;
 | 
					    fogDist = gl_Position.z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,11 @@ module Importer.IQM.Parser (parseIQM) where
 | 
				
			|||||||
import Importer.IQM.Types
 | 
					import Importer.IQM.Types
 | 
				
			||||||
import Data.Attoparsec.ByteString.Char8
 | 
					import Data.Attoparsec.ByteString.Char8
 | 
				
			||||||
import Data.Attoparsec.ByteString
 | 
					import Data.Attoparsec.ByteString
 | 
				
			||||||
 | 
					import Data.Attoparsec.Binary
 | 
				
			||||||
 | 
					import Data.Attoparsec (parse, takeByteString)
 | 
				
			||||||
import Data.ByteString.Char8 (pack)
 | 
					import Data.ByteString.Char8 (pack)
 | 
				
			||||||
import Data.ByteString (split, null)
 | 
					import Data.ByteString (split, null, ByteString)
 | 
				
			||||||
 | 
					import qualified Data.ByteString as B
 | 
				
			||||||
import Data.Word
 | 
					import Data.Word
 | 
				
			||||||
import Data.Int
 | 
					import Data.Int
 | 
				
			||||||
import Unsafe.Coerce
 | 
					import Unsafe.Coerce
 | 
				
			||||||
@@ -20,72 +23,80 @@ import Control.Monad
 | 
				
			|||||||
import Prelude as P hiding (take, null)
 | 
					import Prelude as P hiding (take, null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | helper-function for creating an integral out of [8-Bit Ints]
 | 
					-- | helper-function for creating an integral out of [8-Bit Ints]
 | 
				
			||||||
w8ToInt :: Integral a => a -> a -> a
 | 
					_w8ToInt :: Integral a => a -> a -> a
 | 
				
			||||||
w8ToInt i add = 256*i + add
 | 
					_w8ToInt i add = 256*i + add
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | shorthand-function for parsing Word8 into Integrals
 | 
					-- | shorthand-function for parsing Word8 into Integrals
 | 
				
			||||||
parseNum :: (Integral a, Integral b) => [a] -> b
 | 
					_parseNum :: (Integral a, Integral b) => [a] -> b
 | 
				
			||||||
parseNum = (foldl1 w8ToInt) . map fromIntegral
 | 
					_parseNum = foldl1 _w8ToInt . map fromIntegral
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | read a 16-Bit Int from Parsing-Input and log 2 bytes in our Parsing-Monad
 | 
					-- | read a 16-Bit Int from Parsing-Input and log 2 bytes in our Parsing-Monad
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
--   begins with _ to defeat ghc-warnings. Rename if used!
 | 
					--   begins with _ to defeat ghc-warnings. Rename if used!
 | 
				
			||||||
_int16 :: CParser Int16
 | 
					_int16 :: CParser Word16
 | 
				
			||||||
_int16 = do
 | 
					_int16 = do
 | 
				
			||||||
        ret <- lift $ do
 | 
					        ret <- lift $ do
 | 
				
			||||||
                         a <- anyWord8 :: Parser Word8
 | 
					                         a <- anyWord8 :: Parser Word8
 | 
				
			||||||
                         b <- anyWord8 :: Parser Word8
 | 
					                         b <- anyWord8 :: Parser Word8
 | 
				
			||||||
                         return $ parseNum [b,a]
 | 
					                         return $ _parseNum [b,a]
 | 
				
			||||||
        modify (+2)
 | 
					        modify (+2)
 | 
				
			||||||
        return ret
 | 
					        return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | read a 32-Bit Int from Parsing-Input and log 4 bytes in our Parsing-Monad
 | 
					-- | read a 32-Bit Int from Parsing-Input and log 4 bytes in our Parsing-Monad
 | 
				
			||||||
int32 :: CParser Int32
 | 
					_int32 :: CParser Int32
 | 
				
			||||||
int32 = do
 | 
					_int32 = do
 | 
				
			||||||
        ret <- lift $ do
 | 
					        ret <- lift $ do
 | 
				
			||||||
                         a <- anyWord8 :: Parser Word8
 | 
					                         a <- anyWord8 :: Parser Word8
 | 
				
			||||||
                         b <- anyWord8 :: Parser Word8
 | 
					                         b <- anyWord8 :: Parser Word8
 | 
				
			||||||
                         c <- anyWord8 :: Parser Word8
 | 
					                         c <- anyWord8 :: Parser Word8
 | 
				
			||||||
                         d <- anyWord8 :: Parser Word8
 | 
					                         d <- anyWord8 :: Parser Word8
 | 
				
			||||||
                         return $ parseNum [d,c,b,a]
 | 
					                         return $ _parseNum [d,c,b,a]
 | 
				
			||||||
        modify (+4)
 | 
					        modify (+4)
 | 
				
			||||||
        return $ ret
 | 
					        return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					w32leCParser :: CParser Word32
 | 
				
			||||||
 | 
					w32leCParser = do
 | 
				
			||||||
 | 
						ret <- lift anyWord32le
 | 
				
			||||||
 | 
						modify (+4)
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | Parser for the header
 | 
					-- | Parser for the header
 | 
				
			||||||
readHeader :: CParser IQMHeader
 | 
					readHeader :: CParser IQMHeader
 | 
				
			||||||
readHeader = do
 | 
					readHeader = do
 | 
				
			||||||
         _ <- lift $ string (pack "INTERQUAKEMODEL\0")
 | 
					         _ <- lift $ string (pack "INTERQUAKEMODEL\0")
 | 
				
			||||||
         v <- int32
 | 
					         modify (+16)
 | 
				
			||||||
         -- when v /= 2 then --TODO: error something
 | 
					         v <- w32leCParser
 | 
				
			||||||
         size' <- int32
 | 
						 lift $ when (v /= 2) $ fail "Version /= 2.\nThis Parser only supports Version 2 of the InterQuake-Model IQM"
 | 
				
			||||||
         flags' <- int32
 | 
					         -- when v /= 2 then fail parsing.
 | 
				
			||||||
         num_text' <- int32
 | 
					         size' <- w32leCParser
 | 
				
			||||||
         ofs_text' <- int32
 | 
					         flags' <- w32leCParser
 | 
				
			||||||
         num_meshes' <- int32
 | 
					         num_text' <- w32leCParser
 | 
				
			||||||
         ofs_meshes' <- int32
 | 
					         ofs_text' <- w32leCParser
 | 
				
			||||||
         num_vertexarrays' <- int32
 | 
					         num_meshes' <- w32leCParser
 | 
				
			||||||
         num_vertexes' <- int32
 | 
					         ofs_meshes' <- w32leCParser
 | 
				
			||||||
         ofs_vertexarrays' <- int32
 | 
					         num_vertexarrays' <- w32leCParser
 | 
				
			||||||
         num_triangles' <- int32
 | 
					         num_vertexes' <- w32leCParser
 | 
				
			||||||
         ofs_triangles' <- int32
 | 
					         ofs_vertexarrays' <- w32leCParser
 | 
				
			||||||
         ofs_adjacency' <- int32
 | 
					         num_triangles' <- w32leCParser
 | 
				
			||||||
         num_joints' <- int32
 | 
					         ofs_triangles' <- w32leCParser
 | 
				
			||||||
         ofs_joints' <- int32
 | 
					         ofs_adjacency' <- w32leCParser
 | 
				
			||||||
         num_poses' <- int32
 | 
					         num_joints' <- w32leCParser
 | 
				
			||||||
         ofs_poses' <- int32
 | 
					         ofs_joints' <- w32leCParser
 | 
				
			||||||
         num_anims' <- int32
 | 
					         num_poses' <- w32leCParser
 | 
				
			||||||
         ofs_anims' <- int32
 | 
					         ofs_poses' <- w32leCParser
 | 
				
			||||||
         num_frames' <- int32
 | 
					         num_anims' <- w32leCParser
 | 
				
			||||||
         num_framechannels' <- int32
 | 
					         ofs_anims' <- w32leCParser
 | 
				
			||||||
         ofs_frames' <- int32
 | 
					         num_frames' <- w32leCParser
 | 
				
			||||||
         ofs_bounds' <- int32
 | 
					         num_framechannels' <- w32leCParser
 | 
				
			||||||
         num_comment' <- int32
 | 
					         ofs_frames' <- w32leCParser
 | 
				
			||||||
         ofs_comment' <- int32
 | 
					         ofs_bounds' <- w32leCParser
 | 
				
			||||||
         num_extensions' <- int32
 | 
					         num_comment' <- w32leCParser
 | 
				
			||||||
         ofs_extensions' <- int32
 | 
					         ofs_comment' <- w32leCParser
 | 
				
			||||||
 | 
					         num_extensions' <- w32leCParser
 | 
				
			||||||
 | 
					         ofs_extensions' <- w32leCParser
 | 
				
			||||||
         return IQMHeader { version = v
 | 
					         return IQMHeader { version = v
 | 
				
			||||||
                , filesize           = size'
 | 
					                , filesize           = size'
 | 
				
			||||||
                , flags              = flags'
 | 
					                , flags              = fromIntegral flags'
 | 
				
			||||||
                , num_text           = num_text'
 | 
					                , num_text           = num_text'
 | 
				
			||||||
                , ofs_text           = ofs_text'
 | 
					                , ofs_text           = ofs_text'
 | 
				
			||||||
                , num_meshes         = num_meshes'
 | 
					                , num_meshes         = num_meshes'
 | 
				
			||||||
@@ -115,12 +126,12 @@ readHeader = do
 | 
				
			|||||||
-- | Parser for Mesh-Structure
 | 
					-- | Parser for Mesh-Structure
 | 
				
			||||||
readMesh :: CParser IQMMesh
 | 
					readMesh :: CParser IQMMesh
 | 
				
			||||||
readMesh = do
 | 
					readMesh = do
 | 
				
			||||||
        name <- int32
 | 
					        name <- w32leCParser
 | 
				
			||||||
        mat <- int32
 | 
					        mat <- w32leCParser
 | 
				
			||||||
        fv <- int32
 | 
					        fv <- w32leCParser
 | 
				
			||||||
        nv <- int32
 | 
					        nv <- w32leCParser
 | 
				
			||||||
        ft <- int32
 | 
					        ft <- w32leCParser
 | 
				
			||||||
        nt <- int32
 | 
					        nt <- w32leCParser
 | 
				
			||||||
        return IQMMesh
 | 
					        return IQMMesh
 | 
				
			||||||
                { meshName              = if name == 0 then Nothing else Just (Mesh name)
 | 
					                { meshName              = if name == 0 then Nothing else Just (Mesh name)
 | 
				
			||||||
                , meshMaterial          = mat
 | 
					                , meshMaterial          = mat
 | 
				
			||||||
@@ -140,12 +151,32 @@ readMeshes n = do
 | 
				
			|||||||
        ms <- readMeshes (n-1)
 | 
					        ms <- readMeshes (n-1)
 | 
				
			||||||
        return $ m:ms
 | 
					        return $ m:ms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Parser for Mesh-Structure
 | 
				
			||||||
 | 
					readVAF :: CParser IQMVertexArray
 | 
				
			||||||
 | 
					readVAF = do
 | 
				
			||||||
 | 
					        vat <- rawEnumToVAT =<< w32leCParser
 | 
				
			||||||
 | 
					        flags' <- w32leCParser
 | 
				
			||||||
 | 
					        format <- rawEnumToVAF =<< w32leCParser
 | 
				
			||||||
 | 
					        size <- w32leCParser
 | 
				
			||||||
 | 
					        offset <- w32leCParser
 | 
				
			||||||
 | 
					        return $ IQMVertexArray vat (fromIntegral flags') format (fromIntegral size) offset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | helper to read n consecutive Meshes tail-recursive
 | 
				
			||||||
 | 
					readVAFs :: Int -> CParser [IQMVertexArray]
 | 
				
			||||||
 | 
					readVAFs 1 = do
 | 
				
			||||||
 | 
					        f <- readVAF
 | 
				
			||||||
 | 
					        return [f]
 | 
				
			||||||
 | 
					readVAFs n = do
 | 
				
			||||||
 | 
					        f <- readVAF
 | 
				
			||||||
 | 
					        fs <- readVAFs (n-1)
 | 
				
			||||||
 | 
					        return $ f:fs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | helper-Notation for subtracting 2 integral values of different kind in the precision
 | 
					-- | helper-Notation for subtracting 2 integral values of different kind in the precision
 | 
				
			||||||
--   of the target-kind
 | 
					--   of the target-kind
 | 
				
			||||||
(.-) :: forall a a1 a2.
 | 
					(.-) :: forall a a1 a2.
 | 
				
			||||||
              (Num a, Integral a2, Integral a1) =>
 | 
					              (Num a, Integral a2, Integral a1) =>
 | 
				
			||||||
              a1 -> a2 -> a
 | 
					              a1 -> a2 -> a
 | 
				
			||||||
(.-) a b = (fromIntegral a) - (fromIntegral b)
 | 
					(.-) a b = fromIntegral a - fromIntegral b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
infix 5 .-
 | 
					infix 5 .-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -162,18 +193,35 @@ skipToCounter a = do
 | 
				
			|||||||
                        put d
 | 
					                        put d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | Parses an IQM-File and handles back the Haskell-Structure
 | 
					-- | Parses an IQM-File and handles back the Haskell-Structure
 | 
				
			||||||
parseIQM :: CParser IQM
 | 
					parseIQM :: String -> IO IQM
 | 
				
			||||||
parseIQM = do
 | 
					parseIQM a =
 | 
				
			||||||
        put 0                                                   --start at offset 0
 | 
						do
 | 
				
			||||||
 | 
						f <- B.readFile a
 | 
				
			||||||
 | 
						Done _ raw <- return $ parse doIQMparse f
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						let ret = raw
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					doIQMparse :: Parser IQM
 | 
				
			||||||
 | 
					doIQMparse = 
 | 
				
			||||||
 | 
						flip evalStateT 0 $ --evaluate parser with state starting at 0
 | 
				
			||||||
 | 
							do
 | 
				
			||||||
        	h <- readHeader                                         --read header
 | 
					        	h <- readHeader                                         --read header
 | 
				
			||||||
	        skipToCounter $ ofs_text h                              --skip 0-n bytes to get to text
 | 
						        skipToCounter $ ofs_text h                              --skip 0-n bytes to get to text
 | 
				
			||||||
	        text <- lift . take . fromIntegral $ num_text h         --read texts
 | 
						        text <- lift . take . fromIntegral $ num_text h         --read texts
 | 
				
			||||||
	       	modify . (+) . fromIntegral $ num_text h                --put offset forward
 | 
						       	modify . (+) . fromIntegral $ num_text h                --put offset forward
 | 
				
			||||||
	        skipToCounter $ ofs_meshes h                            --skip 0-n bytes to get to meshes
 | 
						        skipToCounter $ ofs_meshes h                            --skip 0-n bytes to get to meshes
 | 
				
			||||||
        meshes' <- readMeshes (fromIntegral (num_meshes h))     --read meshes
 | 
						        meshes' <- readMeshes $ fromIntegral $ num_meshes h     --read meshes
 | 
				
			||||||
 | 
							skipToCounter $ ofs_vertexarrays h
 | 
				
			||||||
 | 
					                vaf <- readVAFs $ fromIntegral $ num_vertexarrays h     --read Vertex-Arrays
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_ <- lift takeByteString
 | 
				
			||||||
	        return IQM
 | 
						        return IQM
 | 
				
			||||||
	                { header = h
 | 
						                { header = h
 | 
				
			||||||
	                , texts = filter (not.null) (split (unsafeCoerce '\0') text)
 | 
						                , texts = filter (not.null) (split (unsafeCoerce '\0') text)
 | 
				
			||||||
	                , meshes = meshes'
 | 
						                , meshes = meshes'
 | 
				
			||||||
 | 
								, vertexArrays = vaf
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skipDrop :: Int -> Int -> ByteString -> ByteString
 | 
				
			||||||
 | 
					skipDrop a b= B.drop b . B.take a
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,28 @@
 | 
				
			|||||||
-- | Int32 or Int64 - depending on implementation. Format just specifies "uint".
 | 
					{-# LANGUAGE BangPatterns #-}
 | 
				
			||||||
--   4-Byte in the documentation indicates Int32 - but not specified!
 | 
					-- | Word32 or Word64 - depending on implementation. Format just specifies "uint".
 | 
				
			||||||
 | 
					--   4-Byte in the documentation indicates Word32 - but not specified!
 | 
				
			||||||
module Importer.IQM.Types where
 | 
					module Importer.IQM.Types where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Control.Monad.Trans.State.Lazy (StateT)
 | 
				
			||||||
import Data.Int
 | 
					import Data.Int
 | 
				
			||||||
 | 
					import Data.Word
 | 
				
			||||||
import Data.ByteString
 | 
					import Data.ByteString
 | 
				
			||||||
import Data.Attoparsec.ByteString.Char8
 | 
					import Data.Attoparsec.ByteString.Char8
 | 
				
			||||||
import Control.Monad.Trans.State.Lazy (StateT)
 | 
					import Foreign.Ptr
 | 
				
			||||||
 | 
					import Graphics.Rendering.OpenGL.Raw.Types
 | 
				
			||||||
 | 
					import Prelude as P
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | Mesh-Indices to distinguish the meshes referenced
 | 
					-- | Mesh-Indices to distinguish the meshes referenced
 | 
				
			||||||
newtype Mesh = Mesh Int32 deriving (Show, Eq)
 | 
					newtype Mesh = Mesh Word32 deriving (Show, Eq)
 | 
				
			||||||
-- | State-Wrapped Parser-Monad which is capable of counting the
 | 
					-- | State-Wrapped Parser-Monad which is capable of counting the
 | 
				
			||||||
--   Bytes read for offset-gap reasons
 | 
					--   Bytes read for offset-gap reasons
 | 
				
			||||||
type CParser a = StateT Int64 Parser a
 | 
					type CParser a = StateT Int64 Parser a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Flags = GLbitfield      -- ^ Alias for UInt32
 | 
				
			||||||
 | 
					type Offset = Word32         -- ^ Alias for UInt32
 | 
				
			||||||
 | 
					type Index = GLuint          -- ^ Alias for UInt32
 | 
				
			||||||
 | 
					type NumComponents = GLsizei -- ^ Alias for UInt32
 | 
				
			||||||
 | 
					type IQMData = Ptr IQMVertexArrayFormat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | Header of IQM-Format.
 | 
					-- | Header of IQM-Format.
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
@@ -23,33 +32,33 @@ type CParser a = StateT Int64 Parser a
 | 
				
			|||||||
--
 | 
					--
 | 
				
			||||||
--   ofs_* fields are aligned at 4-byte-boundaries
 | 
					--   ofs_* fields are aligned at 4-byte-boundaries
 | 
				
			||||||
data IQMHeader = IQMHeader
 | 
					data IQMHeader = IQMHeader
 | 
				
			||||||
                { version            :: Int32 -- ^ Must be 2
 | 
					                { version            :: !Word32 -- ^ Must be 2
 | 
				
			||||||
                , filesize           :: Int32
 | 
					                , filesize           :: !Word32
 | 
				
			||||||
                , flags              :: Int32
 | 
					                , flags              :: !Flags
 | 
				
			||||||
                , num_text           :: Int32
 | 
					                , num_text           :: !Word32
 | 
				
			||||||
                , ofs_text           :: Int32
 | 
					                , ofs_text           :: !Offset
 | 
				
			||||||
                , num_meshes         :: Int32
 | 
					                , num_meshes         :: !Word32
 | 
				
			||||||
                , ofs_meshes         :: Int32
 | 
					                , ofs_meshes         :: !Offset
 | 
				
			||||||
                , num_vertexarrays   :: Int32
 | 
					                , num_vertexarrays   :: !Word32
 | 
				
			||||||
                , num_vertexes       :: Int32
 | 
					                , num_vertexes       :: !Word32
 | 
				
			||||||
                , ofs_vertexarrays   :: Int32
 | 
					                , ofs_vertexarrays   :: !Offset
 | 
				
			||||||
                , num_triangles      :: Int32
 | 
					                , num_triangles      :: !Word32
 | 
				
			||||||
                , ofs_triangles      :: Int32
 | 
					                , ofs_triangles      :: !Offset
 | 
				
			||||||
                , ofs_adjacency      :: Int32
 | 
					                , ofs_adjacency      :: !Offset
 | 
				
			||||||
                , num_joints         :: Int32
 | 
					                , num_joints         :: !Word32
 | 
				
			||||||
                , ofs_joints         :: Int32
 | 
					                , ofs_joints         :: !Offset
 | 
				
			||||||
                , num_poses          :: Int32
 | 
					                , num_poses          :: !Word32
 | 
				
			||||||
                , ofs_poses          :: Int32
 | 
					                , ofs_poses          :: !Offset
 | 
				
			||||||
                , num_anims          :: Int32
 | 
					                , num_anims          :: !Word32
 | 
				
			||||||
                , ofs_anims          :: Int32
 | 
					                , ofs_anims          :: !Offset
 | 
				
			||||||
                , num_frames         :: Int32
 | 
					                , num_frames         :: !Word32
 | 
				
			||||||
                , num_framechannels  :: Int32
 | 
					                , num_framechannels  :: !Word32
 | 
				
			||||||
                , ofs_frames         :: Int32
 | 
					                , ofs_frames         :: !Offset
 | 
				
			||||||
                , ofs_bounds         :: Int32
 | 
					                , ofs_bounds         :: !Offset
 | 
				
			||||||
                , num_comment        :: Int32
 | 
					                , num_comment        :: !Word32
 | 
				
			||||||
                , ofs_comment        :: Int32
 | 
					                , ofs_comment        :: !Offset
 | 
				
			||||||
                , num_extensions     :: Int32 -- ^ stored as linked list, not as array.
 | 
					                , num_extensions     :: !Word32 -- ^ stored as linked list, not as array.
 | 
				
			||||||
                , ofs_extensions     :: Int32
 | 
					                , ofs_extensions     :: !Offset
 | 
				
			||||||
                } deriving (Show, Eq)
 | 
					                } deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | Format of an IQM-Mesh Structure.
 | 
					-- | Format of an IQM-Mesh Structure.
 | 
				
			||||||
@@ -57,13 +66,29 @@ data IQMHeader = IQMHeader
 | 
				
			|||||||
--   Read it like a Header of the Meshes lateron in the Format
 | 
					--   Read it like a Header of the Meshes lateron in the Format
 | 
				
			||||||
data IQMMesh = IQMMesh
 | 
					data IQMMesh = IQMMesh
 | 
				
			||||||
                { meshName              :: Maybe Mesh
 | 
					                { meshName              :: Maybe Mesh
 | 
				
			||||||
                , meshMaterial          :: Int32
 | 
					                , meshMaterial          :: Word32
 | 
				
			||||||
                , meshFirstVertex       :: Int32
 | 
					                , meshFirstVertex       :: Word32
 | 
				
			||||||
                , meshNumVertexes       :: Int32
 | 
					                , meshNumVertexes       :: Word32
 | 
				
			||||||
                , meshFirstTriangle     :: Int32
 | 
					                , meshFirstTriangle     :: Word32
 | 
				
			||||||
                , meshNumTriangles      :: Int32
 | 
					                , meshNumTriangles      :: Word32
 | 
				
			||||||
                } deriving (Show, Eq)
 | 
					                } deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Format of IQM-Triangle Structure
 | 
				
			||||||
 | 
					data IQMTriangle = IQMTriangle VertexIndex VertexIndex VertexIndex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Type-Alias for Word32 indicating an index on vertices in IQMMesh
 | 
				
			||||||
 | 
					type VertexIndex = Word32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Type-Alias for Word32 indicating an index on IQMTriangle
 | 
				
			||||||
 | 
					type TriangleIndex = Word32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | From the IQM-Format-Description:
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					--   each value is the index of the adjacent triangle for edge 0, 1, and 2, where ~0 (= -1)
 | 
				
			||||||
 | 
					--   indicates no adjacent triangle indexes are relative to the iqmheader.ofs_triangles array
 | 
				
			||||||
 | 
					--   and span all meshes, where 0 is the first triangle, 1 is the second, 2 is the third, etc.
 | 
				
			||||||
 | 
					data IQMAdjacency = IQMAdjacency TriangleIndex TriangleIndex TriangleIndex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- | Format of a whole IQM-File
 | 
					-- | Format of a whole IQM-File
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
--   still unfinished!
 | 
					--   still unfinished!
 | 
				
			||||||
@@ -71,5 +96,82 @@ data IQM = IQM
 | 
				
			|||||||
        { header                :: IQMHeader
 | 
					        { header                :: IQMHeader
 | 
				
			||||||
        , texts                 :: [ByteString]
 | 
					        , texts                 :: [ByteString]
 | 
				
			||||||
        , meshes                :: [IQMMesh]
 | 
					        , meshes                :: [IQMMesh]
 | 
				
			||||||
 | 
					        , vertexArrays          :: [IQMVertexArray]
 | 
				
			||||||
        } deriving (Show, Eq)
 | 
					        } deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Different Vertex-Array-Types in IQM
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					--   Custom Types have to be > 0x10 as of specification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data IQMVertexArrayType = IQMPosition
 | 
				
			||||||
 | 
					                       | IQMTexCoord
 | 
				
			||||||
 | 
					                       | IQMNormal
 | 
				
			||||||
 | 
					                       | IQMTangent
 | 
				
			||||||
 | 
					                       | IQMBlendIndexes
 | 
				
			||||||
 | 
					                       | IQMBlendWeights
 | 
				
			||||||
 | 
					                       | IQMColor
 | 
				
			||||||
 | 
					                       | IQMCustomVAT Word32
 | 
				
			||||||
 | 
					                       deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Lookup-Function for internal enum to VertexArrayFormat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rawEnumToVAT :: Word32 -> CParser IQMVertexArrayType
 | 
				
			||||||
 | 
					rawEnumToVAT 0 = return IQMPosition
 | 
				
			||||||
 | 
					rawEnumToVAT 1 = return IQMTexCoord
 | 
				
			||||||
 | 
					rawEnumToVAT 2 = return IQMNormal
 | 
				
			||||||
 | 
					rawEnumToVAT 3 = return IQMTangent
 | 
				
			||||||
 | 
					rawEnumToVAT 4 = return IQMBlendIndexes
 | 
				
			||||||
 | 
					rawEnumToVAT 5 = return IQMBlendWeights
 | 
				
			||||||
 | 
					rawEnumToVAT 6 = return IQMColor
 | 
				
			||||||
 | 
					rawEnumToVAT a = return $ IQMCustomVAT a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Vetrex-Array-Format of the data found at offset
 | 
				
			||||||
 | 
					data IQMVertexArrayFormat = IQMbyte
 | 
				
			||||||
 | 
					                            | IQMubyte
 | 
				
			||||||
 | 
					                            | IQMshort
 | 
				
			||||||
 | 
					                            | IQMushort
 | 
				
			||||||
 | 
					                            | IQMint
 | 
				
			||||||
 | 
					                            | IQMuint
 | 
				
			||||||
 | 
					                            | IQMhalf
 | 
				
			||||||
 | 
					                            | IQMfloat
 | 
				
			||||||
 | 
					                            | IQMdouble
 | 
				
			||||||
 | 
					--                            | Unknown Word32
 | 
				
			||||||
 | 
					                       deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | Lookup-Function for internal enum to VertexArrayFormat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rawEnumToVAF :: Word32 -> CParser IQMVertexArrayFormat
 | 
				
			||||||
 | 
					rawEnumToVAF 0 = return IQMbyte
 | 
				
			||||||
 | 
					rawEnumToVAF 1 = return IQMubyte
 | 
				
			||||||
 | 
					rawEnumToVAF 2 = return IQMshort
 | 
				
			||||||
 | 
					rawEnumToVAF 3 = return IQMushort
 | 
				
			||||||
 | 
					rawEnumToVAF 4 = return IQMint
 | 
				
			||||||
 | 
					rawEnumToVAF 5 = return IQMuint
 | 
				
			||||||
 | 
					rawEnumToVAF 6 = return IQMhalf
 | 
				
			||||||
 | 
					rawEnumToVAF 7 = return IQMfloat
 | 
				
			||||||
 | 
					rawEnumToVAF 8 = return IQMdouble
 | 
				
			||||||
 | 
					--rawEnumToVAF a = return $ Unknown a
 | 
				
			||||||
 | 
					rawEnumToVAF a = fail $ P.concat ["unrecognized enum(",show a,") in VertexArrayFormat"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- | A Vertex-Array-Definiton.
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					--   The Vertex starts at Offset and has num_vertexes * NumComponents entries.
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					--   All Vertex-Arrays seem to have the same number of components, just differ in Type, Format
 | 
				
			||||||
 | 
					--   and Flags
 | 
				
			||||||
 | 
					data IQMVertexArray = IQMVertexArray
 | 
				
			||||||
 | 
					                        IQMVertexArrayType
 | 
				
			||||||
 | 
					                        Flags
 | 
				
			||||||
 | 
					                        IQMVertexArrayFormat
 | 
				
			||||||
 | 
					                        NumComponents
 | 
				
			||||||
 | 
					                        Offset
 | 
				
			||||||
 | 
					                       deriving (Eq)
 | 
				
			||||||
 | 
					instance Show IQMVertexArray where
 | 
				
			||||||
 | 
					    show (IQMVertexArray t fl fo nc off) = "IQMVertexArray (Type: " ++ show t ++
 | 
				
			||||||
 | 
					                                                        ", Flags: " ++ show fl ++
 | 
				
			||||||
 | 
					                                                        ", Format: " ++ show fo ++
 | 
				
			||||||
 | 
					                                                        ", NumComponents: " ++ show nc ++
 | 
				
			||||||
 | 
					                                                        ", Offset: " ++ show off ++
 | 
				
			||||||
 | 
					                                                        ")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								src/Main.hs
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/Main.hs
									
									
									
									
									
								
							@@ -16,7 +16,6 @@ import           Control.Concurrent.STM               (TQueue,
 | 
				
			|||||||
                                                       newTQueueIO)
 | 
					                                                       newTQueueIO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import           Control.Monad.RWS.Strict             (ask, evalRWST, get, liftIO, modify)
 | 
					import           Control.Monad.RWS.Strict             (ask, evalRWST, get, liftIO, modify)
 | 
				
			||||||
import           Control.Monad.Trans.State            (evalStateT)
 | 
					 | 
				
			||||||
import           Data.Functor                         ((<$>))
 | 
					import           Data.Functor                         ((<$>))
 | 
				
			||||||
import           Data.Monoid                          (mappend)
 | 
					import           Data.Monoid                          (mappend)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,17 +45,21 @@ import           UI.Callbacks
 | 
				
			|||||||
import           Map.Graphics
 | 
					import           Map.Graphics
 | 
				
			||||||
import           Types
 | 
					import           Types
 | 
				
			||||||
import           Importer.IQM.Parser
 | 
					import           Importer.IQM.Parser
 | 
				
			||||||
import           Data.Attoparsec.Char8 (parseTest)
 | 
					--import           Data.Attoparsec.Char8 (parseTest)
 | 
				
			||||||
import qualified Data.ByteString as B
 | 
					--import qualified Data.ByteString as B
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- import qualified Debug.Trace                          as D (trace)
 | 
					-- import qualified Debug.Trace                          as D (trace)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
testParser :: IO ()
 | 
					testParser :: String -> IO ()
 | 
				
			||||||
testParser = do
 | 
					testParser a = putStrLn . show  =<< parseIQM a
 | 
				
			||||||
        f <- B.readFile "sample.iqm"
 | 
					{-do
 | 
				
			||||||
        parseTest (evalStateT parseIQM 0) f
 | 
							f <- B.readFile a
 | 
				
			||||||
 | 
							putStrLn "reading in:"
 | 
				
			||||||
 | 
							putStrLn $ show f
 | 
				
			||||||
 | 
							putStrLn "parsed:"
 | 
				
			||||||
 | 
							parseTest parseIQM f-}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user