summaryrefslogtreecommitdiff
path: root/src/Game/Internal/Types.hs
blob: 8095cfb5bb3e8bc3484e7a9d04d9ab7e4ea66164 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
{-# LANGUAGE NamedFieldPuns, OverloadedRecordDot #-}

{- |
 - Module      : Game.Internal.Types
 - Description : 
 - Copyright   : 2025 Andromeda
 - License     : BSD 3-clause
 - Maintainer  : Matrix @Andromeda:tchncs.de
 - Stability   : Experimental
 -}
module Game.Internal.Types
  ( Object(..)
  , toGLMatrix
  , Model(camera, objects, cursorDeltaPos, cursorPos, program, keys, wprop)
  , mkModel
  , Camera(camPos, camPitch, camYaw, camReference, mouseSensitivity, camVel, strafeStrength, jumpStrength, hasJumped, airTime)
  , mkCamera
  , WorldProperties(g, friction, up)
  , mkWorldProperties
  ) where

import qualified Graphics.Rendering.OpenGL as GL
import qualified Graphics.UI.GLFW as GLFW

import qualified Linear as L
import Linear (V3, V3(..), V4(..))

-- | represents a single draw call
data Object = Object
  { vao :: GL.VertexArrayObject -- ^ vao of vertex buffer
  , numIndicies :: GL.NumArrayIndices -- ^ number of vertices
  , numComponents :: GL.NumComponents -- ^ dimensionallity; vec3, vec4, etc.
  , primitiveMode :: GL.PrimitiveMode -- ^ primitive mode to be drawn with
  } deriving (Show)

-- | converts M44 to a 16array for OpenGL
toGLMatrix :: L.M44 GL.GLfloat -> [GL.GLfloat]
toGLMatrix (V4 (V4 c00 c01 c02 c03) (V4 c10 c11 c12 c13) (V4 c20 c21 c22 c23) (V4 c30 c31 c32 c33)) =
  [ c00
  , c01
  , c02
  , c03
  , c10
  , c11
  , c12
  , c13
  , c20
  , c21
  , c22
  , c23
  , c30
  , c31
  , c32
  , c33
  ]

-- | gamestate
data Model = Model
  { camera :: Camera
  , cursorDeltaPos :: (Double, Double) -- ^ frame-on-frame delta mouse position
  , cursorPos :: (Double, Double) -- ^ current mouse position
  , keys :: [GLFW.Key] -- ^ currently pressed keys
  , objects :: [Object] -- ^ draw calls
  , program :: GL.Program -- ^ shader program
  , wprop :: WorldProperties
  } deriving (Show)

-- | smart constructor for Model
mkModel :: Camera -> [Object] -> GL.Program -> WorldProperties -> Model
mkModel camera objects program wprop =
  Model camera (0, 0) (0, 0) [] objects program wprop

-- | camera
data Camera = Camera
  { camPos :: V3 Float -- ^ position in world space
  , camPitch :: Float -- ^ pitch in radians, up positive
  , camYaw :: Float -- ^ yaw in radians, right positive
  , camReference :: V3 Float -- ^ reference direction; orientation applied to
  , camVel :: V3 Float -- ^ velocity in world space
  , mouseSensitivity :: Float -- ^ scale factor for mouse movement
  , strafeStrength :: Float -- ^ scale factor for strafe
  , jumpStrength :: Float -- ^ scale factor for jump initial velocity
  , hasJumped :: Bool -- ^ whether the camera still has jumping state
  , airTime :: Float -- ^ time since jumping state entered in seconds
  } deriving (Show)

-- | smart constructor for Camera
mkCamera ::
     V3 Float
  -> Float
  -> Float
  -> V3 Float
  -> V3 Float
  -> Float
  -> Float
  -> Float
  -> Camera
mkCamera camPos camPitch camYaw camReference camVel mouseSensitivity strafeStrength jumpStrength =
  Camera
    camPos
    camPitch
    camYaw
    (L.normalize camReference)
    (L.normalize camVel)
    mouseSensitivity
    strafeStrength
    jumpStrength
    False
    0

-- | physical properties of the world
data WorldProperties = WorldProperties
  { g :: Float -- ^ gravity `g`
  , friction :: Float -- ^ scale factor for floor friction
  , up :: V3 Float -- ^ global up vector
  } deriving (Show)

-- | smart constructor for WorldProperties
mkWorldProperties :: Float -> Float -> V3 Float -> WorldProperties
mkWorldProperties g friction up = WorldProperties g friction (L.normalize up)