summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MatchBloxEngine/MatchBloxEngine/C_3DObject.cpp8
-rw-r--r--MatchBloxEngine/MatchBloxEngine/C_3DObject.h1
-rw-r--r--MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.cpp186
-rw-r--r--MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.h105
-rw-r--r--MatchBloxEngine/MatchBloxEngine/Makefile2
-rw-r--r--MatchBloxEngine/MatchBloxEngine/typedefs.h90
6 files changed, 326 insertions, 66 deletions
diff --git a/MatchBloxEngine/MatchBloxEngine/C_3DObject.cpp b/MatchBloxEngine/MatchBloxEngine/C_3DObject.cpp
index 0b819e7..75e7ead 100644
--- a/MatchBloxEngine/MatchBloxEngine/C_3DObject.cpp
+++ b/MatchBloxEngine/MatchBloxEngine/C_3DObject.cpp
@@ -147,9 +147,9 @@ bool C_3DObject::CreateObject(const char *f_pFilePath)
<< "\nNormals: " << l_Geom.m_norms.size()-1
<< "\nTexCrds: " << l_Geom.m_texs.size()-1
<< "\nTriangles: " << l_Geom.m_triangles.size()
- << "\nBoundBox: x(" << m_BBox.m_dLeft << "," << m_BBox.m_dRight << ")"
- << "\n y(" << m_BBox.m_dBottom << "," << m_BBox.m_dTop << ")"
- << "\n z(" << m_BBox.m_dFront << "," << m_BBox.m_dBack << ")"
+ << "\nBoundBox: x(" << m_BBox.m_Min.x << "," << m_BBox.m_Max.x << ")"
+ << "\n y(" << m_BBox.m_Min.y << "," << m_BBox.m_Max.y << ")"
+ << "\n z(" << m_BBox.m_Min.z << "," << m_BBox.m_Max.z << ")"
<< std::endl;
if(!l_bParseOk)
@@ -250,7 +250,7 @@ bool C_3DObject::LoadGeometryData(const char *f_pFilePath, Geometry_t &f_Geom)
{
f_Geom.m_verts.push_back(l_v3);
//update boundingbox
- UpdBBox(m_BBox, l_v3);
+ m_BBox << l_v3;
}
break;
diff --git a/MatchBloxEngine/MatchBloxEngine/C_3DObject.h b/MatchBloxEngine/MatchBloxEngine/C_3DObject.h
index 4027596..55ae123 100644
--- a/MatchBloxEngine/MatchBloxEngine/C_3DObject.h
+++ b/MatchBloxEngine/MatchBloxEngine/C_3DObject.h
@@ -37,6 +37,7 @@ public:
inline const Vect3D_t& GetRot() { return m_Rot; }
inline const Vect3D_t& GetScale() { return m_Scale; }
inline const BoundingBox_t& GetBoundingBox() { return m_BBox; }
+ inline const BoundingBox_t& GetAbsBoundBox() { return m_BBox + m_Pos; }
inline bool Initialized() { return m_bDispListValid; }
void TransRotateScale(); //applies the scaling, translation and rotation
diff --git a/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.cpp b/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.cpp
index 7e17b1b..80767b8 100644
--- a/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.cpp
+++ b/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.cpp
@@ -15,7 +15,9 @@
#include "bitmap.h"
C_MatchBloxEngine::C_MatchBloxEngine(const char *f_strModelPath,
- const char *f_strLogFile)
+ const char *f_strLogFile,
+ GameSettings f_GameSettings)
+: m_GameSettings(f_GameSettings)
{
//create logger
@@ -37,19 +39,10 @@ C_MatchBloxEngine::C_MatchBloxEngine(const char *f_strModelPath,
//init vars
m_CurrentBox = BS_SMALL;
- //debug
- m_pBox[0]->SetPos(0.0, -5.0, -15.0);
- m_pBox[0]->SetRot(45.0, 0.0, 0.0);
- m_pBox[0]->RandomizeTiles();
-
- m_pBlock[0]->SetPos(-6.0, 1.0, -10.0);
- m_pBlock[0]->SetRot(90.0, 0.0, 0.0);
- m_pBlock[1]->SetPos(-2.0, 1.0, -10.0);
- m_pBlock[1]->SetRot(90.0, 0.0, 0.0);
- m_pBlock[2]->SetPos(2.0, 1.0, -10.0);
- m_pBlock[2]->SetRot(90.0, 0.0, 0.0);
- m_pBlock[3]->SetPos(6.0, 1.0, -10.0);
- m_pBlock[3]->SetRot(90.0, 0.0, 0.0);
+ //init the world bounding box
+ m_WorldBox.m_Min = Vect3D_t(-50.0, -50.0, -50.0);
+ m_WorldBox.m_Max = Vect3D_t(50.0, 50.0, 0.0);
+
}
C_MatchBloxEngine::~C_MatchBloxEngine()
@@ -60,10 +53,28 @@ C_MatchBloxEngine::~C_MatchBloxEngine()
DeleteModels();
}
-GameResult C_MatchBloxEngine::GameStep(msgQueue &f_Queue)
+GameResult C_MatchBloxEngine::ProcessMsgs(msgQueue &f_Queue)
{
+ msgStruct l_msg;
+
//process message queue
- return GR_ERROR;
+ while (!f_Queue.empty())
+ {
+ //get the first msg
+ l_msg = f_Queue.front();
+ f_Queue.pop();
+
+ switch (l_msg.m_MessageType)
+ {
+ case WII_CURSOR_MOVE:
+
+ break;
+
+ case WII_BUTTON_PRESS:
+ break;
+ }
+ }
+ return GR_BUSY;
}
void C_MatchBloxEngine::Render_Basics(unsigned int f_uiElapsedTime)
@@ -71,10 +82,13 @@ void C_MatchBloxEngine::Render_Basics(unsigned int f_uiElapsedTime)
//render the environment
m_pEnvMap->Render();
- m_pBox[(intptr_t)m_CurrentBox]->Render();
- for (int i=0; i<4; i++)
- m_pBlock[i]->Render(f_uiElapsedTime);
-// m_pHand->Render(f_uiElapsedTime);
+ if (m_pCurrentSession)
+ {
+ m_pBox[(int)m_pCurrentSession->m_BoxSize]->Render();
+ for (int i=0; i<4; i++)
+ m_pBlock[i]->Render(f_uiElapsedTime);
+ // m_pHand->Render(f_uiElapsedTime);
+ }
}
void C_MatchBloxEngine::Render(unsigned int f_uiElapsedTime)
@@ -148,15 +162,17 @@ bool C_MatchBloxEngine::NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS)
{
//log new game
- //prepare a fresh box
- m_CurrentBox = f_BS;
- m_pBox[(int)m_CurrentBox]->RandomizeTiles();
+ //prepare a session struct for administration
+ m_pCurrentSession = new GameSession(8, f_BS);
+
+ //randomize the box tiles
+ m_pBox[(int)m_pCurrentSession->m_BoxSize]->RandomizeTiles();
+ //init box's position
+ m_pBox[(int)m_pCurrentSession->m_BoxSize]->SetPos(0.0, -6.0, -15.0);
//set state to GET READY
m_State = ES_GET_READY;
- //init object positions
- m_pBox[(int)m_CurrentBox]->SetPos(0.0, -6.0, -15.0);
return true;
}
@@ -165,6 +181,20 @@ bool C_MatchBloxEngine::NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS)
bool C_MatchBloxEngine::StartGame()
{
+ if (m_State == ES_GET_READY)
+ {
+ BlockType l_Block;
+
+ //start the session timer
+ l_Block = m_pCurrentSession->StartSession();
+
+ //move a block into the sky
+ m_pBlock[(int)l_Block]->SetPos(0.0, 0.0, 15.0);
+
+ m_State = ES_PLAYING_GRAB_BLOCK;
+
+ return true;
+ }
return false;
}
@@ -178,7 +208,7 @@ bool C_MatchBloxEngine::Pause()
m_SavedState = m_State;
//probably do something with a time variable
-
+
//set current state to paused
m_State = ES_PAUSED;
@@ -346,3 +376,107 @@ void C_MatchBloxEngine::LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
+void C_MatchBloxEngine::CursorMove(Vect3D_t f_NewCursorPos)
+{
+ //check the state to see what 3d object currently has to be considered to
+ //be the cursor currently is and which bounding box we need to check for overlap
+ BoundingBox_t l_CursBBox;
+ bool l_bCollision = false; //indicates a collission has happend
+
+ switch (m_State)
+ {
+ case ES_PLAYING_PUT_BLOCK:
+ //cursor is the current block figure (that is being held by the player)
+ //translate the bounding box of the block with the cursor position
+ l_CursBBox = m_pBlock[m_CurrentBlock]->GetBoundingBox() + f_NewCursorPos;
+ break;
+
+ default:
+ //cursor is the hand object
+ l_CursBBox = m_pHand->GetBoundingBox() + f_NewCursorPos;
+ break;
+ }
+
+ //now we have the bounding box of the cursor which we use to do some simple hit tests
+
+ //make sure the cursor is still completely contained in the world bounding box
+ if (!m_WorldBox.Contains(l_CursBBox))
+ {
+ //restore the previous cursor position, because the new one is invalid
+ //... nothing to do actually
+ //maybe generate some vibration event and collision animation???
+ l_bCollision = true;
+ }
+ else
+ {
+ //check for bounding box overlap with the static elements in the scene
+ //actually only the block box
+ if (m_pBox[m_CurrentBox]->GetAbsBoundBox().Overlap(l_CursBBox))
+ {
+ //overlap with the block box, a collision is very likely so set
+ //collision to true and reset to false when the player is putting
+ //the block in the right hole (if the player is holding a block
+ //that is, if the player isn't then there is certainly a collision)
+ l_bCollision = true;
+
+ //check if we are holding a block that has to be put in the box
+ if (m_State == ES_PLAYING_PUT_BLOCK)
+ {
+
+
+ }
+ else
+ {
+ //we are not holding a block so every contact with the
+ //block box is a collision
+ l_bCollision = true;
+ }
+ }
+ }
+
+}
+
+GameResult_t C_MatchBloxEngine::CursorMove_PutBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox)
+{
+ //check if the block is being put in the right hole
+ //by testing whether the position of the cursor is close
+ //enough to the center of the correct hole
+ //note that the hole positions are relative to the position
+ //of the box
+ Vect3D_t l_AbsHolePos = m_pBox[m_CurrentBox]->GetPos() +
+ m_pTiles[m_CurrentBlock]->GetPos();
+ Vect3D_t l_PosDif = l_AbsHolePos - f_CursPos;
+ double l_dXZProximity = l_PosDif.x * l_PosDif.x +
+ l_PosDif.y * l_PosDif.y;
+
+ if (l_dXZProximity < m_GameSettings.m_dMinProximity)
+ {
+ //the block the player is holding is considered to be in the right hole
+ //l_bCollision = false;
+
+ //?? would it not be better to check for bounding box intersection with hole?
+ l_bCollision = !(m_pTiles[m_CurrentBlock]->GetAbsBoundBox() +
+ m_pBox[m_CurrentBox]->GetPos())->Overlap(f_CursBBox);
+
+ //now check if the block is far enough in the hole to count as a point
+ if (l_PosDif.z > m_GameSettings.m_dHoleDepth)
+ {
+ //yipee!! we have got a winner!!
+ m_CurrentBlock = m_pGameSession->NewTurn();
+
+ m_GameState
+ }
+
+
+ }
+}
+
+GameResult_t C_MatchBloxEngine::CursorMove_GrabBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox)
+{
+ //grabbing a block: just check for bounding box intersection
+ if (m_pBlock[(int)m_CurrentBlock)->GetAbsBoundBox().Overlap(f_CursBBox))
+ {
+
+ }
+}
+
diff --git a/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.h b/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.h
index 97aa892..5ef6c5d 100644
--- a/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.h
+++ b/MatchBloxEngine/MatchBloxEngine/C_MatchBloxEngine.h
@@ -44,15 +44,99 @@ enum BoxSize
BS_LARGE = 2
};
+struct GameSettings
+{
+ int m_iNrOfTurns;
+ double m_dMinProximity, //The minimum allowed squared (xz) distance between
+ //the center of the block and the center of the hole
+ //for the block to be considered to be in the hole
+ m_dHoleDepth; //Depth of a hole; the minimum z distance between block
+ //and a hole, for the block to be successfully inserted
+ //into the box
+};
+
+struct GameSession
+{
+ int m_iTotalTurns,
+ m_iCurrentTurn;
+ unsigned int m_uiSessionStart, //time in ms
+ m_uiTurnStart,
+ m_uiPauseStart,
+ *m_puiTurnResult;
+ int m_iBlocksLeft[4]; //number of blocks per type
+ BlockType m_CurrentBlockType;
+ BoxSize m_BoxSize;
+
+ GameSession(int f_iNrOfBlocks, BoxSize f_BS)
+ : m_iTotalTurns(f_iNrOfBlocks), m_iCurrentTurn(0),
+ m_BoxSize(f_BS)
+ {
+ m_puiTurnResult = new unsigned int[f_iNrOfBlocks];
+
+ //divide the number of blocks between the block types
+ int l_iNrPerType = f_iNrOfBlocks/4,
+ l_iLeft = f_iNrOfBlocks%4; //the left-over count
+ for(int i=0; i<4; i++)
+ {
+ m_iBlocksLeft[i] = l_iNrPerType;
+ if (l_iLeft > 0)
+ {
+ m_iBlocksLeft[i]++; l_iLeft--;
+ }
+ }
+ }
+ ~GameSession()
+ {
+ delete [] m_puiTurnResult;
+ }
+ BlockType StartSession()
+ {
+ m_uiSessionStart = m_uiTurnStart = glutGet(GLUT_ELAPSED_TIME);
+ return GetRandomBlockType();
+ }
+ BlockType NewTurn()
+ {
+ unsigned int l_uiTime = glutGet(GLUT_ELAPSED_TIME);
+
+ //save turn result
+ m_puiTurnResult[m_iCurrentTurn] = l_uiTime - m_uiTurnStart;
+ m_iCurrentTurn++;
+ m_uiTurnStart = l_uiTime;
+
+ return GetRandomBlockType();
+ }
+ BlockType GetRandomBlockType()
+ {
+ int l_iBlockType = rand()%4;
+ while (m_iBlocksLeft[l_iBlockType] <= 0)
+ l_iBlockType = (l_iBlockType+1)%4;
+
+ m_iBlocksLeft[l_iBlockType]--;
+ return (BlockType)l_iBlockType;
+ }
+ void PauseSession()
+ {
+ //record the time at which the pause starts
+ m_uiPauseStart = glutGet(GLUT_ELAPSED_TIME);
+ }
+ void ResumeSession()
+ {
+ //add the total pause time to the timers
+ unsigned int l_uiPauseTime = glutGet(GLUT_ELAPSED_TIME) - m_uiPauseStart;
+ m_uiSessionStart += l_uiPauseTime;
+ m_uiTurnStart += l_uiPauseTime;
+ }
+}
class C_MatchBloxEngine
{
public:
C_MatchBloxEngine(const char *f_strModelPath,
- const char *f_strLogFile);
+ const char *f_strLogFile
+ GameSettings f_GameSettings);
~C_MatchBloxEngine();
- GameResult GameStep(msgQueue &f_Queue);
+ GameResult ProcessMsgs(msgQueue &f_Queue);
void Render(unsigned int f_uiElapsedTime);
bool NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS);
@@ -74,13 +158,26 @@ private:
m_uiWood3Tex;
EngineState m_State, m_SavedState;
- BoxSize m_CurrentBox;
+ GameSession *m_pCurrentSession;
+ GameSettings m_GameSettings;
- void Render_Basics(unsigned int f_uiElapsedTime);
+ BoundingBox_t m_WorldBox; //an invisible box that limits the movement of the
+ //player
+
+ //init routines
bool LoadModels(const char* f_strModelDir);
void DeleteModels();
void LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle);
+
+ //render routines
+ void Render_Basics(unsigned int f_uiElapsedTime);
+
+ //event/input handlers
+ void CursorMove(Vect3D_t &f_NewCursorPos);
+ GameResult_t CursorMove_PutBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox);
+ GameResult_t CursorMove_GrabBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CusrBBox);
+
};
#endif //C_MATCHBLOXENGINE_HEADER_FILE
diff --git a/MatchBloxEngine/MatchBloxEngine/Makefile b/MatchBloxEngine/MatchBloxEngine/Makefile
index 383ce98..e6e6668 100644
--- a/MatchBloxEngine/MatchBloxEngine/Makefile
+++ b/MatchBloxEngine/MatchBloxEngine/Makefile
@@ -27,5 +27,5 @@ MatchBloxEngine: $(objects)
include $(sources:.cpp=.d)
clean:
- -rm MatchBloxEngine $(objects) *.d
+ -rm MatchBloxEngine $(objects) *.d *.d.*
diff --git a/MatchBloxEngine/MatchBloxEngine/typedefs.h b/MatchBloxEngine/MatchBloxEngine/typedefs.h
index 0262c14..0b9190c 100644
--- a/MatchBloxEngine/MatchBloxEngine/typedefs.h
+++ b/MatchBloxEngine/MatchBloxEngine/typedefs.h
@@ -5,22 +5,6 @@
#include <vector>
#include <limits>
-typedef struct bb
-{
- bb() {
- //init a bounding box with the min values set to max double and visa versa
- m_dLeft = m_dBottom = m_dFront = std::numeric_limits<double>::max();
- m_dRight = m_dTop = m_dBack = -std::numeric_limits<double>::max();
- }
-
- double m_dLeft, //min x
- m_dBottom, //min y
- m_dFront, //min z
- m_dRight, //max x
- m_dTop, //max y
- m_dBack; //max z
-
-} BoundingBox_t;
typedef struct vec3d
{
@@ -55,23 +39,67 @@ typedef struct vec3d
{ return vec3d(*this) *= scal; }
} Vect3D_t;
+typedef struct bb
+{
+ Vect3D_t m_Min, //minimal corner vertex (-x, -y, -z)
+ m_Max; //maximal corner vertex (+x, +y, +z)
+ //default constructor creates a maximum inverted bounding box
+ bb()
+ {
+ //init a bounding box with the min values set to max double and visa versa
+ double l_doubleMax = std::numeric_limits<double>::max();
+ m_Min = Vect3D_t(l_doubleMax, l_doubleMax, l_doubleMax);
+ m_Max = Vect3D_t(-l_doubleMax, -l_doubleMax, -l_doubleMax);
+ }
+
+ //copy constructor
+ bb(const bb &b) : m_Min(b.m_Min), m_Max(b.m_Max) {}
+
+ //translating a bounding box
+ inline bb& operator+=(const Vect3D_t &v)
+ { m_Min += v; m_Max += v; return *this; }
+ inline const bb& operator+(const Vect3D_t &v)
+ { return (bb(*this) += v); }
+
+ //update the bounding box min/max coords with vertex v
+ inline bb& operator<<(const Vect3D_t &v)
+ {
+ if (v.x < m_Min.x) m_Min.x = v.x;
+ else if (v.x > m_Max.x) m_Max.x = v.x;
+ if (v.y < m_Min.y) m_Min.y = v.y;
+ else if (v.y > m_Max.y) m_Max.y = v.y;
+ if (v.z < m_Min.z) m_Min.z = v.z;
+ else if (v.z > m_Max.z) m_Max.z = v.z;
+ return *this;
+ }
+
+ inline bool Contains(const Vect3D_t &v)
+ {
+ //check if the point is contained in the box
+ return m_Min.x < v.x && v.x < m_Max.x &&
+ m_Min.y < v.y && v.y < m_Max.y &&
+ m_Min.z < v.z && v.z < m_Max.z;
+ }
+
+ inline bool Contains(const bb& b)
+ {
+ return Contains(b.m_Min) && Contains(b.m_Max);
+ }
+
+ inline bool Overlap(const bb& rhs)
+ {
+ //check if the boxes overlap in all three axis
+ return ( ( m_Min.x < rhs.m_Min.x && rhs.m_Min.x < rhs.m_Max.x) ||
+ ( m_Min.x < rhs.m_Max.x && rhs.m_Max.x < rhs.m_Max.x) ) &&
+ ( ( m_Min.y < rhs.m_Min.y && rhs.m_Min.y < rhs.m_Max.y) ||
+ ( m_Min.y < rhs.m_Max.y && rhs.m_Max.y < rhs.m_Max.y) ) &&
+ ( ( m_Min.z < rhs.m_Min.z && rhs.m_Min.z < rhs.m_Max.z) ||
+ ( m_Min.z < rhs.m_Max.z && rhs.m_Max.z < rhs.m_Max.z) );
+ }
+
+} BoundingBox_t;
-inline void UpdBBox(BoundingBox_t &B, Vect3D_t &V)
-{
- if (V.x < B.m_dLeft)
- B.m_dLeft = V.x;
- else if (V.x > B.m_dRight)
- B.m_dRight = V.x;
- if (V.y < B.m_dBottom)
- B.m_dBottom = V.y;
- else if (V.y > B.m_dTop)
- B.m_dTop = V.y;
- if (V.z < B.m_dFront)
- B.m_dFront = V.z;
- else if (V.z > B.m_dBack)
- B.m_dBack = V.z;
-};
typedef struct triangle
{