1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
|
#include "../../../include/odfaeg/Physics/boundingBox.h"
#include "../../../include/odfaeg/Physics/boundingSphere.h"
#include "../../../include/odfaeg/Physics/boundingEllipsoid.h"
#include "../../../include/odfaeg/Physics/orientedBoundingBox.h"
#include "../../../include/odfaeg/Physics/boundingPolyhedron.h"
#include "../../../include/odfaeg/Graphics/transformMatrix.h"
using namespace std;
namespace odfaeg {
//Create a bounding box at position 0, 0, 0 and with the dimensions 1, 1, 1.
BoundingBox::BoundingBox() : Interface<BoundingBox>(*this) {
int x = y = z = 0;
width = height = depth = 1;
vertices[0] = Vec3f(x, y, z);
vertices[1] = Vec3f(x + width, y, z);
vertices[2] = Vec3f(x + width, y + height, z);
vertices[3] = Vec3f(x, y + height, z);
vertices[4] = Vec3f(x, y, z + depth);
vertices[5] = Vec3f(x + width, y, z + depth);
vertices[6] = Vec3f(x + width, y + height, z + depth);
vertices[7] = Vec3f(x, y + height, z + depth);
}
//Create a bounding box with the specified , y, z position and of width, height, depth dimensions.
BoundingBox::BoundingBox (int x, int y, int z, int width, int height, int depth) : Interface<BoundingBox>(*this), center (x + width * 0.5f, y + height * 0.5f, z + depth * 0.5f) {
this->x = x;
this->y = y;
this->z = z;
this->width = width;
this->height = height;
this->depth = depth;
vertices[0] = Vec3f(x, y, z);
vertices[1] = Vec3f(x + width, y, z);
vertices[2] = Vec3f(x + width, y + height, z);
vertices[3] = Vec3f(x, y + height, z);
vertices[4] = Vec3f(x, y, z + depth);
vertices[5] = Vec3f(x + width, y, z + depth);
vertices[6] = Vec3f(x + width, y + height, z + depth);
vertices[7] = Vec3f(x, y + height, z + depth);
}
bool BoundingBox::intersects (BaseInterface& interface) {
std::cout<<"intersects with interface"<<std::endl;
static_cast<Interface<BoundingBox>&>(interface).data().intersects(*this);
}
//Test if the box intersects the specified sphere.
bool BoundingBox::intersects (BoundingSphere &bs) {
return bs.intersects(*this);
}
//Test if the box intersects the specified ellipsoid.
bool BoundingBox::intersects (BoundingEllipsoid &be) {
return be.intersects(*this);
}
//Test if the box intersects another.
bool BoundingBox::intersects (BoundingBox &other) {
//Get the medians of our two boxes.
/*Vec3f hi1[6];
hi1[0] = Vec3f(width * 0.5f, 0, 0);
hi1[1] = Vec3f(0, height * 0.5f, 0);
hi1[2] = Vec3f(0, 0, depth * 0.5f);
hi1[3] = Vec3f(-width * 0.5f, 0, 0);
hi1[4] = Vec3f(0, -height * 0.5f, 0);
hi1[5] = Vec3f(0, 0, -depth * 0.5f);
Vec3f hi2[6];
hi2[0] = Vec3f(other.width * 0.5f, 0, 0);
hi2[1] = Vec3f(0, other.height * 0.5f, 0);
hi2[2] = Vec3f(0, 0, other.depth * 0.5f);
hi1[3] = Vec3f(-width * 0.5f, 0, 0);
hi1[4] = Vec3f(0, -height * 0.5f, 0);
hi1[5] = Vec3f(0, 0, -depth * 0.5f);
for (unsigned int i = 0; i < 6; i++) {
Vec2f p1 = Computer::projectShapeOnAxis(hi1[i], vertices);
Vec2f p2 = Computer::projectShapeOnAxis(hi1[i], other.vertices);
if (!Computer::overlap(p1, p2))
return false;
}
for (unsigned int i = 0; i < 6; i++) {
Vec2f p1 = Computer::projectShapeOnAxis(hi2[i], vertices);
Vec2f p2 = Computer::projectShapeOnAxis(hi2[i], other.vertices);
if (!Computer::overlap(p1, p2))
return false;
}
return true;*/
//std::cout<<"other : "<<&other<<std::endl;
int hx1 = width * 0.5;
int hy1 = height * 0.5;
int hz1 = depth * 0.5;
int hx2 = other.width * 0.5;
int hy2 = other.height * 0.5;
int hz2 = other.depth * 0.5;
//Check the mins and max medians positions.
/*std::cout<<"width : "<<width<<" height : "<<height<<std::endl<<"center : "<<center;
std::cout<<"width 2 : "<<other.width<<" height 2 : "<<other.height<<" center 2 : "<<other.center;*/
float minX1 = center.x - hx1, minX2 = other.center.x - hx2;
float minY1 = center.y - hy1, minY2 = other.center.y - hy2;
float minZ1 = center.z - hz1, minZ2 = other.center.z - hz2;
float maxX1 = center.x + hx1, maxX2 = other.center.x + hx2;
float maxY1 = center.y + hy1, maxY2 = other.center.y + hy2;
float maxZ1 = center.z + hz1, maxZ2 = other.center.z + hz2;
//If the medians overlap, our two boxes intersects.
for (int i = 0; i < 3; i++) {
if (i == 0) {
if (minX1 > maxX2 || maxX1 < minX2)
return false;
} else if (i == 1) {
if (minY1 > maxY2 || maxY1 < minY2)
return false;
} else {
if (minZ1 > maxZ2 || maxZ1 < minZ2)
return false;
}
}
return true;
/*Vec3f d = other.center - center;
int c = d.magnitude() * 2;
Vec3f hi[3];
hi[0] = Vec3f(width * 0.5f, 0, 0);
hi[1] = Vec3f(0, height * 0.5f, 0);
hi[2] = Vec3f(0, 0, depth * 0.5f);
Vec3f hi2[3];
hi2[0] = Vec3f(other.width * 0.5f, 0, 0);
hi2[1] = Vec3f(0, other.height * 0.5f, 0);
hi2[2] = Vec3f(0, 0, other.depth * 0.5f);
for (unsigned int i = 0; i < 3; i++) {
int r1 = hi[i].projOnVector(d).magnitude();
int r2;
for (unsigned int j = 0; j < 3; j++) {
r2 = hi2[j].projOnVector(d).magnitude();
}
int rSum = r1 + r2;
std::cout<<rSum<<" "<<c<<std::endl;
if (c - rSum > 0)
return false;
}
return true;*/
}
//Test if an the box intersects with the specified oriented bounding box.
bool BoundingBox::intersects(OrientedBoundingBox &obx) {
return obx.intersects(*this);
}
//Test if the bounding box intersects with the specified bounding polyhedron.
bool BoundingBox::intersects (BoundingPolyhedron &bp) {
Vec3f hi[6];
hi[0] = Vec3f(width * 0.5f, 0, 0);
hi[1] = Vec3f(0, height * 0.5f, 0);
hi[2] = Vec3f(0, 0, depth * 0.5f);
hi[3] = Vec3f(-width * 0.5f, 0, 0);
hi[4] = Vec3f(0, -height * 0.5f, 0);
hi[5] = Vec3f(0, 0, -depth * 0.5f);
std::vector<Vec3f> normals = bp.getNormals();
for (unsigned int i = 0; i < 6; i++) {
Vec2f p1 = Computer::projectShapeOnAxis(hi[i], bp.getPoints());
Vec2f p2 = Computer::projectShapeOnAxis(hi[i], vertices);
if (!Computer::overlap(p1, p2))
return false;
}
for (unsigned int i = 0; i < normals.size(); i++) {
Vec2f p1 = Computer::projectShapeOnAxis(normals[i], bp.getPoints());
Vec2f p2 = Computer::projectShapeOnAxis(normals[i], vertices);
if (!Computer::overlap(p1, p2))
return false;
}
return true;
}
//Test if a point is inside our box.
bool BoundingBox::isPointInside (Vec3f point) {
//Check the min and max values of the medians of our box.
float minX = center.x - width * 0.5f;
float maxX = center.x + width * 0.5f;
float minY = center.y - height * 0.5f;
float maxY = center.y + height * 0.5f;
float minZ = center.z - depth * 0.5f;
float maxZ = center.z + depth * 0.5f;
//If one of the point is on one of the x, y or z medians, the point is inside the box.
return (point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY && point.z >= minZ && point.z <= maxZ);
}
bool BoundingBox::intersects (Ray &ray) {
float tFar = INT_MAX;
float tNear = -INT_MAX;
for (int i = 0; i < 3; i++) {
float d, orig, hi;
if (i == 0) {
hi = width / 2;
d = ray.getDir().x;
orig = ray.getOrig().x - center.x;
} else if (i == 1) {
hi = height / 2;
d = ray.getDir().y;
orig = ray.getOrig().y - center.y;
} else {
hi = depth / 2;
d = ray.getDir().z;
orig = ray.getOrig().z - center.z;
}
if (d == 0)
if (Math::abs(orig) > hi)
return false;
float t1 = (-hi - orig) / d;
float t2 = (hi - orig) / d;
float tmp;
if (t1 > t2) {
tmp = t1;
t1 = t2;
t2 = tmp;
} else
tmp = t1;
if (t1 > tNear)
tNear = t1;
if (t2 < tFar)
tFar = t2;
if (tNear > tFar)
return false;
if(tFar < 0)
return false;
}
return true;
}
//Acceseurs.
Vec3f BoundingBox::getCenter () {
return center;
}
float BoundingBox::getWidth () {
return width;
}
float BoundingBox::getHeight () {
return height;
}
float BoundingBox::getDepth() {
return depth;
}
Vec3f BoundingBox::getSize() {
return Vec3f(width, height, depth);
}
Vec3f BoundingBox::getPosition () {
return Vec3f (x, y, z);
}
void BoundingBox::setPosition(int x, int y, int z) {
this->x = x;
this->y = y;
this->z = z;
}
void BoundingBox::setSize(int width, int height, int depth) {
this->width = width;
this->height = height;
this->depth = depth;
}
void BoundingBox::move(Vec3f t) {
for (unsigned int i = 0; i < vertices.size(); i++)
vertices[i] += t;
x = vertices[0].x;
y = vertices[0].y;
z = vertices[0].z;
center.x = x + width * 0.5f;
center.y = y + height * 0.5f;
center.z = z + depth * 0.5f;
}
} |
Partager