summaryrefslogtreecommitdiffstats
path: root/matchblox/engine/C_MatchBloxEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'matchblox/engine/C_MatchBloxEngine.cpp')
-rw-r--r--matchblox/engine/C_MatchBloxEngine.cpp601
1 files changed, 328 insertions, 273 deletions
diff --git a/matchblox/engine/C_MatchBloxEngine.cpp b/matchblox/engine/C_MatchBloxEngine.cpp
index 93a178f..7dca60d 100644
--- a/matchblox/engine/C_MatchBloxEngine.cpp
+++ b/matchblox/engine/C_MatchBloxEngine.cpp
@@ -7,9 +7,6 @@
#define _USE_MATH_DEFINES
#include <math.h>
-#include "C_MatchBloxEngine.h"
-#include "message_input.h"
-
#include "C_3DObject.h"
#include "C_Environment.h"
#include "C_Hand.h"
@@ -19,7 +16,15 @@
#include "bitmap.h"
#include "message_queue.h"
#include "message_input.h"
+#include "wiimote_utils.h"
+#include "C_Smoother.h"
+#include "C_MatchBloxEngine.h"
+#include "font.h"
+extern "C" {
+extern GLuint g_iBase;
+extern struct BitmapStruct g_sFont;
+}
C_MatchBloxEngine::C_MatchBloxEngine(const char *f_strModelPath,
const char *f_strLogFile,
@@ -50,8 +55,12 @@ C_MatchBloxEngine::C_MatchBloxEngine(const char *f_strModelPath,
m_WorldBox.m_Min = Vect3D_t(-15.0, -5.0, -15.0);
m_WorldBox.m_Max = Vect3D_t(15.0, 15.0, 15.0);
- //m_DotHist.clear();
- //m_DotHistSize = 15;
+ //set smoothers
+ m_pWorldZSmoother[0] = new C_Smoother<double>(0.0);
+ m_pWorldZSmoother[1] = new C_Smoother<double>(0.0);
+
+ m_pWorldZSmoother[0]->SetSimpleMovingAverage(25); //world z coordinate smoother probably lots of lag (but only in z dir)
+ m_pWorldZSmoother[1]->SetExponentialMovingAverage(0.8);
}
C_MatchBloxEngine::~C_MatchBloxEngine()
@@ -60,13 +69,21 @@ C_MatchBloxEngine::~C_MatchBloxEngine()
//delete models
DeleteModels();
+
+ delete m_pWorldZSmoother[0];
+ delete m_pWorldZSmoother[1];
}
GameResult C_MatchBloxEngine::ProcessMsgs(void)
{
struct messageq_s *message;
-
- while (message = messageq_get(MESSAGE_RENDERER))
+ GameResult l_Result = GR_BUSY; //default return value
+
+ //init current time
+ m_uiCurrentTime = glutGet(GLUT_ELAPSED_TIME);
+
+ while ((message = messageq_get(MESSAGE_RENDERER)) &&
+ l_Result == GR_BUSY)
{
switch(message->sender)
{
@@ -75,70 +92,69 @@ GameResult C_MatchBloxEngine::ProcessMsgs(void)
case MESSAGE_INPUT_MOUSE:
break;
case MESSAGE_INPUT_WIIMOTE:
- //get message payload
- //??how to interpret the message payload??
- //wiimote ir dots have a range of 1024x768 in xy which can easily be mapped to world xycoords
- //for the z coordinate: we know the size of the sensorbar, the reach of a human arm is <1m so
- //if we map the initial z distance (in mm) -iz- (taken in ES_GET_READY) to be 0 and -z to be iz - 250mm
- //and +z to be iz + 250 mm we have 3d input!!
- //process button presses
-
- //process ir data
input_payload_wiimote *l_pMsg;
l_pMsg = (input_payload_wiimote*)message->payload;
-
- //for(int i=0; i<4; i++)
+ switch (m_State)
{
- if (l_pMsg->btns && WIIMOTE_BUTTON_A)
+ case ES_GET_READY:
+ if (l_pMsg->btns & WIIMOTE_BUTTON_A &&
+ l_pMsg->btns & WIIMOTE_BUTTON_B &&
+ l_pMsg->posDataValid)
{
- //init depth
- Vect3D_t l_relPos;
- if (CalcWiimoteRelativeCursorPos(l_pMsg, &l_relPos))
- {
- m_dInitialWiimoteDist = l_relPos.z;
- }
- else
+ //the 3d mouse position data is valid and A+B are pressed
+ //init the z depth and start the game
+ m_dInitialWiimoteDist = l_pMsg->Zdist;
+ if (!StartGame())
{
- m_dInitialWiimoteDist = 500.0;
+ l_Result = GR_ERROR;
}
}
- else
+ break;
+
+ case ES_FINISHED:
+ if (l_pMsg->btns & WIIMOTE_BUTTON_ALL)
{
+ //any button is pressed
+ //delete session and return GAME_FINISHED
+ delete m_pCurrentSession;
+ l_Result = GR_FINISHED;
+ }
+ break;
+
+ default:
+ if (l_pMsg->posDataValid)
+ {
+ m_uiLastPosValid = m_uiCurrentTime;
Vect3D_t l_WorldPos;
+ if (l_pMsg->btns & WIIMOTE_BUTTON_A)
+ {
+ int i = 0; //debug break
+ }
+
if (ConvertWiimoteToWorld(l_pMsg, &l_WorldPos))
{
- m_pBlock[0]->SetPos(l_WorldPos);
+ CursorMove(l_WorldPos);
}
}
-
- //std::cout << "Dot["<<i<<"] ("<< l_pMsg->Dot[i].RawX <<","<< l_pMsg->Dot[i].RawY <<")\n";
+ break;
}
-
- //if (m_State == ES_GET_READY)
- //{
- // //if player has pressed the A button
- // //take the initial z distance
-
- // //perhaps we should do a countdown 3.. 2.. 1.. GO! but this requires another engine state
- //}
- //if (m_State == ES_PLAYING_GRAB_BLOCK || m_State == ES_PLAYING_PUT_BLOCK)
- //{
- // //convert ir data to cursor pos in world coordinates
-
- // Vect3D_t tmpPos(l_pMsg->x, l_pMsg->y, l_pMsg->z);
- // CursorMove(tmpPos);
- //}
+
break;
default:
std::cout << "Undefined message! Sender: " << message->sender << std::endl;
+ //l_Result = GR_ERROR;
}
}
- return GR_BUSY;
+ return l_Result;
}
-void C_MatchBloxEngine::Render_Basics(unsigned int f_uiElapsedTime)
+
+void C_MatchBloxEngine::Render(unsigned int f_uiElapsedTime)
{
+ //glMatrixMode(GL_MODELVIEW);
+ //glLoadIdentity();
+
glPushMatrix();
//set camera pitch
@@ -151,69 +167,129 @@ void C_MatchBloxEngine::Render_Basics(unsigned int f_uiElapsedTime)
glPushMatrix();
-
//move the camera backwards
glTranslated(0.0, 0.0, -16.0);
glRotated(20.0, 1.0, 0.0, 0.0);
-
-
-
- //if (m_pCurrentSession)
- //{
- m_pBox[(int)m_CurrentBox]->Render();
- m_pBlock[0]->Render(f_uiElapsedTime);
- /* for (int i=0; i<4; i++)
- m_pBlock[i]->Render(f_uiElapsedTime);*/
- // m_pHand->Render(f_uiElapsedTime);
- //}
-
- glPopMatrix();
-}
+ m_pBox[(int)m_CurrentBox]->Render();
-void C_MatchBloxEngine::Render(unsigned int f_uiElapsedTime)
-{
switch (m_State)
{
case ES_INITIALISED:
- Render_Basics(f_uiElapsedTime);
- break;
-
case ES_ERROR:
- //render a red cube
- glPushMatrix();
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_LIGHTING);
- glColor3d(1.0, 0.0, 0.0);
- glTranslated(0.0, 0.0, -5.0);
- glutSolidCube(5.0);
- glPopAttrib();
- glPopMatrix();
+ m_pHand->Render(f_uiElapsedTime);
break;
case ES_GET_READY:
- Render_Basics(f_uiElapsedTime);
//render some GET READY text
+ RenderGetReady();
break;
case ES_PLAYING_GRAB_BLOCK:
- Render_Basics(f_uiElapsedTime);
- break;
-
case ES_PLAYING_PUT_BLOCK:
- Render_Basics(f_uiElapsedTime);
+ m_pBlock[(int)m_CurrentBlock]->Render(f_uiElapsedTime);
+ m_pHand->Render(f_uiElapsedTime);
+
+ //render timer and block count
+ RenderHUD(f_uiElapsedTime);
break;
case ES_PAUSED:
- Render_Basics(f_uiElapsedTime);
- //render menu??
break;
case ES_FINISHED:
+ RenderResults();
//render results...
break;
}
+ if (f_uiElapsedTime - m_uiLastPosValid > 5000)
+ {
+ RenderPointHere();
+ }
+
+ glPopMatrix();
+
+}
+
+void C_MatchBloxEngine::RenderGetReady()
+{
+ ColorStruct l_TextCol = {0.0, 0.3, 1.0};
+ int w = glutGet(GLUT_WINDOW_WIDTH),
+ h = glutGet(GLUT_WINDOW_HEIGHT);
+
+ RenderText((w/2)-(9*32), (h/2)-16, "Press A+B to begin.", l_TextCol);
+}
+
+void C_MatchBloxEngine::RenderHUD(unsigned int f_uiElapsedTime)
+{
+ ColorStruct l_TextCol = {0.0, 0.3, 1.0};
+ std::stringstream l_ss;
+ unsigned l_uiTime = f_uiElapsedTime - m_pCurrentSession->m_uiSessionStart;
+
+ int l_iMSecs = l_uiTime % 1000;
+ l_uiTime /= 1000;
+ int l_iSecs = l_uiTime % 60;
+ l_uiTime /= 60;
+ int l_iMins = l_uiTime % 60;
+
+ l_ss << "Block " << m_pCurrentSession->m_iCurrentTurn << "/" << m_pCurrentSession->m_iTotalTurns
+ << " Time: " << setw(2) << setfill('0') << l_iMins << ":" << setw(2) << l_iSecs
+ << "." << l_iMSecs;
+
+ RenderText(32, 16, (char*)l_ss.str().c_str(), l_TextCol);
+}
+
+void C_MatchBloxEngine::RenderResults()
+{
+ ColorStruct l_TextCol = {0.0, 0.3, 1.0};
+ RenderText(32, 64, "YOU SUCK!", l_TextCol);
+}
+
+void C_MatchBloxEngine::RenderPointHere()
+{
+ ColorStruct l_TextCol = {0.0, 0.3, 1.0};
+ int w = glutGet(GLUT_WINDOW_WIDTH),
+ h = glutGet(GLUT_WINDOW_HEIGHT);
+
+ RenderText((w/2)-(6*32), (h/4), "Point >o< here!", l_TextCol);
+}
+
+void C_MatchBloxEngine::RenderText(GLint x, GLint y, char *string, struct ColorStruct f_sColor)
+{
+ glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+ glDisable(GL_DEPTH_TEST);
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, g_sFont.m_iImageId);
+ glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glColor3d(f_sColor.m_dRed, f_sColor.m_dGreen, f_sColor.m_dBlue);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix(); //push modelview matrix
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix(); //push projection matrix
+
+ glLoadIdentity();
+ glOrtho(0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT), 0, 0, 1);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glTranslated(x, y, 0);
+ glListBase(g_iBase - 32);
+ glCallLists((GLsizei)strlen(string), GL_UNSIGNED_BYTE, string);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix(); //pop projection matrix
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix(); //pop modelview matrix
+
+ glPopAttrib();
}
bool C_MatchBloxEngine::NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS)
@@ -241,13 +317,8 @@ bool C_MatchBloxEngine::StartGame()
{
if (m_State == ES_GET_READY)
{
- //start the session timer
- m_CurrentBlock = m_pCurrentSession->StartSession();
-
- //move a block into the sky
- m_pBlock[(int)m_CurrentBlock ]->SetPos(0.0, 0.0, 15.0);
-
- m_State = ES_PLAYING_GRAB_BLOCK;
+ //start the game session
+ NewBlock();
return true;
}
@@ -353,7 +424,9 @@ bool C_MatchBloxEngine::LoadModels(const char* f_strModelDir)
//load the hand???
-
+ l_Mat.setAmb(1.0, 1.0, 1.0, 1.0);
+ l_Mat.setDif(1.0, 1.0, 1.0, 1.0);
+ m_pHand = new C_Hand("", 0, l_Mat);
//Load the box tiles
l_Mat.setAmb(1.0, 1.0, 1.0, 1.0);
@@ -437,245 +510,227 @@ 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
+ 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;
+ //translate the bounding box of the block with the cursor position
+ l_bCollision = CursorMove_PutBlock(f_NewCursorPos);
break;
default:
//cursor is the hand object
- l_CursBBox = m_pHand->GetBoundingBox() + f_NewCursorPos;
+ l_bCollision = CursorMove_GrabBlock(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))
+ if (l_bCollision)
{
- //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;
+ //send a rumble message and set collision animation state
+ //message_send()
}
- else
+}
+
+bool C_MatchBloxEngine::CursorMove_GrabBlock(Vect3D_t &f_NewCursorPos)
+{
+ BoundingBox_t l_HandBB = m_pHand->GetBoundingBox() + f_NewCursorPos;
+
+ if (m_WorldBox.Contains(l_HandBB))
{
- //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))
+ if (m_State == ES_PLAYING_GRAB_BLOCK)
{
- //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)
+ //check for overlap with the current block
+ if (m_pBlock[(int)m_CurrentBlock]->GetAbsBoundBox().Overlap(l_HandBB))
{
-
+ //grabbing the block
+ 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;
+ m_pHand->SetState(HS_GRAB, m_uiCurrentTime);
+
+ m_pBlock[(int)m_CurrentBlock]->SetPos(f_NewCursorPos);
}
}
- }
+
+ //set the new position
+ m_pHand->SetPos(f_NewCursorPos);
+ return false;
+ }
+ else
+ {
+ //the cursor is leaving the world box, which is a collision
+ m_pHand->SetState(HS_COLLIDE, m_uiCurrentTime);
+ return true; //true == collision
+ }
}
-//bool C_MatchBloxEngine::CursorMove_PutBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CursBBox)
-//{
-// //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
-// bool l_bCollision = false;
-// 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_pCurrentSession->NewTurn();
-//
-// //m_GameState
-// }
-//
-//
-//
-// }
-//
-// return false;
-//}
-
-//bool C_MatchBloxEngine::CursorMove_GrabBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CursBBox)
-//{
-// //grabbing a block: just check for bounding box intersection
-// if (m_pBlock[(int)m_CurrentBlock]->GetAbsBoundBox().Overlap(f_CursBBox))
-// {
-//
-// }
-// return true;
-//}
-
-
-bool C_MatchBloxEngine::FindIRDots(input_payload_wiimote *f_pWiimote, ir_dot_t f_Dot[2])
+bool C_MatchBloxEngine::CursorMove_PutBlock(Vect3D_t &f_NewCursorPos)
{
- //find the pair of ir dots with the largest squared distance
- int mdist = 0, //max length
- dist2,dx,dy,
- dot0, dot1;
-
- //loop through all combinations
- for(int i = 0; i < 4; i++)
+ bool l_bCollision;
+ BoundingBox_t l_BlockBB = m_pBlock[(int)m_CurrentBlock]->GetBoundingBox() + f_NewCursorPos,
+ l_TileBB = m_pTiles[(int)m_CurrentBlock]->GetAbsBoundBox() + m_pBox[(int)m_CurrentBox]->GetPos();
+
+ if (m_WorldBox.Contains(l_BlockBB))
{
- for (int j = i+1; j < 4; j++)
+ //check for overlap with the block box
+ if (m_pBox[(int)m_CurrentBox]->GetAbsBoundBox().Overlap(l_BlockBB))
{
- //check if the ir dots are found
- if (f_pWiimote->ir.dot[i].visible &&
- f_pWiimote->ir.dot[j].visible)
+ //check for overlap with the target hole tile
+ if (l_TileBB.Overlap(l_BlockBB))
{
- //compute the squared distance
- dx = f_pWiimote->ir.dot[i].rx - f_pWiimote->ir.dot[j].rx;
- dy = f_pWiimote->ir.dot[i].ry - f_pWiimote->ir.dot[j].ry;
- dist2 = dx*dx + dy*dy;
-
- if (dist2 > mdist)
+ Vect3D_t l_AbsHolePos = m_pBox[m_CurrentBox]->GetPos() +
+ m_pTiles[m_CurrentBlock]->GetPos();
+ Vect3D_t l_PosDif = l_AbsHolePos - m_pBlock[(int)m_CurrentBlock]->GetPos();
+ double l_dXZProximity = l_PosDif.x * l_PosDif.x +
+ l_PosDif.y * l_PosDif.y;
+ cout << "Block proximety: " << l_dXZProximity << endl;
+
+ if (l_dXZProximity < m_GameSettings.m_dMinProximity)
+ {
+ //we have a winner
+ l_bCollision = false;
+ NewBlock();
+ }
+ else
{
- mdist = dist2;
- dot0 = i;
- dot1 = j;
- //std::cout << "(" << i << "," << j <<") " << mdist << std::endl;
+ l_bCollision = true;
}
}
- }
- }
-
- if (mdist > 0)
- {
- std::cout << "Winner - (" << dot0 << "," << dot1 <<") " << mdist << " numdots: " << (int)f_pWiimote->ir.num_dots << std::endl;
- //left down is f_Dot[0]
- if (f_pWiimote->ir.dot[dot0].rx < f_pWiimote->ir.dot[dot1].ry ||
- (f_pWiimote->ir.dot[dot0].rx == f_pWiimote->ir.dot[dot1].ry &&
- f_pWiimote->ir.dot[dot0].rx < f_pWiimote->ir.dot[dot1].ry))
- {
- f_Dot[0] = f_pWiimote->ir.dot[dot0];
- f_Dot[1] = f_pWiimote->ir.dot[dot1];
+ else
+ {
+ //overlap with the block box but not with the correct tile
+ l_bCollision = true;
+ }
}
else
{
- f_Dot[0] = f_pWiimote->ir.dot[dot1];
- f_Dot[1] = f_pWiimote->ir.dot[dot0];
+ //inside the world box and not overlapping the block box
+ l_bCollision = false;
}
-
- return true;
}
else
{
- //std::cout << "nothing...\n";
- return false;
+ //leaving the world box
+ l_bCollision = true;
}
-}
+ if (l_bCollision)
+ {
+ m_pBlock[(int)m_CurrentBlock]->SetState(BS_COLLIDE, m_uiCurrentTime);
+ }
+ else
+ {
+ if (m_State == ES_PLAYING_PUT_BLOCK)
+ {
+ m_pBlock[(int)m_CurrentBlock]->SetPos(f_NewCursorPos);
+ }
+ }
-bool C_MatchBloxEngine::CalcWiimoteRelativeCursorPos(input_payload_wiimote *f_pWiimote, Vect3D_t *f_pRelPos)
-{
- //get two ir dots
- ir_dot_t l_Dot[2];
+ //allways set mouse pointer position
+ m_pHand->SetPos(f_NewCursorPos);
- if (!FindIRDots(f_pWiimote, l_Dot))
- return false;
+ return l_bCollision;
+}
+
+bool C_MatchBloxEngine::Check_PutBlock(Vect3D_t &f_CursPos, BoundingBox_t &f_CursBBox)
+{
+ //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;
+ BoundingBox_t l_HoleBBox = m_pTiles[m_CurrentBlock]->GetAbsBoundBox() + m_pBox[m_CurrentBox]->GetPos();
+
+ //first check if the block is being put in the right tile with
+ //the right xz-proximity
+ if (l_HoleBBox.Overlap(f_CursBBox) &&
+ l_dXZProximity < m_GameSettings.m_dMinProximity)
+ {
+ //check if the block is deep enough inside the box to count as a point
+ if (l_PosDif.z > m_GameSettings.m_dHoleDepth)
+ {
+ //yipee!! we have got a winner!!
+ if (m_pCurrentSession->NextTurn(m_CurrentBlock))
+ {
+ NewBlock();
+ }
+ else
+ {
+ GameFinished();
+ }
+ return true;
+ }
- //dotpair l_dp(l_Dot[0], l_Dot[1]);
- //m_DotHist.push_front(l_dp);
- //if (m_DotHist.size() > m_DotHistSize)
- // m_DotHist.pop_back();
-
- ////calculate the average dots
- //l_Dot[0].RawX = l_Dot[0].RawY = l_Dot[1].RawX = l_Dot[1].RawY = 0;
- //for(list<dotpair>::iterator it = m_DotHist.begin(); it != m_DotHist.end(); it++)
- //{
- // l_Dot[0].RawX += it->first.RawX; l_Dot[0].RawY += it->first.RawY;
- // l_Dot[1].RawX += it->second.RawX; l_Dot[1].RawY += it->second.RawY;
- //}
- //l_Dot[0].RawX /= (double)m_DotHist.size(); l_Dot[0].RawY /= (double)m_DotHist.size();
- //l_Dot[1].RawX /= (double)m_DotHist.size(); l_Dot[1].RawY /= (double)m_DotHist.size();
-
-
- //invert the x and y axis
- l_Dot[0].rx = 1016 - l_Dot[0].ry;
- l_Dot[1].rx = 1016 - l_Dot[1].ry;
- l_Dot[0].rx = 760 - l_Dot[0].ry;
- l_Dot[1].rx = 760 - l_Dot[1].ry;
-
- double l_dX = (double)l_Dot[0].rx - l_Dot[1].rx, //difference in x coordinates
- l_dY = (double)l_Dot[0].ry - l_Dot[1].ry, //difference in y coordinates
- l_dDotDist = sqrt(l_dX*l_dX + l_dY*l_dY), //distance between ir dots (in camera pixels)
- l_dRadPerPixel = ( 41.0 * (M_PI/180.0) ) /1016.0, //radians per camera pixel: x view angel = 41 deg, 1016 pixels
- l_dDotAngle = l_dRadPerPixel * l_dDotDist; //the angle between the lines from the camera through the two
- //ir dots (in radians)
-
- f_pRelPos->x = (double)(l_Dot[0].rx + l_Dot[1].rx)/2.0; //camera x coordinate [0,1016]
- f_pRelPos->y = (double)(l_Dot[0].ry + l_Dot[1].ry)/2.0; //camera y coordinate [0,760]
- f_pRelPos->z = (0.5 * 205.0) / tan(0.5 * l_dDotAngle); //the distance between the sensorbar and wiimote (in mm)
- //std::cout << "(" << f_pRelPos->x << "," << f_pRelPos->y << "," << f_pRelPos->z << ")\n";
+ //not a win but also no collison -> set the position
+ m_pBlock[(int)m_CurrentBlock]->SetPos(f_CursPos);
+ return true;
+ }
- return true;
+ return false;
}
-bool C_MatchBloxEngine::ConvertWiimoteToWorld(input_payload_wiimote *f_pWiimote, Vect3D_t *f_pWorldPos)
-{
- Vect3D_t l_RelPos;
- if (!CalcWiimoteRelativeCursorPos(f_pWiimote, &l_RelPos))
+bool C_MatchBloxEngine::ConvertWiimoteToWorld(input_payload_wiimote *f_pWiimoteMsg, Vect3D_t *f_pWorldPos)
+{
+ if (!f_pWiimoteMsg->posDataValid)
+ {
return false;
+ }
+
+ Vect3D_t l_RelPos(f_pWiimoteMsg->relX, f_pWiimoteMsg->relY, f_pWiimoteMsg->Zdist);
//use the world bounding box dimensions to convert the relative position to world coordinates
- //z is in mm, cap it to 250mm from the initial wiimote distance
+ //z is in mm, cap it to 500mm from the initial wiimote distance
//using the initial distance
- l_RelPos.z = l_RelPos.z - m_dInitialWiimoteDist + 250;
+ l_RelPos.z = (l_RelPos.z - m_dInitialWiimoteDist + 500.0) / 1000.0;
if (l_RelPos.z < 0.0) l_RelPos.z = 0.0;
- else if (l_RelPos.z > 500.0) l_RelPos.z = 500.0;
+ else if (l_RelPos.z > 1.0) l_RelPos.z = 1.0;
- //Vect3D_t l_WorldSize(m_WorldBox.m_Max - m_WorldBox.m_Min);
- Vect3D_t l_WorldSize;
- l_WorldSize.x = m_WorldBox.m_Max.x - m_WorldBox.m_Min.x;
- l_WorldSize.y = m_WorldBox.m_Max.y - m_WorldBox.m_Min.y;
- l_WorldSize.z = m_WorldBox.m_Max.z - m_WorldBox.m_Min.z;
+ Vect3D_t l_WorldSize = m_WorldBox.m_Max - m_WorldBox.m_Min;
+
+ *f_pWorldPos = m_WorldBox.m_Min + (l_RelPos * l_WorldSize);
- f_pWorldPos->x = m_WorldBox.m_Min.x + ((l_RelPos.x * l_WorldSize.x)/1016.0); //1016 pixels in x
- f_pWorldPos->y = m_WorldBox.m_Min.y + ((l_RelPos.y * l_WorldSize.y)/ 760.0); // 769 pixels in y
- f_pWorldPos->z = m_WorldBox.m_Min.z + ((l_RelPos.z * l_WorldSize.z)/ 500.0);// 500 mm in z
+ //cout << "Z_world: " << std::fixed << std::setprecision(2) << setw(10) << left << f_pWorldPos->z;
- //std::cout << "(" << f_pWorldPos->x << "," << f_pWorldPos->y << "," << f_pWorldPos->z << ")\n";
+ //smooth the world z coordinate in two passes (first average the last 25 samples)
+ //and then smooth exponentially over the averages
+ f_pWorldPos->z = m_pWorldZSmoother[0]->Smooth(f_pWorldPos->z);
+ f_pWorldPos->z = m_pWorldZSmoother[1]->Smooth(f_pWorldPos->z);
+ //cout << "Z_world_smoof: " << std::fixed << std::setprecision(2) << left << f_pWorldPos->z << endl;
return true;
+}
+
+void C_MatchBloxEngine::NewBlock()
+{
+ if (m_pCurrentSession->NextTurn(m_CurrentBlock))
+ {
+ //move a block into the sky
+ m_pBlock[(int)m_CurrentBlock ]->SetPos(0.0, 10.0, 0.0);
+
+ m_State = ES_PLAYING_GRAB_BLOCK;
+ }
+ else
+ {
+ m_State = ES_FINISHED;
+ }
+}
+
+void C_MatchBloxEngine::GameFinished()
+{
+
+
+ //save session results to database
} \ No newline at end of file