[DEV] add camera system on the game engine

This commit is contained in:
Edouard DUPIN 2012-12-18 23:16:40 +01:00
parent 326dccb94d
commit 10f7131b62
13 changed files with 222 additions and 56 deletions

2
external/etk vendored

@ -1 +1 @@
Subproject commit df8a54b55a24afbbda666956ca729f404381945c
Subproject commit e3890a6c1471e393ba39cc431e3d1f62de0280b8

View File

@ -0,0 +1,43 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ewol/game/Camera.h>
#include <ewol/debug.h>
void game::Camera::Update(void)
{
m_matrix.Identity();
//m_matrix.Rotate(vec3(0,0,1), M_PI/2.0 );
//m_matrix.Rotate(vec3(0,1,0), M_PI/2.0 );
m_matrix.Rotate(vec3(1,0,0), m_angles.x );
m_matrix.Rotate(vec3(0,1,0), m_angles.y );
m_matrix.Rotate(vec3(0,0,1), m_angles.z );
m_matrix.Translate(m_position);
EWOL_DEBUG("camera: pos=" << m_position << " angle=" << m_angles);
}
game::Camera::Camera(vec3 pos, vec3 angles) :
m_position(pos),
m_angles(angles)
{
Update();
}
void game::Camera::SetPosition(vec3 pos)
{
m_position = pos;
Update();
}
void game::Camera::SetAngle(vec3 angles)
{
m_angles = angles;
Update();
}

View File

@ -0,0 +1,65 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __GAME_CAMERA_H__
#define __GAME_CAMERA_H__
#include <etk/types.h>
#include <etk/math/Vector3D.h>
#include <etk/math/Matrix4.h>
namespace game
{
class Camera
{
private:
vec3 m_position; //!< position of the camera.
vec3 m_angles; //!< Angles to the camera is seing.
mat4 m_matrix; //!< transformation matrix.
/**
* @brief Update the matrix property
*/
void Update(void);
public:
/**
* @brief Constructor.
* @param[in] pos Position of the camera.
* @param[in] angles Rotations angles of the camera
*/
Camera(vec3 pos=vec3(0,0,1), vec3 angles=vec3(0,0,0));/**
* @brief Set the position of the camera.
* @param[in] pos Position of the camera.
*/
void SetPosition(vec3 pos);
/**
* @brief Get the curent Camera position.
* @return the current position.
*/
vec3& GetPosition(void) { return m_position; };
/**
* @brief Set the angle on the camera
* @param[in] angles Rotations angles of the camera
*/
void SetAngle(vec3 angles);
/**
* @brief Get the curent Camera angles.
* @return the current angles.
*/
vec3& GetAngle(void) { return m_angles; };
/**
* @brief Get the transformation matix for the camera.
* @return the current transformation matrix
*/
mat4& GetMatrix(void) { return m_matrix; };
};
};
#endif

View File

@ -32,7 +32,7 @@ game::Element::Element(etk::UString meshResource) :
Scale(vec3(100,100,100) );
//m_property.Rotate(m_property.m_angle, rotx);
Translate(vec3(0.01,0.0,0.0));
//Translate(vec3(0.01,0.0,0.0));
}
game::Element::~Element(void)
@ -83,18 +83,14 @@ void game::Element::ProcessGravity(float delta, game::Gravity& gravity)
}
}
void game::Element::ProcessSpeed(float delta)
{
vec3 curentAcceleration = m_gravityForce + m_userAcceleration;
m_speed += curentAcceleration*delta;
}
void game::Element::ProcessPosition(float delta)
{
if (m_speed != vec3(0,0,0)) {
m_position += m_speed*delta;
m_matrixNeedUpdate = true;
//EWOL_DEBUG("modify m_position=" << m_position << "m m_speed=" << m_speed << "m/s m_gravityForce=" << m_gravityForce << "+" << m_userAcceleration << "m/s2");
}
vec3 m_speed0(m_speed);
vec3 curentAcceleration(m_gravityForce + m_userAcceleration);
m_speed += curentAcceleration*delta;
m_position += m_speed0*delta + curentAcceleration*delta*delta/2.0f ;
m_matrixNeedUpdate = true;
//EWOL_DEBUG("modify m_position=" << m_position << "m m_speed=" << m_speed << "m/s m_gravityForce=" << m_gravityForce << "+" << m_userAcceleration << "m/s2");
}

View File

@ -73,11 +73,6 @@ namespace game
* @param[in] gravity reference on all the gravity point.
*/
virtual void ProcessGravity(float delta, game::Gravity& gravity);
/**
* @brief Update the speed of the curent element
* @param[in] delta delta from the last call.
*/
virtual void ProcessSpeed(float delta);
/**
* @brief Update the position of the element
* @param[in] delta delta from the last call.
@ -136,6 +131,10 @@ namespace game
}
return m_matrix;
};
void SetSpeed(vec3 newSpeed)
{
m_speed = newSpeed;
}
};
};

View File

@ -51,14 +51,12 @@ void game::Engine::ProcessGravity(float deltaTime)
if (NULL != m_elementsStatic[iii]) {
m_elementsStatic[iii]->ProcessGravity(deltaTime, m_gravity[jjj]);
}
m_elementsStatic[iii]->ProcessSpeed(deltaTime);
m_elementsStatic[iii]->ProcessPosition(deltaTime);
}
for (int32_t iii=0; iii<m_elementsDynamic.Size() ; iii++) {
if (NULL != m_elementsDynamic[iii]) {
m_elementsDynamic[iii]->ProcessGravity(deltaTime, m_gravity[jjj]);
}
m_elementsDynamic[iii]->ProcessSpeed(deltaTime);
m_elementsDynamic[iii]->ProcessPosition(deltaTime);
}
}

View File

@ -36,11 +36,11 @@ extern const float game::GravityConst = 0.0000000000667f;
// Earth
extern const float game::earthMass = 5973600000000000000000000.0f; // in kg
extern const float game::earthRadius = 6378137.0f; // in meter
extern const game::Gravity game::gravityEarth(true, earthMass, vec3(0, 0, -(float)((GravityConst*earthMass)/(earthRadius*earthRadius))) );
extern const game::Gravity game::gravityEarth(true, earthMass, vec3(0, -(float)((GravityConst*earthMass)/(earthRadius*earthRadius)), 0) );
// Mars
extern const float game::marsMass = 25000000000000000.0f; // in kg
extern const float game::marsRadius = 3396200.0f; // in meter
extern const game::Gravity game::gravityMars(true, marsMass, vec3(0, 0, -(float)((GravityConst*marsMass)/(marsRadius*marsRadius))) );
extern const game::Gravity game::gravityMars(true, marsMass, vec3(0, -(float)((GravityConst*marsMass)/(marsRadius*marsRadius)), 0) );

View File

@ -17,11 +17,13 @@
widget::Scene::Scene(game::Engine* gameEngine) :
m_gameEngine(gameEngine),
m_isRunning(true),
m_lastCallTime(-1)
m_lastCallTime(-1),
modeMoving(0)
{
SetCanHaveFocus(true);
PeriodicCallSet(true);
m_zoom = 1.0/1000.0;
m_ratioTime = 1.0f;
}
@ -72,6 +74,12 @@ void widget::Scene::OnDraw(ewol::DrawProperty& displayProp)
void widget::Scene::PeriodicCall(int64_t localTime)
{
double curentTime=(double)localTime/1000000.0;
// small hack to change speed ...
if (m_ratioTime != 1) {
double ellapseTime = curentTime - m_lastCallTime;
ellapseTime *= m_ratioTime;
m_lastCallTime = curentTime - ellapseTime;
}
// First time :
if (-1 == m_lastCallTime) {
m_lastCallTime = curentTime;
@ -104,28 +112,21 @@ void widget::Scene::GenDraw(ewol::DrawProperty displayProp)
m_size.x,
m_size.y);
float ratio = m_size.x / m_size.y;
if (false) {
mat4 tmpTranslate = etk::matTranslate(vec3(-m_size.x/2, -m_size.y/2, -1.0f));
mat4 tmpScale = etk::matScale(vec3(m_zoom, m_zoom, 1.0f));
mat4 tmpProjection = etk::matPerspective(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpMat = tmpProjection * tmpScale * tmpTranslate;
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);
//EWOL_INFO("ratio : " << ratio);
mat4 tmpProjection;// = etk::matPerspective( M_PI/2.0, ratio, -1, 1);
if (ratio >= 1.0) {
tmpProjection = etk::matOrtho(-ratio, ratio, -1, 1, -1, 1);
} else {
//EWOL_INFO("ratio : " << ratio);
mat4 tmpProjection;
if (ratio >= 1.0) {
tmpProjection = etk::matPerspective(-ratio, ratio, -1, 1, -1, 1);
} else {
ratio = 1.0/ratio;
tmpProjection = etk::matPerspective(-1, 1, -ratio, ratio, -1, 1);
}
mat4 tmpScale = etk::matScale(vec3(m_zoom, m_zoom, m_zoom) );
mat4 tmpMat = tmpProjection * tmpScale;
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);
ratio = 1.0/ratio;
tmpProjection = etk::matOrtho(-1, 1, -ratio, ratio, -1, 1);
}
mat4 tmpScale = etk::matScale(vec3(m_zoom, m_zoom, m_zoom) );
mat4 tmpMat = tmpProjection * tmpScale * m_camera.GetMatrix();
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);
// Call the widget drawing methode
displayProp.m_origin = m_origin;
displayProp.m_size = m_size;
@ -177,6 +178,35 @@ bool widget::Scene::OnEventInput(ewol::keyEvent::type_te type, int32_t IdInput,
m_zoom *= 0.91;
} else if (5 == IdInput && ewol::keyEvent::statusUp == statusEvent) {
m_zoom *= 1.1;
} else if (1 == IdInput) {
if(modeMoving==1 && ewol::keyEvent::statusUp == statusEvent) {
modeMoving = 0;
} else if (modeMoving==0 && ewol::keyEvent::statusDown == statusEvent) {
modeMoving = 1;
oldCursorPos = relativePos;
} else if (modeMoving==1 && ewol::keyEvent::statusMove == statusEvent) {
vec2 offset = relativePos - oldCursorPos;
vec3 oldPos = m_camera.GetPosition();
oldPos.x += offset.x;
oldPos.y += offset.y;
m_camera.SetPosition(oldPos);
oldCursorPos = relativePos;
}
} else if (3 == IdInput) {
if(modeMoving==3 && ewol::keyEvent::statusUp == statusEvent) {
modeMoving = 0;
} else if (modeMoving==0 && ewol::keyEvent::statusDown == statusEvent) {
modeMoving = 3;
oldCursorPos = relativePos;
} else if (modeMoving==3 && ewol::keyEvent::statusMove == statusEvent) {
vec2 offset = relativePos - oldCursorPos;
offset *= M_PI/(360.0f*6);
vec3 oldAngles = m_camera.GetAngle();
oldAngles.x -= offset.y;
oldAngles.y += offset.x;
m_camera.SetAngle(oldAngles);
oldCursorPos = relativePos;
}
}
} else if (type == ewol::keyEvent::typeFinger) {

View File

@ -15,6 +15,7 @@
#include <ewol/debug.h>
#include <ewol/game/Engine.h>
#include <ewol/game/Element.h>
#include <ewol/game/Camera.h>
#include <ewol/widget/Widget.h>
@ -22,9 +23,11 @@ namespace widget {
class Scene :public ewol::Widget
{
protected:
game::Camera m_camera; //!< Display point of view
game::Engine* m_gameEngine; //!< display engine system
bool m_isRunning; //!< the display is running (not in pause)
double m_lastCallTime; //!< previous call Time
float m_ratioTime; //!< Ratio time for the speed of the game ...
public:
/**
* @brief Main scene constructor
@ -55,18 +58,18 @@ namespace widget {
virtual void ScenePeriodicCall(int64_t localTime, int32_t deltaTime) { };
// camera properties :
private:
vec3 m_camRotation;
vec3 m_camTranslation;
float m_camAngleView;
float m_camdistanceViewStart;
float m_camdistanceViewStop;
float m_zoom;
int32_t modeMoving;
vec2 oldCursorPos;
public:
void SetCamaraTranslation();
void SetCamaraRotation();
void SetCamaraAngleView();
void SetCamaraDistanceViewStart();
void SetCamaraDistanceViewStop();
/**
* @brief Get the current camera reference for the scene rendering
*/
game::Camera& GetCamera(void) { return m_camera; };
/**
* @brief Set the curent Time Ratio (default 1)
*/
void SetRatioTime(float newRatio) { m_ratioTime = newRatio; };
/**
* @brief Convert the absolute position in the local Position (Relative)
* @param[in] pos Absolute position that you request convertion

View File

@ -139,7 +139,7 @@ void ewol::Widget::GenDraw(DrawProperty displayProp)
m_size.y);
mat4 tmpTranslate = etk::matTranslate(vec3((float)(-tmpclipX/2 - (tmpOriginX-m_origin.x)), (float)(-m_size.y/2.0), -1.0f));
mat4 tmpScale = etk::matScale(vec3(m_zoom, m_zoom, 1.0f));
mat4 tmpProjection = etk::matPerspective(-tmpclipX/2, tmpclipX/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpProjection = etk::matOrtho(-tmpclipX/2, tmpclipX/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpMat = tmpProjection * tmpScale * tmpTranslate;
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);
@ -156,7 +156,7 @@ void ewol::Widget::GenDraw(DrawProperty displayProp)
m_size.y);
mat4 tmpTranslate = etk::matTranslate(vec3(-m_size.x/2, -m_size.y/2, -1.0f));
mat4 tmpScale = etk::matScale(vec3(m_zoom, m_zoom, 1.0f));
mat4 tmpProjection = etk::matPerspective(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpProjection = etk::matOrtho(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpMat = tmpProjection * tmpScale * tmpTranslate;
// set internal matrix system :
ewol::openGL::SetMatrix(tmpMat);

View File

@ -351,7 +351,7 @@ void widget::WidgetScrooled::GenDraw(ewol::DrawProperty displayProp)
m_origin.y,
m_size.x,
m_size.y);
mat4 tmpProjection = etk::matPerspective(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpProjection = etk::matOrtho(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpScale = etk::matScale(vec3(m_zoom, m_zoom, 1.0) );
mat4 tmpTranslate = etk::matTranslate(vec3(-m_maxSize.x/2, -m_maxSize.y/2, -1.0) );
mat4 tmpMat = tmpProjection * tmpScale * tmpTranslate;
@ -366,7 +366,7 @@ void widget::WidgetScrooled::GenDraw(ewol::DrawProperty displayProp)
m_size.x,
m_size.y);
mat4 tmpProjection = etk::matPerspective(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpProjection = etk::matOrtho(-m_size.x/2, m_size.x/2, -m_size.y/2, m_size.y/2, -1, 1);
mat4 tmpTranslate = etk::matTranslate(vec3( -m_maxSize.x/2, -m_maxSize.y/2, -1.0) );
mat4 tmpMat = tmpProjection * tmpTranslate;
// set internal matrix system :

View File

@ -89,6 +89,7 @@ FILE_LIST+= ewol/widget/Scene.cpp \
ewol/game/BoundingSphere.cpp \
ewol/game/Geometry.cpp \
ewol/game/Gravity.cpp \
ewol/game/Camera.cpp \
ewol/game/Map.cpp \
ewol/game/Mass.cpp \
ewol/game/Sky.cpp

View File

@ -32,6 +32,9 @@ static const char * l_eventRotationX = "event-rotation-X";
static const char * l_eventRotationY = "event-rotation-Y";
static const char * l_eventRotationZ = "event-rotation-Z";
static const char * l_eventLunch = "event-lunch";
static const char * l_eventChangeTimeSpeed2 = "event-speed2";
static const char * l_eventChangeTimeSpeed0 = "event-speed0.5";
static const char * l_eventChangeTimeSpeed1 = "event-speed1";
@ -82,6 +85,21 @@ TestScene::TestScene(void)
myButton->RegisterOnEvent(this, ewolEventButtonPressed, l_eventLunch);
mySizerHori->SubWidgetAdd(myButton);
}
myButton = new widget::Button("1x speed");
if (NULL != myButton) {
myButton->RegisterOnEvent(this, ewolEventButtonPressed, l_eventChangeTimeSpeed1);
mySizerHori->SubWidgetAdd(myButton);
}
myButton = new widget::Button("0.5x speed");
if (NULL != myButton) {
myButton->RegisterOnEvent(this, ewolEventButtonPressed, l_eventChangeTimeSpeed0);
mySizerHori->SubWidgetAdd(myButton);
}
myButton = new widget::Button("2x speed");
if (NULL != myButton) {
myButton->RegisterOnEvent(this, ewolEventButtonPressed, l_eventChangeTimeSpeed2);
mySizerHori->SubWidgetAdd(myButton);
}
widget::Spacer* mySpacer = new widget::Spacer();
if (NULL != mySpacer) {
@ -209,7 +227,20 @@ void TestScene::OnReceiveMessage(ewol::EObject * CallerObject, const char * even
baseRotationVect = vec3(0,0,1);
} else if (eventId == l_eventLunch) {
stupidCube * tmpp = new stupidCube(250);
tmpp->SetSpeed(vec3(10,50,0));
m_gameEngine.AddElement(tmpp, true);
} else if (eventId == l_eventChangeTimeSpeed1) {
if (NULL!=m_testWidget) {
m_testWidget->SetRatioTime(1);
}
} else if (eventId == l_eventChangeTimeSpeed0) {
if (NULL!=m_testWidget) {
m_testWidget->SetRatioTime(0.5);
}
} else if (eventId == l_eventChangeTimeSpeed2) {
if (NULL!=m_testWidget) {
m_testWidget->SetRatioTime(2);
}
}
return;