using std::list;
using std::array;
typedef Model::Triangle Triangle;
+typedef Model::Box Box;
typedef IMesh::Node Node;
+
// Vergleiche Unterbaum
//#define COMPARE_MTREE
//draw BBox of MTREE deep LVL -1 means all lvl's
-#define BBOX_MTREE 10
+#define BBOX_MTREE 5
// Vergleiche auch Triangles
#define COMPARE_FACE
root = buildMeshTree(mat4(1.f), numvertices, numfaces, vertex, normals, index);
vec3 min, max;
- root->getBBmm(min, max);
- setBB(min, max);
+ setBB(*root);
#else
setBB(numvertices, vertex);
#endif
root = buildMeshTree(_transformation, numvertices, numfaces, vertex, normals, index);
vec3 min, max;
- root->getBBmm(min, max);
- setBB(min, max);
+ setBB(*root);
#else
setBB(numvertices, vertex, _transformation);
#endif
void drawSubBBox(const mat4& _modelMat, const vec4& _color, Node* _node, int _lvl)
{
- vec3 BBsiz, BBpos;
- _node->getBBcs(BBpos, BBsiz);
+ //vec3 BBsiz, BBpos;
+ //_node->getBBcs(BBpos, BBsiz);
Graphix::getGlError();
Graphix::shader_BBox->useShader();
int tmp = Graphix::shader_BBox->getUniformLocation("uFragmentColor");
if (tmp >= 0)
glUniform4fv(tmp, 1, value_ptr(_color));
Graphix::getGlError();
- Model::getBBoxModel()->drawModel(Graphix::shader_BBox, NULL, _modelMat*translate(BBpos)*glm::scale(BBsiz*2.f));
+ Model::getBBoxModel()->drawModel(Graphix::shader_BBox, NULL, _modelMat*translate(_node->center())*glm::scale(_node->size()*2.f));
if (_lvl == 0)
return;
#endif
}
-//void IMesh::drawModel(Shader* _shader, Texture* _texture, const mat4& _modelMat) const
-//{
-//
-//}
-
-//void IMesh::bindShader(Shader* _shader)
-//{
-//
-//}
Overlap IMesh::checkColNode2O(const Node* _node, const vec3& _scale, const mat4& _mOSMat, const Model* _model, const mat4& _modelMat) const
{
scaleVec3(pos, _scale);
scaleVec3(size, _scale);
- Overlap stepNode = _model->checkColO2SBox(_modelMat, pos, size,_mOSMat);
+ Overlap stepNode = _model->checkColO2SBox(_modelMat, Box(pos, size),_mOSMat);
//Falls _node nicht overlap
if (!stepNode)
//return secondT;
}
-Overlap IMesh::checkColO2SBox(const mat4& _mMat, const vec3& _pos, const vec3& _size, const mat4& _modelMat) const
-{
- //Outer Mesh
-//#ifdef COMPARE_MTREE
-// vec3 scale = getScale(_mMat);
-// Overlap firstBB = checkColO2NodeBox(root, scale, removeScale(_mMat), _pos, _size, _modelMat);
-//#else
- Overlap firstBB = Model::checkColO2SBox(_mMat, _pos, _size, _modelMat);
-//#endif
-
- //if (!firstBB)
- return firstBB;
-
- //Inner Mesh
- //call checkColO2STriangle
-
-}
-
Overlap IMesh::checkColO2SBox(const mat4& _mMat, const Box& _boxB, const mat4& _modelMat) const
{
//Outer Mesh
return "IMesh";
}
-void getCSfromNodeList(vec3& _center, vec3& _size, const list<Node*>& _TriList)
+Box getBoxfromNodeList(const list<Node*>& _TriList)
{
- vec3 BBmin, BBmax;
- _TriList.front()->getBBmm(BBmin, BBmax);
- for (auto k = _TriList.cbegin(); k != _TriList.cend(); ++k)
- {
- (*k)->getUBBmm(BBmin, BBmax);
- }
+ Box ret(*_TriList.front());
- _size = (BBmax - BBmin) / 2.f;
- _center = (BBmin + BBmax) / 2.f;
-}
+ for (auto k = ++_TriList.cbegin(); k != _TriList.cend(); ++k)
+ ret.update(**k);
-void getMMfromNodeList(vec3& _min, vec3& _max, const list<Node*>& _TriList)
-{
- _TriList.front()->getBBmm(_min, _max);
- for (auto k = _TriList.cbegin(); k != _TriList.cend(); ++k)
- {
- (*k)->getUBBmm(_min, _max);
- }
+ return ret;
}
-Node* IMesh::buildMeshTree(const list<Node*>& _triList, vec3 _min, vec3 _max)
+
+Node* IMesh::buildMeshTree(const list<Node*>& _triList)
{
//catch if list is empty
if (_triList.size() == 0)
return _triList.front();
//catch if list has only two elements => 2 LEAFS
if (_triList.size() == 2)
- return new Node(_min, _max, _triList.front(), _triList.back());
+ return new Node(_triList.front(), _triList.back());
+ //catch if list has only three elements = 1 NODE & 3 LEAFS
if (_triList.size() == 3)
{
- vec3 nMi, nMa;
list<Node*> tmpList = _triList;
Node* tmpNode = tmpList.front();
tmpList.pop_front();
- getMMfromNodeList(nMi, nMa, tmpList);
-
- return new Node(_min, _max, tmpNode, buildMeshTree(tmpList, nMi, nMa));
+ return new Node(tmpNode, buildMeshTree(tmpList));
}
- vec3 size = (_min - _max) / 2.f;
- vec3 center = (_min + _max) / 2.f;
+
+ Box box(getBoxfromNodeList(_triList));
+
//find longest dist
- vec3 sort = sortVec3(size);
+ vec3 sort = sortVec3(box.size());
//SPLIT and call self
array<list<Node*>, 3> lower, upper;
float bestPerc(1), splitPerc(1);
//try different DIM
-
for (auto k = _triList.cbegin(); k != _triList.cend(); ++k)
{
- (*k)->getBBmm(tmpMin, tmpMax);
vec3 mean = (*k)->getMean();
for (dim = 0; dim < 3; ++dim)
{
- if (mean[(int)sort[dim]] < center[(int)sort[dim]])
- {
- if (lower[dim].size() < 1)
- {
- lMin[dim] = tmpMin;
- lMax[dim] = tmpMax;
- }
- else
- updateVec3MinMax(lMin[dim], lMax[dim], tmpMin, tmpMax);
+ if (mean[(int)sort[dim]] < box.center()[(int)sort[dim]])
lower[dim].push_back(*k);
- }
else
- {
- if (upper[dim].size() < 1)
- {
- uMin[dim] = tmpMin;
- uMax[dim] = tmpMax;
- }
- else
- updateVec3MinMax(uMin[dim], uMax[dim], tmpMin, tmpMax);
upper[dim].push_back(*k);
- }
}
}
+
+ //check best Dim
for (dim = 0; dim < 3; ++dim)
{
splitPerc = abs(upper[dim].size() / (float)_triList.size() - .5f);
dim = bestDim;
- return new Node(_min, _max, buildMeshTree(lower[dim], lMin[dim], lMax[dim]),
- buildMeshTree(upper[dim], uMin[dim], uMax[dim]));
+ return new Node(box, buildMeshTree(lower[dim]), buildMeshTree(upper[dim]));
}
Node* IMesh::buildMeshTree(const mat4& modelMat, const uint& numvertices, const uint& numfaces, const float* vertex, const float* normals, const uint* index)
tmp_normal *= -1;
node_list.push_back(new Node(new Triangle(tmp_vert, tmp_normal)));
}
- vec3 min, max;
- getMMfromNodeList(min, max, node_list);
-
-
- return buildMeshTree(node_list, min, max);
+ return buildMeshTree(node_list);
}
-Node::Node(Triangle* tri) : element(tri), lNode(nullptr), uNode(nullptr)
+Node::Node(Triangle* tri) : element(tri), lNode(nullptr), uNode(nullptr), Box(*tri)
{
mean = element->getMean();
- element->getBBmm(min, max);
- size = (max - min) / 2.f;
- center = (min + max) / 2.f;
+ //element->getBBmm(min, max);
+ //size = (max - min) / 2.f;
+ //center = (min + max) / 2.f;
}
-//Node::Node(Triangle* tri, const vec3& cen, const vec3& siz, const vec3& mi, const vec3& ma)
-// : element(tri), center(cen), size(siz), min(mi), max(ma), lNode(nullptr), uNode(nullptr), splitDim(-1)
-//{
-//}
+Node::Node(const Box& _box, Node* _lower, Node* _upper)
+ : Box(_box), element(nullptr), lNode(_lower), uNode(_upper)
+{}
-Node::Node(const vec3& _min, const vec3& _max, Node* _lower, Node* _upper)
- : element(nullptr), lNode(_lower), uNode(_upper), center((_min + _max) / 2.f), size((_max - _min) / 2.f), min(_min), max(_max)
+Node::Node(Node* _lower, Node* _upper)
+ : element(nullptr), lNode(_lower), uNode(_upper), Box(merge(*_lower,*_upper))
{
+
}
Node::~Node()
}
-void Node::getBBcs(vec3& cen, vec3& siz) const
-{
- cen = center;
- siz = size;
-}
-
-void Node::getBBmm(vec3& mi, vec3& ma) const
-{
- mi = min;
- ma = max;
-}
-
-void Node::getUBBmm(vec3& mi, vec3& ma) const
-{
- updateVec3MinMax(mi, ma, min, max);
-}
-
vec3 Node::getMean() const
{
return mean;
void useModelMat(const mat4& model, Shader* shader) const override;
- //void drawModel(Shader* shader, Texture* texture, const mat4& modelMat) const;
-
- //void bindShader(Shader* shader);
-
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;
Overlap checkColO2SBox(const mat4& mMat, const Model::Box& boxB, const mat4& modelMat) const override;
//Overlap checkColO2STriangle(const mat4& mMat, const vec3& pos, const mat3& directions) const override;
operator std::string() const override;
static Node* buildMeshTree(const mat4& modelMat, const uint& numvertices, const uint& numfaces, const float* vertex, const float* normals, const uint* index);
- static Node* buildMeshTree(const std::list<IMesh::Node*>& triList, vec3 min, vec3 max);
+ static Node* buildMeshTree(const std::list<IMesh::Node*>& triList);
- class Node
+ class Node : public Model::Box
{
public:
Node(Triangle* tri);
- //Node(Triangle* tri, const vec3& center, const vec3& size, const vec3& min, const vec3& max);
- Node::Node(const vec3& min, const vec3& max, Node* lower, Node* upper);
+ Node(Node* lower, Node* upper);
+ Node(const Box& box, Node* lower, Node* upper);
~Node();
- /* sets center & size */
- void getBBcs(vec3& center, vec3& size) const;
- /* sets min & max */
- void getBBmm(vec3& min, vec3& max) const;
- /* updates min & max */
- void getUBBmm(vec3& min, vec3& max) const;
- /* get mean*/
vec3 getMean() const;
Node* getLNode() const;
Model::Triangle* getElement() const;
private:
- vec3 center;
- vec3 size;
- vec3 min;
- vec3 max;
vec3 mean;
Node *lNode, *uNode;
Box boxA(box);
boxA.scale(scale);
-// Overlap stepBB = _model->checkColO2SBox(_modelMat, pos, size, removeScale(_mMat));
-
Overlap stepBB = _model->checkColO2SBox(_modelMat, boxA, removeScale(_mMat));
return stepBB;
}
-Overlap Model::checkColO2SBox(const mat4& _mMat, const vec3& _posB, const vec3& _sizeB, const mat4& _modelMatB) const
-{
- vec3 scale = getScale(_mMat);
- vec3 posA = box.center();
- vec3 sizeA = box.size();
-
- scaleVec3(posA, scale);
- scaleVec3(sizeA, scale);
-
- mat4 mMat = removeScale(_mMat);
-
- mat4 modelAR = glm::inverse(_modelMatB)*mMat;
- mat4 modelBR = glm::inverse(mMat)*_modelMatB;
-
- 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));
- ret.update(overlap, inside);
- }
-
- return ret;
-}
-
Overlap Model::checkColO2SBox(const mat4& _mMat, const Box& _boxB, const mat4& _modelMatB) const
{
//split _mMat to scale and mMat
//
//}
-void Model::checkCollideByAxis(float& _overlap, float& _inside, uint dim, const float* posA, const float* posB, const float* sizeA, const float* sizeB)
-{
- _overlap = sizeA[0] + sizeB[0];
- _inside = sizeA[0] + sizeB[0];
- for (uint i = 0; i < dim; ++i)
- {
-
- _overlap = min(sizeA[i] + sizeB[i] - abs(posA[i] - posB[i]), _overlap);
-
- if (_overlap < 0)
- {
- _overlap = -1;
- _inside = -1;
- return;
- }
- if (_inside >= 0)
- _inside = min(abs(sizeA[i] - sizeB[i]) - abs(posA[i] - posB[i]), _inside);
-
- }
- if (_inside < 0)
- _inside = -1;
-}
Overlap Model::checkCollideByAxis(const Box& _boxA, const Box& _boxB)
{
return (vertex[0] + vertex[1] + vertex[2]) / 3.f;
}
+Triangle::operator Model::Box() const
+{
+ vec3 min = vertex[0];
+ vec3 max = min;
+ for (uint i = 0; i < 3; ++i)
+ {
+ for (uint j = 0; j < 3; ++j)
+ {
+ if (vertex[i][j] < min[j])
+ min[j] = vertex[i][j];
+ if (vertex[i][j] > max[j])
+ max[j] = vertex[i][j];
+ }
+ }
+ return Box((max + min)*.5f, (max - min)*.5f);
+}
+
+
//CLASS BOX
Box::Box() : cen(0.f), siz(0.f)
{
}
-//Box::Box(const Box& _box) : cen(_box.cen), siz(_box.siz)
-//{
-//}
-
Box::~Box()
{
}
+
void Box::getBBcs(vec3& _center, vec3& _size) const
{
_center = cen;
_size = siz;
}
+
void Box::rotate(const mat4& _modelMat)
{
//Rotate Center
return siz;
}
+void Box::update(const Box& _box)
+{
+ vec3 diff = _box.cen - cen;
+ float size;
+
+ for (int i = 0; i<3; ++i)
+ {
+ if (abs(siz[i] - _box.siz[i]) - abs(diff[i]) >= 0)
+ {
+ if (siz[i] < _box.siz[i])
+ {
+ siz[i] = _box.siz[i];
+ cen[i] = _box.cen[i];
+ }
+ }
+ else
+ {
+ size = (siz[i] + _box.siz[i] + abs(diff[i])) * .5f;
+ cen[i] = cen[i] - sign(diff[i]) * (siz[i] - size);
+ siz[i] = size;
+ }
+
+ }
+}
+
+
Box Box::merge(const Box& _boxA, const Box& _boxB)
{
vec3 diff = _boxB.cen - _boxA.cen;