diff --git a/external/etk b/external/etk index 3b5aa7b8..52d5bd18 160000 --- a/external/etk +++ b/external/etk @@ -1 +1 @@ -Subproject commit 3b5aa7b84f5f41c72eccf3c2fecb6f8404401e9b +Subproject commit 52d5bd18102bed9321a620e29581c480d084d44d diff --git a/sources/ewol/game/BoundingAABB.cpp b/sources/ewol/game/BoundingAABB.cpp index a3035e6e..cd863db1 100644 --- a/sources/ewol/game/BoundingAABB.cpp +++ b/sources/ewol/game/BoundingAABB.cpp @@ -13,10 +13,9 @@ game::BoundingAABB::BoundingAABB(void) : - m_hasContact(false), - m_center(0,0,0), - m_size(1,1,1), - m_oldUserPosition(0,0,0) + m_PointStart(-1,-1,-1), + m_PointStop(1,1,1), + m_hasContact(false) { #ifdef DEBUG if (false == ewol::resource::Keep(m_displayBounding) ) { @@ -39,44 +38,38 @@ game::BoundingAABB::~BoundingAABB(void) void game::BoundingAABB::Update(game::MeshObject& object, mat4& rotation, vec3& position, vec3& scale) { - vec3 pointStart; - vec3 pointStop; mat4 transformMatrix = etk::matTranslate(position) * etk::matScale(scale) * rotation; for (int32_t iii=0; iii point.x) { - pointStart.x = point.x; - } else if (pointStop.x < point.x) { - pointStop.x = point.x; + if (m_PointStart.x > point.x) { + m_PointStart.x = point.x; + } else if (m_PointStop.x < point.x) { + m_PointStop.x = point.x; } - if (pointStart.y > point.y) { - pointStart.y = point.y; - } else if (pointStop.y < point.y) { - pointStop.y = point.y; + if (m_PointStart.y > point.y) { + m_PointStart.y = point.y; + } else if (m_PointStop.y < point.y) { + m_PointStop.y = point.y; } - if (pointStart.z > point.z) { - pointStart.z = point.z; - } else if (pointStop.z < point.z) { - pointStop.z = point.z; + if (m_PointStart.z > point.z) { + m_PointStart.z = point.z; + } else if (m_PointStop.z < point.z) { + m_PointStop.z = point.z; } } } - m_size = (pointStop - pointStart) / 2; - m_center = pointStop - m_size; - m_oldUserPosition = position; - #ifdef DEBUG vec3 tmpBB(0.001,0.001,0.001); - vec3 tmpStart = pointStart - tmpBB; - vec3 tmpStop = pointStop + tmpBB; + vec3 tmpStart = m_PointStart - tmpBB; + vec3 tmpStop = m_PointStop + tmpBB; // (start) X / Y vec3 tmpPos = tmpStart; m_vertices[0] = tmpStart; @@ -179,12 +172,16 @@ void game::BoundingAABB::Draw(void) bool game::BoundingAABB::HasContact(game::BoundingAABB& obj) { - if( (abs(m_center.x-obj.m_center.x) > m_size.x+obj.m_size.x) - || (abs(m_center.y-obj.m_center.y) > m_size.y+obj.m_size.y) - || (abs(m_center.z-obj.m_center.z) > m_size.z+obj.m_size.z) ) { + if( m_PointStart.x > obj.m_PointStop.x + || m_PointStop.x < obj.m_PointStart.x + || m_PointStart.y > obj.m_PointStop.y + || m_PointStop.y < obj.m_PointStart.y + || m_PointStart.z > obj.m_PointStop.z + || m_PointStop.z < obj.m_PointStart.z) { return false; } return true; } + diff --git a/sources/ewol/game/BoundingAABB.h b/sources/ewol/game/BoundingAABB.h index de3ec379..e401f354 100644 --- a/sources/ewol/game/BoundingAABB.h +++ b/sources/ewol/game/BoundingAABB.h @@ -18,9 +18,9 @@ namespace game class BoundingAABB { private : + vec3 m_PointStart; + vec3 m_PointStop; bool m_hasContact; //!< this bounding is on contact with something else ... - vec3 m_center; - vec3 m_size; vec3 m_oldUserPosition; // this is due to the fact object are never centered ... #ifdef DEBUG ewol::Colored3DObject* m_displayBounding; @@ -55,6 +55,8 @@ namespace game * @brief Get the current contact status */ bool GetContactStatus(void) { return m_hasContact; }; + + vec3 Size(void) { return m_PointStop-m_PointStart; }; }; } diff --git a/sources/ewol/game/Element.cpp b/sources/ewol/game/Element.cpp index 369b6cf4..71134474 100644 --- a/sources/ewol/game/Element.cpp +++ b/sources/ewol/game/Element.cpp @@ -9,12 +9,14 @@ #include +#include #include static int32_t uniqueId = 0; game::Element::Element(etk::UString meshResource) : + m_engine(NULL), m_resource(NULL), m_matrixNeedUpdate(true), m_scale(1,1,1), @@ -23,7 +25,8 @@ game::Element::Element(etk::UString meshResource) : m_uniqueId(uniqueId), m_groupId(0), m_type(0), - m_visible(true) + m_visible(true), + m_static(false) { ewol::MeshObj* tmpObject = NULL; // get a resources : @@ -99,11 +102,56 @@ void game::Element::ProcessPosition(float delta) vec3 curentAcceleration(m_gravityForce + m_userAcceleration); m_speed += curentAcceleration*delta; vec3 tmpPos = m_position +m_speed*delta; - // TODO : Detect collision of other elements ... if (m_position != tmpPos) { + // TODO : Detect collision of other elements ... + vec3 size = m_bounding.Size(); + vec3 move = tmpPos - m_position; + vec3 moveAbs = move; + moveAbs.Abs(); + if( ( 0 < size.x + && moveAbs.x > 2*size.x ) + || ( 0 < size.y + && moveAbs.y > 2*size.y ) + || ( 0 < size.z + && moveAbs.z > 2*size.z )) { + int32_t maxIterations = 0; + // generate a subdivide channel to prevent tunel effects ... + // Get the smallest axis to test : + if( moveAbs.x >= moveAbs.y + && moveAbs.x >= moveAbs.z) { + //Test on X : + //estimate the number of subdivision needed in recursive mode : + maxIterations = moveAbs.x/abs(size.x); + EWOL_DEBUG("XXX move with dist=" << move << "m <" << size*2 << "m"); + } else if ( moveAbs.y >= moveAbs.x + && moveAbs.y >= moveAbs.z) { + //Test on Y : + //estimate the number of subdivision needed in recursive mode : + maxIterations = moveAbs.y/abs(size.y); + EWOL_DEBUG("YYY move with dist=" << move << "m <" << size*2 << "m"); + } else { + //Test on Z : + //estimate the number of subdivision needed in recursive mode : + maxIterations = moveAbs.z/abs(size.z); + EWOL_DEBUG("ZZZ move with dist=" << move << "m <" << size*2 << "m"); + } + vec3 deltaMove = move/maxIterations; + vec3 tmppppPos = m_position; + game::BoundingAABB tmpBounding; + // linear test : + for (int32_t iii=0; iiim_object, m_displayRotation, tmppppPos, m_scale); + if (true == m_engine->HasCollision(tmpBounding, this)) { + tmpPos = tmppppPos; + // the tunnel effect is catch ... + EWOL_CRITICAL("Tunel effect catch : (" << iii << "/" << maxIterations-1 << ")"); + break; + } + } + } m_position = tmpPos; 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"); } } diff --git a/sources/ewol/game/Element.h b/sources/ewol/game/Element.h index bc4af249..e1f3d5e4 100644 --- a/sources/ewol/game/Element.h +++ b/sources/ewol/game/Element.h @@ -20,9 +20,11 @@ namespace game { + class Engine; class Element { protected: + game::Engine* m_engine; ewol::Mesh* m_resource; //!< Resource to display the element. game::BoundingAABB m_bounding; //!< Bounding of this element private: @@ -45,6 +47,7 @@ namespace game 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 ... + bool m_static; //!< This element is static... public: /** * @brief Basic constructor. @@ -55,6 +58,11 @@ namespace game * @brief Basic destructor. */ virtual ~Element(void); + /** + * @brief Link with a specific engine. + * @param[in] engine Engine pointer + */ + void SetEngine(game::Engine* engine) { m_engine = engine; }; /** * @brief Draw the element. */ @@ -113,6 +121,15 @@ namespace game m_scale = vect; m_matrixNeedUpdate = true; } + /** + * @brief Scale the element to an other size + * @param[in] proportion scale value in all direction ... + */ + void Scale(float proportion) + { + m_scale = vec3(proportion,proportion,proportion); + m_matrixNeedUpdate = true; + } /** * @brief Rotate the current object * @param[in] vect rotation angle @@ -147,6 +164,14 @@ namespace game { return m_bounding; } + /** + * @brief Set this element Static or not + */ + void SetStaticMode(bool newMode) { m_static = newMode; }; + /** + * @brief Get the current static or dynamic mode + */ + bool GetStaticMode(void) { return m_static; }; }; }; diff --git a/sources/ewol/game/Engine.cpp b/sources/ewol/game/Engine.cpp index 6a51e2e4..495be601 100644 --- a/sources/ewol/game/Engine.cpp +++ b/sources/ewol/game/Engine.cpp @@ -69,16 +69,19 @@ void game::Engine::ProcessCollision(float deltaTime) bounding1.SetContactMode(false); } } - + // Brut force bounding detection : for (int32_t iii=0; iiiGetBounding(); - for (int32_t jjj=iii+1; jjjGetBounding(); - if (true == bounding2.HasContact(bounding1)) { - bounding2.SetContactMode(true); - bounding1.SetContactMode(true); + // If the element is static, the bounding detection is not needed... + if (true) {//false == m_elements[iii]->GetStaticMode()) { + game::BoundingAABB& bounding1 = m_elements[iii]->GetBounding(); + for (int32_t jjj=iii+1; jjjGetBounding(); + if (true == bounding2.HasContact(bounding1)) { + bounding2.SetContactMode(true); + bounding1.SetContactMode(true); + } } } } @@ -86,6 +89,25 @@ void game::Engine::ProcessCollision(float deltaTime) } } + +bool game::Engine::HasCollision(game::BoundingAABB& bounding, game::Element* currentElement) +{ + // Brut force bounding detection : + for (int32_t iii=0; iiiGetBounding())) { + return true; + } + } + } + return false; +} + + + void game::Engine::Draw(ewol::DrawProperty& displayProp) { //EWOL_DEBUG("Drawing the system"); @@ -107,6 +129,9 @@ void game::Engine::Draw(ewol::DrawProperty& displayProp) void game::Engine::AddElement(game::Element* newElement) { bool find=false; + if (NULL == newElement) { + EWOL_ERROR("try to set a NULL pointer game::Element"); + } for (int32_t iii=0 ; iiiSetEngine(this); } } diff --git a/sources/ewol/game/Engine.h b/sources/ewol/game/Engine.h index 37d32c29..0ee3b5f7 100644 --- a/sources/ewol/game/Engine.h +++ b/sources/ewol/game/Engine.h @@ -57,6 +57,7 @@ namespace game * @param[in] deltaTime delta time in µs from the previous call. */ void ProcessCollision(float deltaTime); + bool HasCollision(game::BoundingAABB& bounding, game::Element* currentElement); /** * @brief Display the environement. */ diff --git a/sources/ewol/renderer/resources/MeshObj.cpp b/sources/ewol/renderer/resources/MeshObj.cpp index b28c56e7..60b01fe2 100644 --- a/sources/ewol/renderer/resources/MeshObj.cpp +++ b/sources/ewol/renderer/resources/MeshObj.cpp @@ -39,9 +39,10 @@ ewol::MeshObj::MeshObj(etk::UString _fileName) : etk::Vector< vec2 > uvTextures; etk::Vector< vec3 > normals; - + int32_t lineID = 0; while (NULL != fileName.FileGets(inputDataLine, 2048) ) { + lineID++; if (inputDataLine[0]=='v') { if (inputDataLine[1]=='n') { // Vertice normal : vn 0.000000 0.000000 -1.000000 @@ -61,25 +62,77 @@ ewol::MeshObj::MeshObj(etk::UString _fileName) : } } else if (inputDataLine[0]=='f') { // face : f 5/1/1 1/2/1 4/3/1* - uint32_t vertexIndex[3], uvIndex[3], normalIndex[3]; - int32_t matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d\n", + uint32_t vertexIndex[4], uvIndex[4], normalIndex[4]; + bool quadMode = true; + int32_t matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], - &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); - if (9 != matches){ - EWOL_ERROR("Parsing error in the .obj files : " << fileName); - continue; + &vertexIndex[2], &uvIndex[2], &normalIndex[2], + &vertexIndex[3], &uvIndex[3], &normalIndex[3] ); + if (12 != matches){ + // no normal mode : + matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d %d/%d\n", + &vertexIndex[0], &uvIndex[0], + &vertexIndex[1], &uvIndex[1], + &vertexIndex[2], &uvIndex[2], + &vertexIndex[3], &uvIndex[3] ); + if (8 != matches){ + quadMode = false; + matches = sscanf(&inputDataLine[2], "%d/%d/%d %d/%d/%d %d/%d/%d\n", + &vertexIndex[0], &uvIndex[0], &normalIndex[0], + &vertexIndex[1], &uvIndex[1], &normalIndex[1], + &vertexIndex[2], &uvIndex[2], &normalIndex[2] ); + if (9 != matches){ + // no normal mode : + matches = sscanf(&inputDataLine[2], "%d/%d %d/%d %d/%d\n", + &vertexIndex[0], &uvIndex[0], + &vertexIndex[1], &uvIndex[1], + &vertexIndex[2], &uvIndex[2] ); + if (6 != matches){ + EWOL_ERROR("Parsing error in the .obj files : " << fileName << " (l=" << lineID << ") in 'f' section : \"" << &inputDataLine[2] << "\" expected : %d/%d(/%d) %d/%d(/%d) %d/%d(/%d) (%d/%d(/%d)) () for option"); + continue; + } + } + } } - indicesVertices.PushBack(vertexIndex[0]); - indicesVertices.PushBack(vertexIndex[1]); - indicesVertices.PushBack(vertexIndex[2]); - indicesUv.PushBack(uvIndex[0]); - indicesUv.PushBack(uvIndex[1]); - indicesUv.PushBack(uvIndex[2]); - indicesNormal.PushBack(normalIndex[0]); - indicesNormal.PushBack(normalIndex[1]); - indicesNormal.PushBack(normalIndex[2]); - + if (true==quadMode) { + indicesVertices.PushBack(vertexIndex[0]); + indicesVertices.PushBack(vertexIndex[1]); + indicesVertices.PushBack(vertexIndex[2]); + // second triangle + indicesVertices.PushBack(vertexIndex[0]); + indicesVertices.PushBack(vertexIndex[2]); + indicesVertices.PushBack(vertexIndex[3]); + indicesUv.PushBack(uvIndex[0]); + indicesUv.PushBack(uvIndex[1]); + indicesUv.PushBack(uvIndex[2]); + // second triangle + indicesUv.PushBack(uvIndex[0]); + indicesUv.PushBack(uvIndex[2]); + indicesUv.PushBack(uvIndex[3]); + if (12 == matches) { + indicesNormal.PushBack(normalIndex[0]); + indicesNormal.PushBack(normalIndex[1]); + indicesNormal.PushBack(normalIndex[2]); + // second triangle + indicesNormal.PushBack(normalIndex[0]); + indicesNormal.PushBack(normalIndex[2]); + indicesNormal.PushBack(normalIndex[3]); + } + } else { + indicesVertices.PushBack(vertexIndex[0]); + indicesVertices.PushBack(vertexIndex[1]); + indicesVertices.PushBack(vertexIndex[2]); + indicesUv.PushBack(uvIndex[0]); + indicesUv.PushBack(uvIndex[1]); + indicesUv.PushBack(uvIndex[2]); + if (9 == matches) { + indicesNormal.PushBack(normalIndex[0]); + indicesNormal.PushBack(normalIndex[1]); + indicesNormal.PushBack(normalIndex[2]); + } + } + // TODO : Calculate normal when none is provided ... } else if (inputDataLine[0]=='s') { // ??? : s off } else if (inputDataLine[0]=='#') { @@ -125,15 +178,17 @@ ewol::MeshObj::MeshObj(etk::UString _fileName) : // Get the indices of its attributes uint32_t vertexIndex = indicesVertices[iii]; uint32_t uvIndex = indicesUv[iii]; - uint32_t normalIndex = indicesNormal[iii]; // Put the attributes in buffers m_object.m_vertices.PushBack(vertices[vertexIndex-1]); m_object.m_uvTextures.PushBack(uvTextures[uvIndex-1]); - m_object.m_normals.PushBack(normals[normalIndex-1]); draw::Color tmpppp(0xFFFFFFFF); draw::Colorf tmppppp(tmpppp); m_coordColor.PushBack(tmppppp); + if (indicesNormal.Size()>iii) { + uint32_t normalIndex = indicesNormal[iii]; + m_object.m_normals.PushBack(normals[normalIndex-1]); + } } }