From 4bf7e226f841671973fa059c7ba232bb9e027498 Mon Sep 17 00:00:00 2001 From: Peter Schaefer Date: Thu, 7 May 2015 11:34:34 +0200 Subject: [PATCH] saving loaded meshes collision on SubBBox works :) new class Overlap (overlap, inside and vec and shortest direction) Overlap (shortest direction doesnt work) --- Weave/Game.cpp | 3 +- Weave/Graphix/Model/IMesh.cpp | 12 +-- Weave/Graphix/Model/IMesh.h | 3 + Weave/Graphix/Model/IMetaMesh.cpp | 66 ++++++++++-- Weave/Graphix/Model/IMetaMesh.h | 5 +- Weave/Graphix/Model/Model.cpp | 174 ++++++++++++++++++++++++++---- Weave/Graphix/Model/Model.h | 35 +++++- Weave/Scene/SceneObject.cpp | 6 +- 8 files changed, 253 insertions(+), 51 deletions(-) diff --git a/Weave/Game.cpp b/Weave/Game.cpp index 19ec862..dd53c20 100644 --- a/Weave/Game.cpp +++ b/Weave/Game.cpp @@ -66,8 +66,7 @@ Game::Game() : playing(true) //current_world->addObject(new SceneObject(shader1, glm::mat4(1.0f), "Player.dae", "model_player.png")); //current_world->addObject(new SceneObject(shader1, translate(vec3(-3.f, .4f, 0.f))*scale(vec3(3.f)), "cow/cow.dae", "model_cow_2D.jpg")); current_world->addObject(new SceneObject(shader1, translate(vec3(-3.f, .4f, 0.f))*scale(vec3(.32f)), vec4(3.0f, 0.5f, 0.4f, 1.5f), "duck.dae", "model_duck_2D.png")); - - current_world->addObject(new SceneObject(shader1, translate(vec3(-3.f, .4f, 0.f))*scale(vec3(.32f)), vec4(3.0f, 3.f, 0.4f, 1.5f), "duck.dae", "model_cow_2D.jpg")); + current_world->addObject(new SceneObject(shader1, translate(vec3(-5.f, .4f, 0.f))*scale(vec3(.32f)), vec4(3.0f, 3.f, 0.4f, 1.5f), "duck.dae", "model_cow_2D.jpg")); current_world->addObject(new EventBox(translate(vec3(3.f, .4f, 0.f)),EB_LOSTZONE)); current_world->addObject(new EventBox(translate(vec3(3.f, .4f, -15.f)), EB_WINZONE)); diff --git a/Weave/Graphix/Model/IMesh.cpp b/Weave/Graphix/Model/IMesh.cpp index 4a6b3e5..de00367 100644 --- a/Weave/Graphix/Model/IMesh.cpp +++ b/Weave/Graphix/Model/IMesh.cpp @@ -16,9 +16,6 @@ using std::string; IMesh::IMesh(const string& _modelpath, uint _mindex) : modelpath(_modelpath) { - float *vertex = nullptr, *normals = nullptr, *uvs = nullptr; - uint *index = nullptr; - import(_modelpath, numvertices, numfaces, vertex, uvs, normals, index, _mindex); updateBB(numvertices,vertex); @@ -28,16 +25,11 @@ IMesh::IMesh(const string& _modelpath, uint _mindex) : modelpath(_modelpath) genBuffer(uvBuffer, numvertices * 2 * sizeof(float), (void*)uvs); genBuffer(indexBuffer, numfaces * 3 * sizeof(uint), (void*)index); - delete vertex, normals, uvs, index; - } IMesh::IMesh(const aiMesh* _mesh, const mat4& _transformation) : modelMat(_transformation), modelpath("IMesh") { - float *vertex = nullptr, *normals = nullptr, *uvs = nullptr; - uint *index = nullptr; - import(_mesh, numvertices, numfaces, vertex, uvs, normals, index); updateBB(numvertices,vertex,modelMat); @@ -47,13 +39,13 @@ IMesh::IMesh(const aiMesh* _mesh, const mat4& _transformation) : modelMat(_trans genBuffer(uvBuffer, numvertices * 2 * sizeof(float), (void*)uvs); genBuffer(indexBuffer, numfaces * 3 * sizeof(uint), (void*)index); - delete vertex, normals, uvs, index; - } IMesh::~IMesh() { + delete vertex, normals, uvs, index; + glDeleteBuffers(1, &vertexBuffer); glDeleteBuffers(1, &indexBuffer); glDeleteBuffers(1, &normalBuffer); diff --git a/Weave/Graphix/Model/IMesh.h b/Weave/Graphix/Model/IMesh.h index 14e7353..43451d4 100644 --- a/Weave/Graphix/Model/IMesh.h +++ b/Weave/Graphix/Model/IMesh.h @@ -33,6 +33,9 @@ protected: std::string modelpath; mat4 modelMat; + float *vertex = nullptr, *normals = nullptr, *uvs = nullptr; + uint *index = nullptr; + // Mesh Speichern? bool import(const std::string& modelpath, uint& numvertices, uint& numfaces, float*& vertex, float*& uvs, float*& normals, uint*& index , uint mindex = 0) const; bool import(const aiMesh* mesh, uint& numvertices, uint& numfaces, float*& vertex, float*& uvs, float*& normals, uint*& index) const; diff --git a/Weave/Graphix/Model/IMetaMesh.cpp b/Weave/Graphix/Model/IMetaMesh.cpp index 7bd6958..155502a 100644 --- a/Weave/Graphix/Model/IMetaMesh.cpp +++ b/Weave/Graphix/Model/IMetaMesh.cpp @@ -99,26 +99,70 @@ void IMetaMesh::drawBBox(const mat4& _modelMat,const vec4& _color) const } +Overlap IMetaMesh::checkColS2O(const mat4& _mMat, const Model* _model, const mat4& _modelMat) const +{ + //Outer BBox + Overlap firstBB = Model::checkColS2O(_mMat, _model, _modelMat); + if (!firstBB) + return firstBB; + + //Inner BBox + Overlap tmp,secondSubBB; + for (auto i = models.begin(); i != models.end(); ++i) + { + tmp = (*i)->checkColS2O(_mMat, _model, _modelMat); + if (tmp) + { + secondSubBB.update(tmp); + } + + } + //if (!secondSubBB) + return secondSubBB; + +} -void IMetaMesh::checkColliding(float& _overlap, float& _inside, const Model* _model, const mat4& _modelMatThis, const mat4& _modelMatOther) const +Overlap IMetaMesh::checkColO2SBox(const mat4& _mMat, const vec3& _pos, const vec3& _size, const mat4& _modelMat) const { - Model::checkColliding(_overlap, _inside, _model, _modelMatThis, _modelMatOther); + //Outer BBox + Overlap firstBB = Model::checkColO2SBox(_mMat, _pos, _size, _modelMat); + if (!firstBB) + return firstBB; - if (min(_overlap, _inside) >= 0) + //Inner BBox + Overlap tmp, secondSubBB; + for (auto i = models.begin(); i != models.end(); ++i) { - _overlap = -1; _inside = -1; - float subOverlap = -1, subInside = -1; - for (auto i = models.begin(); i != models.end(); ++i) + tmp = (*i)->checkColO2SBox(_mMat, _pos, _size, _modelMat); + if (tmp) { - _model->checkColliding(subOverlap, subInside, *i, _modelMatThis, _modelMatOther); - if (subOverlap > _overlap) - _overlap = subOverlap; - if (subInside > _inside) - _inside = subInside; + secondSubBB.update(tmp); } + } + //if (!secondSubBB) + return secondSubBB; } +//void checkColliding(float& _overlap, float& _inside, const Model* _model, const mat4& _modelMatThis, const mat4& _modelMatOther) const +//{ +// Model::checkColliding(_overlap, _inside, _model, _modelMatThis, _modelMatOther); +// +// if (min(_overlap, _inside) >= 0) +// { +// _overlap = -1; _inside = -1; +// float subOverlap = -1, subInside = -1; +// for (auto i = models.begin(); i != models.end(); ++i) +// { +// _model->checkColliding(subOverlap, subInside, *i, _modelMatThis, _modelMatOther); +// if (subOverlap > _overlap) +// _overlap = subOverlap; +// if (subInside > _inside) +// _inside = subInside; +// } +// } +//} + IMetaMesh::operator string() const { return modelpath; diff --git a/Weave/Graphix/Model/IMetaMesh.h b/Weave/Graphix/Model/IMetaMesh.h index 13f763f..60aafa6 100644 --- a/Weave/Graphix/Model/IMetaMesh.h +++ b/Weave/Graphix/Model/IMetaMesh.h @@ -22,8 +22,11 @@ public: void drawBBox(const mat4& modelMat, const vec4& color = vec4(0.9f, 0.f, 0.f, 1.f)) const override; + Overlap checkColS2O(const mat4& mMat, const Model* model, const mat4& modelMat) const override; + Overlap checkColO2SBox(const mat4& mMat, const vec3& pos, const vec3& size, const mat4& modelMat) const override; + /* calls Colliding to check if self collides with model*/ - void checkColliding(float& overlap, float& inside, const Model* model, const mat4& modelMatThis, const mat4& modelMatOther) const; +// void checkColliding(float& overlap, float& inside, const Model* model, const mat4& modelMatThis, const mat4& modelMatOther) const; operator std::string() const override; diff --git a/Weave/Graphix/Model/Model.cpp b/Weave/Graphix/Model/Model.cpp index 941bc8f..8f29e3e 100644 --- a/Weave/Graphix/Model/Model.cpp +++ b/Weave/Graphix/Model/Model.cpp @@ -237,40 +237,86 @@ void Model::useModelMat(const mat4& _model, Shader* _shader) const glUniformMatrix4fv(tmp, 1, GL_FALSE, value_ptr(_model)); } -void Model::isColliding(float& _overlap, float& _inside, const Model* _modelThis, const Model* _modelOther, const mat4& _modelMatThis, const mat4& _modelMatOther) +Overlap Model::isColliding(const Model* _modelThis, const Model* _modelOther, const mat4& _modelMatThis, const mat4& _modelMatOther) { - vec3 posA, sizeA, posB, sizeB; - float overlap=INFINITY, inside=INFINITY; + return _modelThis->checkColS2O(_modelMatThis, _modelOther, _modelMatOther); - _modelThis->getBBsp(sizeA, posA); - _modelOther->getBBsp(sizeB, posB); + //vec3 posA, sizeA, posB, sizeB; + //float overlap, inside; - mat4 modelAR = glm::inverse(removeScale(_modelMatOther))*_modelMatThis; - mat4 modelBR = glm::inverse(removeScale(_modelMatThis))*_modelMatOther; + //_modelThis->getBBsp(sizeA, posA); + //_modelOther->getBBsp(sizeB, posB); - vec3 posAR = (vec3)(modelAR*vec4(posA, 1.f)); - vec3 posBR = (vec3)(modelBR*vec4(posB, 1.f)); + //mat4 modelAR = glm::inverse(removeScale(_modelMatOther))*_modelMatThis; + //mat4 modelBR = glm::inverse(removeScale(_modelMatThis))*_modelMatOther; - vec3 sizeAR = rotateSize(sizeA, modelAR); - vec3 sizeBR = rotateSize(sizeB, modelBR); + //vec3 posAR = (vec3)(modelAR*vec4(posA, 1.f)); + //vec3 posBR = (vec3)(modelBR*vec4(posB, 1.f)); - vec3 scaleA = getScale(_modelMatThis); - vec3 scaleB = getScale(_modelMatOther); + //vec3 sizeAR = rotateSize(sizeA, modelAR); + //vec3 sizeBR = rotateSize(sizeB, modelBR); - scaleVec3(posA, scaleA); - scaleVec3(posB, scaleB); + //vec3 scaleA = getScale(_modelMatThis); + //vec3 scaleB = getScale(_modelMatOther); - scaleVec3(sizeA, scaleA); - scaleVec3(sizeB, scaleB); + //scaleVec3(posA, scaleA); + //scaleVec3(posB, scaleB); - checkCollideByAxis(_overlap, _inside, 3, value_ptr(posAR), value_ptr(posB), value_ptr(sizeAR), value_ptr(sizeB)); - if (_overlap >= 0) + //scaleVec3(sizeA, scaleA); + //scaleVec3(sizeB, scaleB); + + //checkCollideByAxis(overlap,inside, 3, value_ptr(posAR), value_ptr(posB), value_ptr(sizeAR), value_ptr(sizeB)); + //Overlap ret(overlap, inside); + //if (ret.overlap() >= 0) + //{ + // checkCollideByAxis(overlap, inside, 3, value_ptr(posA), value_ptr(posBR), value_ptr(sizeA), value_ptr(sizeBR)); + // ret.update(overlap, inside); + //} + //return ret; +} + +Overlap Model::checkColS2O(const mat4& _mMat, const Model* _model, const mat4& _modelMat) const +{ + vec3 scale = getScale(_mMat); + vec3 pos = BBposition; + scaleVec3(pos, scale); + vec3 size = BBsize; + scaleVec3(size, scale); + + Overlap stepBB = _model->checkColO2SBox(_modelMat, pos, size, removeScale(_mMat)); + + return stepBB; +} + +Overlap Model::checkColO2SBox(const mat4& _mMat, const vec3& _posB, const vec3& _sizeB, const mat4& _modelMat) const +{ + vec3 scale = getScale(_mMat); + vec3 posA = BBposition; + scaleVec3(posA, scale); + vec3 sizeA = BBsize; + scaleVec3(sizeA, scale); + + mat4 mMat = removeScale(_mMat); + + mat4 modelAR = glm::inverse(_modelMat)*mMat; + mat4 modelBR = glm::inverse(mMat)*_modelMat; + + vec3 posAR = (vec3)(modelAR*vec4(posA, 1.f)); + vec3 posBR = (vec3)(modelBR*vec4(_posB, 1.f)); + + vec3 sizeAR = rotateSize(sizeA, modelAR); + vec3 sizeBR = rotateSize(_sizeB, modelBR); + + float overlap, inside; + checkCollideByAxis(overlap, inside, 3, value_ptr(posAR), value_ptr(_posB), value_ptr(sizeAR), value_ptr(_sizeB)); + Overlap ret(overlap, inside); + if (ret.overlap() >= 0) { checkCollideByAxis(overlap, inside, 3, value_ptr(posA), value_ptr(posBR), value_ptr(sizeA), value_ptr(sizeBR)); - _overlap = min(overlap, _overlap); - _inside = min(overlap, _inside); + ret.update(overlap, inside); } + return ret; } void Model::checkColliding(float& _overlap, float& _inside, const Model* _model, const mat4& _modelMatThis, const mat4& _modelMatOther) const @@ -431,4 +477,88 @@ float Model::getPDistHit(const vec3& _P, const vec3& _direction) const Model* Model::BoundingBox = nullptr; Model* Model::SkyBoxModel = nullptr; std::unordered_map Model::IMetaModel; -std::unordered_map Model::IMetaModel_count; \ No newline at end of file +std::unordered_map Model::IMetaModel_count; + + + +Overlap::Overlap() : unset(true) +{ +} + +Overlap::Overlap(float _over, float _in) : in(_in), over(_over), unset(false) +{ +} + +Overlap::~Overlap() +{ +} + +float Overlap::overlap() const +{ + if (unset) + return -1; + else + return over; +} + +float Overlap::inside() const +{ + if (unset) + return -1; + else + return in; +} + +Overlap::operator bool() const +{ + if (unset) + return false; + else + return over>=0; +} + +void Overlap::update(float _over, float _in) +{ + if (unset) + { + over = _over; + in = _in; + unset = true; + return; + } + + // select closest distance + if (over > _over) + { + over = _over; + } + + //sync inside + in = min(in, _in); +} + +void Overlap::update(const Overlap& _other) +{ + if (unset) + { + *this = _other; + return; + } + + // select closest distance + if (over > _other.over) + { + over = _other.over; + } + + //sync inside + in = min(in, _other.in); +} + +Overlap Overlap::merge(const Overlap& _first, const Overlap& _second) +{ + // select closest distance + Overlap ret = _first; + ret.update(_second); + return ret; +} \ No newline at end of file diff --git a/Weave/Graphix/Model/Model.h b/Weave/Graphix/Model/Model.h index e18bc9e..3793e0f 100644 --- a/Weave/Graphix/Model/Model.h +++ b/Weave/Graphix/Model/Model.h @@ -6,6 +6,7 @@ class Shader; class Texture; +class Overlap; typedef unsigned int uint; @@ -30,8 +31,14 @@ public: virtual void getBBsp(vec3& size, vec3& pos) const; /* calls Colliding to check if self collides with model*/ - static void isColliding(float& overlap, float& inside, const Model* modelThis, const Model* modelOther, const mat4& modelMatThis, const mat4& modelMatOther); - void checkColliding(float& overlap, float& inside, const Model* model, const mat4& modelMatThis, const mat4& modelMatOther) const; + static Overlap isColliding(const Model* modelThis, const Model* modelOther, const mat4& modelMatThis, const mat4& modelMatOther); + + + /* test self against other*/ + virtual Overlap checkColS2O(const mat4& mMat, const Model* model, const mat4& modelMat) const; + virtual Overlap checkColO2SBox(const mat4& mMat, const vec3& pos, const vec3& size, const mat4& modelMat) const; + //virtual void checkColO2STriangle() const; + virtual void checkColliding(float& overlap, float& inside, const Model* model, const mat4& modelMatThis, const mat4& modelMatOther) const; static Model* getBBoxModel(); static Model* getSkyBoxModel(); @@ -78,3 +85,27 @@ private: }; +class Overlap +{ +public: + Overlap(); + Overlap(float over, float in); + ~Overlap(); + + float overlap() const; + float inside() const; + + operator bool() const; + + static Overlap merge(const Overlap& first, const Overlap& second); + void update(float over, float in); + void update(const Overlap& other); + +protected: + bool unset; + float over; + float in; + + vec3 center; + vec3 normal; +}; \ No newline at end of file diff --git a/Weave/Scene/SceneObject.cpp b/Weave/Scene/SceneObject.cpp index 8caf26f..7ffd156 100644 --- a/Weave/Scene/SceneObject.cpp +++ b/Weave/Scene/SceneObject.cpp @@ -147,11 +147,11 @@ void SceneObject::checkCollision(SceneObject* _first, SceneObject* _second) if (_first->collision_ignore || _second->collision_ignore) return; - float isOverlaping, isInside; - Model::isColliding(isOverlaping, isInside, _first->model,_second->model, _first->modelMat, _second->modelMat); + + Overlap over = Model::isColliding(_first->model,_second->model, _first->modelMat, _second->modelMat); /* overlapping 1 yes, 0 touch, -1 no*/ /* inside 1 yes, 0 touch, -1 no*/ - if (isOverlaping >= 0) + if (over.overlap() >= 0) { _first->collides(_second); _second->collides(_first); -- 2.47.3