char BoundingBox::inside(const BoundingBox & b) const { return (getMin(0) >= b.getMin(0) && getMin(1) >= b.getMin(1) && getMin(2) >= b.getMin(2) && getMax(0) <= b.getMax(0) && getMax(1) <= b.getMax(1) && getMax(2) <= b.getMax(2)); }
char BoundingBox::isBoxAround(const BoundingBox & b, float threshold) const { if(b.getMin(0) > getMax(0) + threshold) return 0; if(b.getMax(0) < getMin(0) - threshold) return 0; if(b.getMin(1) > getMax(1) + threshold) return 0; if(b.getMax(1) < getMin(1) - threshold) return 0; if(b.getMin(2) > getMax(2) + threshold) return 0; if(b.getMax(2) < getMin(2) - threshold) return 0; return 1; }
Transform::Transform(Matrix &m, Object3D *o) :mMat(m), mObj(o) { mMat.Inverse(mReverseMat); //Compute the transformed BBox BoundingBox *pBB = mObj->getBoundingBox(); if (pBB == NULL) return; Vec3f minP = pBB->getMin(); Vec3f maxP = pBB->getMax(); mMat.Transform(minP); mMat.Transform(maxP); BoundingBox box; box = Union(box, minP); box = Union(box, Vec3f(maxP.x(), minP.y(), minP.z())); box = Union(box, Vec3f(minP.x(), maxP.y(), minP.z())); box = Union(box, Vec3f(maxP.x(), maxP.y(), minP.z())); box = Union(box, Vec3f(minP.x(), minP.y(), maxP.z())); box = Union(box, Vec3f(maxP.x(), minP.y(), maxP.z())); box = Union(box, Vec3f(minP.x(), maxP.y(), maxP.z())); box = Union(box, maxP); mpBox = new BoundingBox(); mpBox->Set(&box); }
bool BoundingBox::intersects( std::list<Vector> vectors, BoundingBox &other){ GLfloat rot[3]; other.getRotation( rot); Matrix4f transformationMatrix; Matrix4f rotationMatrix; rotationMatrix.rotate( -rotation[0], -rotation[1], -rotation[2]); rotationMatrix.rotate( rot[0], rot[1], rot[2]); Matrix4f axis; GLfloat mins[3], maxes[3]; for (int i=0; i<NUM_DIMENSIONS; i++) { Vector v( axis[ i * (NUM_DIMENSIONS +1) ], axis[ i * (NUM_DIMENSIONS +1) +1], axis[i* (NUM_DIMENSIONS +1) +2] ); Matrix matrixVector = rotationMatrix * v; Vector newV(matrixVector); findExtremePoint(vectors, newV, mins + i, maxes + i); } Vector newMin( mins[0], mins[1], mins[2]); Vector newMax( maxes[0], maxes[1], maxes[2]); Vector translate(other.getTranslation()); transformationMatrix.rotate( rotation[0], rotation[1], rotation[2]); transformationMatrix.translate( translation.getX(), translation.getY(), translation.getZ()); transformationMatrix.rotate( -rot[0], -rot[1], -rot[2]); transformationMatrix.translate( -translate.getX(), -translate.getY(), -translate.getZ()); newMin = transformationMatrix * newMin; newMax = transformationMatrix * newMax; if ( newMax.getX() + EPSILON < other.getMin().getX() || other.getMax().getX() + EPSILON< newMin.getX() ) return false; if ( newMax.getY() + EPSILON < other.getMin().getY() || other.getMax().getY() + EPSILON< newMin.getY() ) return false; if ( newMax.getZ() + EPSILON < other.getMin().getZ() || other.getMax().getZ() + EPSILON< newMin.getZ() ) return false; return true; }
char BoundingBox::intersect(const BoundingBox & another) const { for(int i=0; i < 3; i++) { if(getMin(i) > another.getMax(i)) return 0; if(getMax(i) < another.getMin(i)) return 0; } return 1; }
void resetProjection() { if(screenHeight == 0) { projection = mat4(); // don't want to divide by zero... return; } BoundingBox* box = currentMesh->getBoundingBox(); projection = mat4() * Perspective(90, (float)screenWidth/screenHeight, 0.0000001, 100000) * LookAt(box->getMax() + box->getSize()/2, box->getMin(), vec4(0, 1, 0, 0)); }
BoundingBox BoundingBox::operator=( const BoundingBox& rhs){ min = rhs.getMin(); max = rhs.getMax(); translation = rhs.getTranslation(); rhs.getRotation( rotation ); return *this; }
bool Ray::intersect (const BoundingBox & bbox, Vec3Df & intersectionPoint) const { const Vec3Df & minBb = bbox.getMin (); const Vec3Df & maxBb = bbox.getMax (); bool inside = true; unsigned int quadrant[NUMDIM]; register unsigned int i; unsigned int whichPlane; Vec3Df maxT; Vec3Df candidatePlane; for (i=0; i<NUMDIM; i++) if (origin[i] < minBb[i]) { quadrant[i] = LEFT; candidatePlane[i] = minBb[i]; inside = false; } else if (origin[i] > maxBb[i]) { quadrant[i] = RIGHT; candidatePlane[i] = maxBb[i]; inside = false; } else { quadrant[i] = MIDDLE; } if (inside) { intersectionPoint = origin; return (true); } for (i = 0; i < NUMDIM; i++) if (quadrant[i] != MIDDLE && direction[i] !=0.) maxT[i] = (candidatePlane[i]-origin[i]) / direction[i]; else maxT[i] = -1.; whichPlane = 0; for (i = 1; i < NUMDIM; i++) if (maxT[whichPlane] < maxT[i]) whichPlane = i; if (maxT[whichPlane] < 0.) return (false); for (i = 0; i < NUMDIM; i++) if (whichPlane != i) { intersectionPoint[i] = origin[i] + maxT[whichPlane] *direction[i]; if (intersectionPoint[i] < minBb[i] || intersectionPoint[i] > maxBb[i]) return (false); } else { intersectionPoint[i] = candidatePlane[i]; } return (true); }
BoundingBox transformBoundingBox(BoundingBox b, mat4 transform) { /* Bounding box * ca-------cb * | | * | | * | | * cd-------cc */ //mat4 transform = getCurrentModelviewMatrix(); vec2 min2, max2,ca,cb,cc,cd; // get the min and max vec2's of the boundingBox b.getMin(min2); b.getMax(max2); // create the corner points of the bounding box ca[0] = min2[0]; ca[1] = max2[1]; cb[0] = max2[0]; cb[1] = max2[1]; cc[0] = max2[0]; cc[1] = min2[1]; cd[0] = min2[0]; cd[1] = min2[1]; // convert the four corner points into vec4 vec4 ca4(ca[0],ca[1],0,1), cb4(cb[0],cb[1],0,1), cc4(cc[0],cc[1],0,1), cd4(cd[0],cd[1],0,1); // transform the corner points ca4 = transform*ca4; cb4 = transform*cb4; cc4 = transform*cc4; cd4 = transform*cd4; // find the new bounding box after the transformation min2[0] = min(min(min(ca4[0],cb4[0]),cc4[0]),cd4[0]); min2[1] = min(min(min(ca4[1],cb4[1]),cc4[1]),cd4[1]); max2[0] = max(max(max(ca4[0],cb4[0]),cc4[0]),cd4[0]); max2[1] = max(max(max(ca4[1],cb4[1]),cc4[1]),cd4[1]); // make the bounding box and return it return BoundingBox(min2,max2); }
void PhotonMapping::TracePhotons() { std::cout << "trace photons" << std::endl; // first, throw away any existing photons delete kdtree; // consruct a kdtree to store the photons BoundingBox *bb = mesh->getBoundingBox(); Vec3f min = bb->getMin(); Vec3f max = bb->getMax(); Vec3f diff = max-min; min -= 0.001*diff; max += 0.001*diff; kdtree = new KDTree(BoundingBox(min,max)); // photons emanate from the light sources const std::vector<Face*>& lights = mesh->getLights(); // compute the total area of the lights double total_lights_area = 0; for (unsigned int i = 0; i < lights.size(); i++) { total_lights_area += lights[i]->getArea(); } // shoot a constant number of photons per unit area of light source // (alternatively, this could be based on the total energy of each light) for (unsigned int i = 0; i < lights.size(); i++) { double my_area = lights[i]->getArea(); int num = args->num_photons_to_shoot * my_area / total_lights_area; // the initial energy for this photon Vec3f energy = my_area/double(num) * lights[i]->getMaterial()->getEmittedColor(); Vec3f normal = lights[i]->computeNormal(); for (int j = 0; j < num; j++) { Vec3f start = lights[i]->RandomPoint(); // the initial direction for this photon (for diffuse light sources) Vec3f direction = RandomDiffuseDirection(normal); TracePhoton(start,direction,energy,0); } } }
// this only test intersection with axis alligned bounding box bool Ray::intersectSimpleBbox(const BoundingBox& box, double & t) const { vec3 v = direction; point3 p = startPoint; point3 boxMin = box.getMin(); point3 boxMax = box.getMax(); double tnear{ -1.0 }, tfar{ INFINITY }; // test X,Y,Z for(int i = 0; i<3;i++) { if (v[i] == 0) { if (p[i] < boxMin[i] || p[i] > boxMax[i]) { return false; } } // if survive parallel test double t1 = (boxMin[i] - p[i]) / v[i]; double t2 = (boxMax[i] - p[i]) / v[i]; if(t1 > t2) { swap(t1, t2); } if(t1 > tnear) { tnear = t1; } if(t2 < tfar) { tfar = t2; } if(tnear > tfar) { return false; } if(tfar < 0) { return false; } } // check if eye is in the box if(tnear) { t = tnear; }else { t = tfar; } return true; }
bool OpenGLRenderer::renderBoundingBox(const BoundingBox &box, const glm::mat4 &modelMatrix, const glm::vec3 &color, Camera &camera, RenderTarget &renderTarget) { /* Generate the box lines */ GLfloat boxFaces[] = { /* First face */ box.getMin().x, box.getMin().y, box.getMin().z, box.getMax().x, box.getMin().y, box.getMin().z, box.getMin().x, box.getMin().y, box.getMin().z, box.getMin().x, box.getMax().y, box.getMin().z, box.getMin().x, box.getMin().y, box.getMin().z, box.getMin().x, box.getMin().y, box.getMax().z, /*--*/ box.getMax().x, box.getMax().y, box.getMax().z, box.getMin().x, box.getMax().y, box.getMax().z, box.getMax().x, box.getMax().y, box.getMax().z, box.getMax().x, box.getMin().y, box.getMax().z, box.getMax().x, box.getMax().y, box.getMax().z, box.getMax().x, box.getMax().y, box.getMin().z, /*--*/ box.getMin().x, box.getMax().y, box.getMax().z, box.getMin().x, box.getMax().y, box.getMin().z, box.getMin().x, box.getMax().y, box.getMax().z, box.getMin().x, box.getMin().y, box.getMax().z, /*--*/ box.getMax().x, box.getMin().y, box.getMax().z, box.getMax().x, box.getMin().y, box.getMin().z, box.getMax().x, box.getMin().y, box.getMax().z, box.getMin().x, box.getMin().y, box.getMax().z, /*--*/ box.getMax().x, box.getMax().y, box.getMin().z, box.getMin().x, box.getMax().y, box.getMin().z, box.getMax().x, box.getMax().y, box.getMin().z, box.getMax().x, box.getMin().y, box.getMin().z, }; /* Calculate MVP matrix, bounding box coordinates are already in world coordinates */ glm::mat4 MVP = camera.getPerspectiveMatrix() * camera.getViewMatrix() * modelMatrix; __(glEnable(GL_DEPTH_TEST)); /* Bind the render target */ renderTarget.bind(); { GLuint boxPosVAO, boxPosVBO; /* Bind program to upload the uniform */ _renderBoundingBox.attach(); /* Send our transformation to the currently bound _renderBoundingBox, in the "MVP" uniform */ _renderBoundingBox.setUniformMat4("u_MVPMatrix", &MVP); _renderBoundingBox.setUniformVec3("u_boxColor", const_cast<glm::vec3 &>(color)); __(glGenVertexArrays(1, &boxPosVAO)); __(glBindVertexArray(boxPosVAO)); __(glGenBuffers(1, &boxPosVBO)); __(glBindBuffer(GL_ARRAY_BUFFER, boxPosVBO)); __(glBufferData(GL_ARRAY_BUFFER, sizeof boxFaces, boxFaces, GL_STATIC_DRAW)); __(glEnableVertexAttribArray(0)); __(glVertexAttribPointer(0, // attribute. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void *)0 // array buffer offset )); __(glDrawArrays(GL_LINES, 0, sizeof boxFaces / (2 * sizeof *boxFaces))); __(glBindVertexArray(0)); __(glDeleteBuffers(1, &boxPosVBO)); __(glDeleteVertexArrays(1, &boxPosVAO)); /* Unbind */ _renderBoundingBox.detach(); } renderTarget.unbind(); return true; }