[DEV] create the basic gravity equations

This commit is contained in:
Edouard DUPIN 2012-12-18 22:09:27 +01:00
parent 4b4758bc7f
commit 326dccb94d
23 changed files with 359 additions and 121 deletions

2
external/etk vendored

@ -1 +1 @@
Subproject commit 0b2050cf687a0f698b838df781a8095a9e92939d
Subproject commit df8a54b55a24afbbda666956ca729f404381945c

View File

@ -11,7 +11,6 @@
#include "ewol/debug.h"
#include "ewol/game/MeshObject.h"
#include "ewol/game/MeshProperty.h"
namespace game
{
@ -51,7 +50,7 @@ namespace game
/**
* @brief Update Bounding properties.
*/
virtual void Update(game::MeshObject& object, game::MeshProperty& property) = 0;
virtual void Update(game::MeshObject& object) = 0;
};
};

View File

@ -22,15 +22,17 @@ game::BoundingAABB::~BoundingAABB(void)
}
void game::BoundingAABB::Update(game::MeshObject& object, game::MeshProperty& property)
void game::BoundingAABB::Update(game::MeshObject& object)
{
if (true==m_markedToUpdate) {
/*
mat4 transMat = etk::matRotate(property.m_angle) * etk::matTranslate(property.m_position);
m_markedToUpdate=false;
for (int32_t iii=0; iii<object.m_vertices.Size(); iii++) {
vec3 point = transMat * object.m_vertices[iii];
}
*/
}
}

View File

@ -32,7 +32,7 @@ namespace game
/**
* @brief Update Bounding properties.
*/
virtual void Update(game::MeshObject& object, game::MeshProperty& property);
virtual void Update(game::MeshObject& object);
};
}

View File

@ -10,7 +10,7 @@
#include <ewol/game/BoundingOBB.h>
game::BoundingOBB::BoundingOBB(game::MeshObject& object, game::MeshProperty& property) :
game::BoundingOBB::BoundingOBB(game::MeshObject& object) :
Bounding(game::BoundingModeOBB)
{
@ -21,7 +21,7 @@ game::BoundingOBB::~BoundingOBB(void)
}
void game::BoundingOBB::Update(game::MeshObject& object, game::MeshProperty& property)
void game::BoundingOBB::Update(game::MeshObject& object)
{
}

View File

@ -25,7 +25,7 @@ namespace game
* @biref Main constructor.
* @param[in] mode Bounding mode.
*/
BoundingOBB(game::MeshObject& object, game::MeshProperty& property);
BoundingOBB(game::MeshObject& object);
/**
* @biref Main constructor.
*/
@ -33,7 +33,7 @@ namespace game
/**
* @brief Update Bounding properties.
*/
virtual void Update(game::MeshObject& object, game::MeshProperty& property);
virtual void Update(game::MeshObject& object);
};
}

View File

@ -21,7 +21,7 @@ game::BoundingPlane::~BoundingPlane(void)
}
void game::BoundingPlane::Update(game::MeshObject& object, game::MeshProperty& property)
void game::BoundingPlane::Update(game::MeshObject& object)
{
}

View File

@ -31,7 +31,7 @@ namespace game
/**
* @brief Update Bounding properties.
*/
virtual void Update(game::MeshObject& object, game::MeshProperty& property);
virtual void Update(game::MeshObject& object);
};
}

View File

@ -21,7 +21,7 @@ game::BoundingSphere::~BoundingSphere(void)
}
void game::BoundingSphere::Update(game::MeshObject& object, game::MeshProperty& property)
void game::BoundingSphere::Update(game::MeshObject& object)
{
}

View File

@ -32,7 +32,7 @@ namespace game
/**
* @brief Update Bounding properties.
*/
virtual void Update(game::MeshObject& object, game::MeshProperty& property);
virtual void Update(game::MeshObject& object);
};
}

View File

@ -16,11 +16,11 @@ static int32_t uniqueId = 0;
game::Element::Element(etk::UString meshResource) :
m_resource(NULL),
m_mass(0.0f),
m_uniqueId(uniqueId),
m_groupId(0),
m_type(0),
m_visible(true),
m_mass(0)
m_visible(true)
{
ewol::MeshObj* tmpObject = NULL;
// get a resources :
@ -30,9 +30,9 @@ game::Element::Element(etk::UString meshResource) :
}
uniqueId++;
m_property.Scale(vec3(100,100,100) );
Scale(vec3(100,100,100) );
//m_property.Rotate(m_property.m_angle, rotx);
m_property.Translate(vec3(0.01,0.0,0.0));
Translate(vec3(0.01,0.0,0.0));
}
game::Element::~Element(void)
@ -47,7 +47,7 @@ game::Element::~Element(void)
void game::Element::Draw(void)
{
if (NULL != m_resource) {
m_resource->Draw(m_property.GetMatrix());
m_resource->Draw(GetMatrix());
}
}
@ -57,3 +57,44 @@ bool game::Element::ArtificialIntelligence(int32_t deltaMicroSecond)
return false;
}
void game::Element::ProcessGravityClear(void)
{
m_gravityForce = vec3(0,0,0);
}
void game::Element::ProcessGravity(float delta, game::Gravity& gravity)
{
if (0==m_mass) {
return;
}
if (gravity.m_uniform==true) {
m_gravityForce += gravity.m_vect;//*m_mass;
} else {
vec3 vectSeparation = m_position - gravity.m_vect;
float squareDistance = vectSeparation.GetSquaredLength();
// calculate gravity equation :
float force = game::GravityConst * gravity.m_mass * m_mass / squareDistance;
vectSeparation.Normalize();
// generate the force vector
vectSeparation *= force;
m_gravityForce += vectSeparation;
}
}
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");
}
}

View File

@ -14,7 +14,7 @@
#include <etk/math/Vector3D.h>
#include <etk/Vector.h>
#include <ewol/debug.h>
#include <ewol/game/MeshProperty.h>
#include <ewol/game/Gravity.h>
#include <ewol/renderer/resources/Mesh.h>
namespace game
@ -23,13 +23,26 @@ namespace game
{
protected:
ewol::Mesh* m_resource; //!< Resource to display the element.
game::MeshProperty m_property; //!< display property f the element.
private:
bool m_matrixNeedUpdate; //!< the matrix need to be regenerated
mat4 m_matrix; //!< generated display matrix.
vec3 m_scale; //!< scale of the element. (change the size in dynamic from the loaded model)
vec3 m_displayAngle; //!< Rotate the model.
mat4 m_displayRotation; //!< Associated matrix of totation associated with m_displayAngle.
protected:
// specific for the physical engine :
vec3 m_position; //!< position of the element. (in m)
vec3 m_speed; //!< Speed of the element. (in m/s)
float m_mass; //!< object mass (in kg)
vec3 m_gravityForce; //!< curent gravity force in newton of the object (m/s^2)
vec3 m_userAcceleration; //!< the only one parameter that the user can change (m/s^2), if the coder want that the equation do not take stipid things ...
protected:
uint32_t m_uniqueId; //!< General element ID (uint16_t, because all is reference with the groupId like this only a uint32_t reference an element)
uint32_t m_groupId; //!< General group Id More than 65000 group can be really interesting to create supid game ...
int32_t m_type; //!< type of this element
bool m_visible; //!< This is to know if the element is displayed or not ==> TODO : check if usefull ...
float m_mass; //!< Current element Mass ==> for the physical calculation
public:
/**
* @brief Basic constructor.
@ -50,6 +63,79 @@ namespace game
* @return true if this element must be destroyed
*/
virtual bool ArtificialIntelligence(int32_t deltaMicroSecond);
/**
* @brief Clear the current gravity reference
*/
void ProcessGravityClear(void);
/**
* @brief Update the gravity properties.
* @param[in] delta delta from the last call.
* @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.
*/
virtual void ProcessPosition(float delta);
/**
* @param reset the position / speed / angle / and result matrix
*/
void Identity(void)
{
m_position = vec3(0,0,0);
m_speed = vec3(0,0,0);
m_displayAngle = vec3(0,0,0);
m_displayRotation.Identity();
m_matrix.Identity();
};
/**
* @brief Translate The curent element to a new position
* @param[in] vect new position
*/
void Translate(etk::Vector3D<float> vect)
{
m_position += vect;
m_matrixNeedUpdate = true;
}
/**
* @brief Scale the element to an other size
* @param[in] vect new object scaling
*/
void Scale(etk::Vector3D<float> vect)
{
m_scale = vect;
m_matrixNeedUpdate = true;
}
/**
* @brief Rotate the curent object
* @param[in] vect rotation angle
* @param[in] angleRad radian angle
*/
void Rotate(etk::Vector3D<float> vect, float angleRad=0.0)
{
m_displayAngle.RotateAxis(angleRad, vect);
m_displayRotation = etk::matRotate(vect, angleRad) * m_displayRotation;
m_matrixNeedUpdate = true;
}
/**
* @brief Get the Current matrix of the element (never access it directly, it might be sometime updated)
* @return the reference on the matrix (updated if needed)
*/
mat4& GetMatrix(void)
{
if (m_matrixNeedUpdate == true) {
m_matrixNeedUpdate = false;
m_matrix = etk::matScale(m_scale) * m_displayRotation * etk::matTranslate(m_position);
}
return m_matrix;
};
};
};

View File

@ -20,11 +20,53 @@ game::Engine::Engine(void)
game::Engine::~Engine(void)
{
for (int32_t iii=0; iii<m_elementsStatic.Size() ; iii++) {
if (NULL != m_elementsStatic[iii]) {
delete(m_elementsStatic[iii]);
m_elementsStatic[iii] = NULL;
}
}
m_elementsStatic.Clear();
for (int32_t iii=0; iii<m_elementsDynamic.Size() ; iii++) {
if (NULL != m_elementsDynamic[iii]) {
delete(m_elementsDynamic[iii]);
m_elementsDynamic[iii] = NULL;
}
}
m_elementsDynamic.Clear();
}
void game::Engine::Process(int64_t lastTime, int32_t deltaTime)
void game::Engine::Process(double lastTime, float deltaTime)
{
ProcessGravity(deltaTime);
ProcessIA(deltaTime);
ProcessCollision(deltaTime);
}
void game::Engine::ProcessGravity(float deltaTime)
{
//EWOL_DEBUG("Gravity management");
for(int32_t jjj=0 ; jjj<m_gravity.Size() ; jjj++) {
for (int32_t iii=0; iii<m_elementsStatic.Size() ; iii++) {
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);
}
}
}
void game::Engine::ProcessIA(float deltaTime)
{
//EWOL_DEBUG("Artificial Intelligence management");
for (int32_t iii=0; iii<m_elementsStatic.Size() ; iii++) {
if (NULL != m_elementsStatic[iii]) {
m_elementsStatic[iii]->ArtificialIntelligence(deltaTime);
@ -37,8 +79,15 @@ void game::Engine::Process(int64_t lastTime, int32_t deltaTime)
}
}
void game::Engine::ProcessCollision(float deltaTime)
{
//EWOL_DEBUG("Collision management");
}
void game::Engine::Draw(ewol::DrawProperty& displayProp)
{
//EWOL_DEBUG("Drawing the system");
for (int32_t iii=0; iii<m_elementsStatic.Size() ; iii++) {
if (NULL != m_elementsStatic[iii]) {
m_elementsStatic[iii]->Draw();
@ -79,3 +128,10 @@ void game::Engine::AddElement(game::Element* newElement, bool dynamic)
}
}
}
void game::Engine::AddGravity(game::Gravity gravity)
{
m_gravity.PushBack(gravity);
}

View File

@ -13,15 +13,19 @@
#include <etk/types.h>
#include <ewol/debug.h>
#include <ewol/game/Element.h>
#include <ewol/game/Gravity.h>
#include <ewol/widget/Widget.h>
namespace game
{
class Engine
{
private:
etk::Vector<game::Element*> m_elementsStatic;
etk::Vector<game::Element*> m_elementsDynamic;
etk::Vector<game::Gravity> m_gravity; //!< list of gravity element
etk::Vector<game::Element*> m_elementsStatic; //!< List of the game element (bounding does not move)
etk::Vector<game::Element*> m_elementsDynamic; //!< List of the game element (change position all the time)
public:
/**
* @brief Basic constructor.
@ -36,7 +40,22 @@ namespace game
* @param[in] lastTime Previous call time (if the system is in pause this time does restart at the same time the next time.
* @param[in] deltaTime delta time in µs from the previous call.
*/
void Process(int64_t lastTime, int32_t deltaTime);
void Process(double lastTime, float deltaTime);
/**
* @brief Processing the gravity properties.
* @param[in] deltaTime delta time in µs from the previous call.
*/
void ProcessGravity(float deltaTime);
/**
* @brief Processing the Artificial Intelligence.
* @param[in] deltaTime delta time in µs from the previous call.
*/
void ProcessIA(float deltaTime);
/**
* @brief Processing the collision.
* @param[in] deltaTime delta time in µs from the previous call.
*/
void ProcessCollision(float deltaTime);
/**
* @brief Display the environement.
*/
@ -47,6 +66,11 @@ namespace game
* @param[in] dynamic this element change of place.
*/
void AddElement(game::Element* newElement, bool dynamic);
/**
* @brief Add a gravity on the system.
* @param[in] gravity The gravity to add.
*/
void AddGravity(game::Gravity gravity);
};
};

View File

@ -14,10 +14,9 @@
#include <ewol/game/BoundingPlane.h>
#include <ewol/game/BoundingSphere.h>
game::Geometry::Geometry(game::MeshObject& object, game::MeshProperty& property) :
game::Geometry::Geometry(game::MeshObject& object) :
m_dynamic(false),
m_object(object),
m_property(property),
m_bounding(NULL),
m_mass(NULL)
{
@ -49,6 +48,7 @@ void game::Geometry::SetBoundingMode(game::boundingMode type)
return;
}
}
/*
switch(type)
{
default:
@ -67,12 +67,13 @@ void game::Geometry::SetBoundingMode(game::boundingMode type)
m_bounding = new game::BoundingOBB(m_object, m_property);
break;
}
*/
}
void game::Geometry::BoundingUpdate(void)
{
if (NULL != m_bounding) {
m_bounding->Update(m_object, m_property);
m_bounding->Update(m_object);
}
}

View File

@ -21,16 +21,14 @@ namespace game
private :
bool m_dynamic; //!< Set at true if the Geometry can move or not (bounding can change)
game::MeshObject& m_object; //!< Object vertex/ normal and other properties
game::MeshProperty& m_property; //!< Display properties of this element.
game::Bounding* m_bounding; //!< Bounding interface.
game::Mass* m_mass; //!< Mass properties.
public:
/**
* @brief main constructor
* @param[in] object the reference mesh object (must not be NULL)
* @param[in] property the reference mesh property (must not be NULL)
*/
Geometry(game::MeshObject& object, game::MeshProperty& property);
Geometry(game::MeshObject& object);
/**
* @brief main destructor
*/

View File

@ -0,0 +1,46 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/types.h>
#include <ewol/debug.h>
#include <ewol/game/Gravity.h>
game::Gravity::Gravity(void) :
m_uniform(false),
m_mass(0),
m_vect(0,0,0)
{
}
game::Gravity::Gravity(bool uniform, float mass, vec3 vect) :
m_uniform(uniform),
m_mass(mass),
m_vect(vect)
{
}
// gravity force is :
// F = G*m1*m2 / radius^2.
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))) );
// 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))) );

View File

@ -0,0 +1,42 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __GAME_GRAVITY_H__
#define __GAME_GRAVITY_H__
#include <etk/types.h>
#include <etk/math/Vector3D.h>
namespace game
{
class Gravity
{
public:
bool m_uniform; //!< The gravity is not a stelar object
float m_mass; //!< Masse of the stelar object.
vec3 m_vect; //!< Position of the stelar object or gravity(acceleration) force when it is uniform.
Gravity(void);
Gravity(bool uniform, float mass, vec3 vect);
};
extern const float GravityConst;
// Earth
extern const float earthMass;
extern const float earthRadius;
extern const Gravity gravityEarth;
// Mars
extern const float marsMass;
extern const float marsRadius;
extern const Gravity gravityMars;
};
#endif

View File

@ -1,82 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __GAME_MESH_PROPERTY_H__
#define __GAME_MESH_PROPERTY_H__
#include <etk/types.h>
#include <etk/Vector.h>
#include <etk/math/Vector3D.h>
#include <etk/math/Matrix4.h>
namespace game
{
class MeshProperty
{
public:
vec3 m_scale; //!< scale of the element.
vec3 m_position; //!< position of the element.
vec3 m_speed; //!< Speed of the element.
vec3 m_angle;
mat4 m_rotation; //!< rotation matrix ...
bool needUpdate;
mat4 m_matrix; //!< generated dispaly matrix.
public:
MeshProperty(void) :
m_position(0,0,0),
m_speed(0,0,0),
needUpdate(true)
{
//m_matrix.Identity();
};
virtual ~MeshProperty(void) {};
void Identity(void)
{
m_position = vec3(0,0,0);
m_speed = vec3(0,0,0);
m_angle = vec3(0,0,0);
m_matrix.Identity();
};
void Translate(etk::Vector3D<float> vect)
{
m_position += vect;
needUpdate = true;
}
void Scale(etk::Vector3D<float> vect)
{
m_scale = vect;
needUpdate = true;
}
void Rotate(etk::Vector3D<float> vect, float angleRad=0.0)
{
m_rotation *= etk::matRotate(vect, angleRad);
needUpdate = true;
}
mat4& GetMatrix(void)
{
if (needUpdate == true) {
m_matrix = etk::matScale(m_scale) * m_rotation * etk::matTranslate(m_position);
}
return m_matrix;
};
vec3& GetSpeed(void)
{
return m_speed;
}
vec3& GetPosition(void)
{
return m_position;
}
};
};
#endif

View File

@ -71,21 +71,26 @@ void widget::Scene::OnDraw(ewol::DrawProperty& displayProp)
void widget::Scene::PeriodicCall(int64_t localTime)
{
double curentTime=(double)localTime/1000000.0;
// First time :
if (-1 == m_lastCallTime) {
m_lastCallTime = localTime;
m_lastCallTime = curentTime;
}
// check if the processing is availlable
if (false == m_isRunning) {
m_lastCallTime = localTime;
m_lastCallTime = curentTime;
MarkToRedraw();
return;
}
// cut the processing in small slot of time to prevent error in the real-time Display (Android call us between 30 to 60 fps)
int32_t deltaTime = (int32_t) (localTime - m_lastCallTime);
float deltaTime = (float) (curentTime - m_lastCallTime);
//EWOL_DEBUG("Time: m_lastCallTime=" << m_lastCallTime << " deltaTime=" << deltaTime);
if (NULL != m_gameEngine) {
m_gameEngine->Process(m_lastCallTime, deltaTime);
if (true == m_isRunning) {
m_gameEngine->Process(m_lastCallTime, deltaTime);
}
}
m_lastCallTime = curentTime;
MarkToRedraw();
}

View File

@ -24,7 +24,7 @@ namespace widget {
protected:
game::Engine* m_gameEngine; //!< display engine system
bool m_isRunning; //!< the display is running (not in pause)
int64_t m_lastCallTime; //!< previous call Time
double m_lastCallTime; //!< previous call Time
public:
/**
* @brief Main scene constructor

View File

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

View File

@ -31,6 +31,7 @@ static const char * l_eventAddSphere = "event-add-sphere";
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";
@ -76,6 +77,11 @@ TestScene::TestScene(void)
myButton->RegisterOnEvent(this, ewolEventButtonPressed, l_eventRotationZ);
mySizerHori->SubWidgetAdd(myButton);
}
myButton = new widget::Button("lunch object");
if (NULL != myButton) {
myButton->RegisterOnEvent(this, ewolEventButtonPressed, l_eventLunch);
mySizerHori->SubWidgetAdd(myButton);
}
widget::Spacer* mySpacer = new widget::Spacer();
if (NULL != mySpacer) {
@ -136,6 +142,11 @@ TestScene::TestScene(void)
mySpacer->SetColor(0x00FFFF80);
SubWidgetAdd(mySpacer);
}
// et other property on the Engine :
m_gameEngine.AddGravity(game::gravityEarth);
APPL_CRITICAL("Create "__class__" (end)");
}
@ -152,12 +163,17 @@ vec3 baseRotationVect;
class stupidCube : public game::Element
{
public:
stupidCube(void) : game::Element("DATA:cube.obj") {};
stupidCube(float poidKg=0.0f) : game::Element("DATA:cube.obj")
{
m_mass = poidKg;
};
// herited methode
virtual bool ArtificialIntelligence(int32_t deltaMicroSecond)
{
m_property.Rotate(baseRotationVect, 0.01);
if (m_mass == 0.0f) {
Rotate(baseRotationVect, 0.01);
}
return false;
}
@ -191,6 +207,9 @@ void TestScene::OnReceiveMessage(ewol::EObject * CallerObject, const char * even
baseRotationVect = vec3(0,1,0);
} else if (eventId == l_eventRotationZ) {
baseRotationVect = vec3(0,0,1);
} else if (eventId == l_eventLunch) {
stupidCube * tmpp = new stupidCube(250);
m_gameEngine.AddElement(tmpp, true);
}
return;