void MyDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const float window_aspect = window_width/static_cast<float>(window_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // from -100 to 100 in z // const GLfloat far = 201; const GLfloat theta = 40.0; if (near == -1) { BoundingBox3f bb = scene.bbox_full(); const float zoom = 1; const float3 size = bb.size(); const float3 eye = make_float3( 0, 0, size.s[2]/2 + ((size.s[1]/2)/tan(20*M_PI/180.0))*1.1) * zoom; near = 1; far = length(eye) + length(size)*2; } gluPerspective(theta, window_aspect, near, far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); scene.Display(); glFlush(); glutSwapBuffers(); }
float32 getMinPrj(const BoundingBox3f &bb, Vector3f origin, Vector3f prjVector) { float32 minPrj = (bb.getCorner(0) - origin)*prjVector; for (card32 i=1; i<8; i++) { float32 prj = (bb.getCorner(i) - origin)*prjVector; if (prj<minPrj) minPrj = prj; } return minPrj; }
void ObjectFactory::generateRandomObjects(const BoundingBox3f& region, const Duration& duration, double forceRadius, int forceNumRandomObjects) { Time start(Time::null()); Time end = start + duration; Vector3f region_extents = region.extents(); uint32 nobjects = GetOptionValue<uint32>(OBJECT_NUM_RANDOM); if (forceNumRandomObjects) nobjects=forceNumRandomObjects; if (nobjects == 0) return; bool simple = GetOptionValue<bool>(OBJECT_SIMPLE); bool only_2d = GetOptionValue<bool>(OBJECT_2D); std::string motion_path_type = GetOptionValue<String>(OBJECT_STATIC); float driftX = GetOptionValue<float>(OBJECT_DRIFT_X); float driftY = GetOptionValue<float>(OBJECT_DRIFT_Y); float driftZ = GetOptionValue<float>(OBJECT_DRIFT_Z); float percent_queriers = GetOptionValue<float>(OBJECT_QUERY_FRAC); Vector3f driftVecDir(driftX,driftY,driftZ); for(uint32 i = 0; i < nobjects; i++) { UUID id = randomUUID(); ObjectInputs* inputs = new ObjectInputs; Vector3f startpos = region.min() + Vector3f(randFloat()*region_extents.x, randFloat()*region_extents.y, (only_2d ? 0.5 : randFloat())*region_extents.z); double radval = forceRadius; if (!radval) radval=10; float bounds_radius = (simple ? radval : (randFloat()*2*radval)); //SILOG(oh,error,"Creating "<<id.toString()<<" radius "<<bounds_radius); inputs->localID = mLocalIDSource++; if (motion_path_type == "static")//static inputs->motion = new StaticMotionPath(start, startpos); else if (motion_path_type == "drift") //drift { // inputs->motion = new OSegTestMotionPath(start, end, startpos, 3, Duration::milliseconds((int64)1000), region, zfactor); // FIXME inputs->motion = new OSegTestMotionPath(start, end, startpos, 3, Duration::milliseconds((int64)1000), region, 0.5, driftVecDir); // FIXME } else //random inputs->motion = new RandomMotionPath(start, end, startpos, 3, Duration::milliseconds((int64)1000), region, (only_2d ? 0.0 : 1.0)); // FIXME inputs->bounds = BoundingSphere3f( Vector3f(0, 0, 0), bounds_radius ); inputs->registerQuery = (randFloat() <= percent_queriers); inputs->queryAngle = SolidAngle(SolidAngle::Max / 900.f); // FIXME how to set this? variability by objects? inputs->connectAt = Duration::seconds(0.f); inputs->startTimer = Network::IOTimer::create(mContext->ioService); mObjectIDs.insert(id); mInputs[id] = inputs; } }
// static BoundingBox3f BoundingBox3f::unite( const BoundingBox3f& b0, const BoundingBox3f& b1 ) { Vector3f b0Min = b0.minimum(); Vector3f b0Max = b0.maximum(); Vector3f b1Min = b1.minimum(); Vector3f b1Max = b1.maximum(); Vector3f newMin( min( b0Min.x, b1Min.x ), min( b0Min.y, b1Min.y ), min( b0Min.z, b1Min.z ) ); Vector3f newMax( max( b0Max.x, b1Max.x ), max( b0Max.y, b1Max.y ), max( b0Max.z, b1Max.z ) ); return BoundingBox3f( newMin, newMax ); }
// static BoundingBox3f BoundingBox3f::intersect( const BoundingBox3f& b0, const BoundingBox3f& b1 ) { Vector3f b0Min = b0.minimum(); Vector3f b0Max = b0.maximum(); Vector3f b1Min = b1.minimum(); Vector3f b1Max = b1.maximum(); Vector3f newMin( max( b0Min.x, b1Min.x ), max( b0Min.y, b1Min.y ), max( b0Min.z, b1Min.z ) ); Vector3f newMax( min( b0Max.x, b1Max.x ), min( b0Max.y, b1Max.y ), min( b0Max.z, b1Max.z ) ); for(int i = 0; i < 3; ++i) newMax[i] = max(newMax[i], newMin[i]); return BoundingBox3f( newMin, newMax ); }
bool SkeletonHand::containsBBox(const BoundingBox3f &b) { if (b.contains(palm.position)) return true; if (b.contains(handJointPosition)) return true; for (int i = 0; i < 5; i++) { if (b.contains(finger[i].position)) return true; for (int j = 0; j < mesh.nrOfJoints; j++) if (b.contains(finger[i].jointPositions[j])) return true; } return false; }
bool BoundingBox3f::overlaps( const BoundingBox3f& other ) { bool bOverlapsInDirection[3]; Vector3f otherMin = other.minimum(); Vector3f otherMax = other.maximum(); for( int i = 0; i < 3; ++i ) { bool bMinInside0 = ( otherMin[i] >= m_min[i] ) && ( otherMin[i] <= m_max[i] ); bool bMinInside1 = ( m_min[i] >= otherMin[i] ) && ( m_min[i] <= otherMax[i] ); bool bMaxInside0 = ( otherMax[i] >= m_min[i] ) && ( otherMax[i] <= m_max[i] ); bool bMaxInside1 = ( m_max[i] >= otherMin[i] ) && ( m_max[i] <= otherMax[i] ); bool bMinInside = bMinInside0 || bMinInside1; bool bMaxInside = bMaxInside0 || bMaxInside1; bOverlapsInDirection[i] = bMinInside || bMaxInside; } return bOverlapsInDirection[0] && bOverlapsInDirection[1] && bOverlapsInDirection[2]; }
BoundingBox3f Mesh::getClippedBoundingBox(uint32_t index, const BoundingBox3f &bbox) const { /* Reserve room for some additional vertices */ Point3d vertices1[NORI_TRICLIP_MAXVERTS], vertices2[NORI_TRICLIP_MAXVERTS]; int nVertices = 3; /* The kd-tree code will frequently call this function with almost-collapsed bounding boxes. It's extremely important not to introduce errors in such cases, otherwise the resulting tree will incorrectly remove triangles from the associated nodes. Hence, do the following computation in double precision! */ for (int i=0; i<3; ++i) vertices1[i] = m_vertexPositions[m_indices[3*index+i]].cast<double>(); for (int axis=0; axis<3; ++axis) { nVertices = sutherlandHodgman(vertices1, nVertices, vertices2, axis, bbox.min[axis], true); nVertices = sutherlandHodgman(vertices2, nVertices, vertices1, axis, bbox.max[axis], false); } BoundingBox3f result; for (int i=0; i<nVertices; ++i) result.expandBy(vertices1[i].cast<float>()); result.clip(bbox); return result; }
void CommunicationCache::insert(const UUID& uuid, const OSegEntry& sID) { BoundingBoxList bboxes = mCSeg->serverRegion(sID.server()); BoundingBox3f bbox = bboxes[0]; for(uint32 i = 1; i< bboxes.size(); i++) bbox.mergeIn(bboxes[i]); float xer = mCentralX - ((bbox.max().x + bbox.min().x)/2); float yer = mCentralY - ((bbox.max().y + bbox.min().y)/2); float zer = mCentralZ - ((bbox.max().z + bbox.min().z)/2); float distance = sqrt(xer*xer + yer*yer + zer*zer); float logger = log(mDistScaledUnits*distance); float lookupWeight = sID.radius()/(mDistScaledUnits* distance*distance*logger*logger); boost::lock_guard<boost::mutex> lck(mMutex); mCompleteCache.insert(uuid,sID.server(),0,0,0,0,sID.radius(),lookupWeight,1); }
CommunicationCache::CommunicationCache(SpaceContext* spctx, float scalingUnits, CoordinateSegmentation* cseg,uint32 cacheSize) : mCompleteCache(.2,"CommunicationCache",&commCacheScoreFunction,&commCacheScoreFunctionPrint,spctx,cacheSize,FLT_MAX), mDistScaledUnits(scalingUnits), mCSeg(cseg), ctx(spctx), mCacheSize(cacheSize) { BoundingBoxList bboxes = mCSeg->serverRegion(ctx->id()); BoundingBox3f bbox = bboxes[0]; for(uint32 i = 1; i< bboxes.size(); i++) bbox.mergeIn(bboxes[i]); mCentralX = (bbox.max().x + bbox.min().x)/2; mCentralY = (bbox.max().y + bbox.min().y)/2; mCentralZ = (bbox.max().z + bbox.min().z)/2; }
bool LoadMonitor::isAdjacent(BoundingBox3f& box1, BoundingBox3f& box2) { if (box1.min().x == box2.max().x || box1.max().x == box2.min().x) { //if box1.miny or box1.maxy lies between box2.maxy and box2.miny, return true; //if box2.miny or box2.maxy lies between box1.maxy and box1.miny, return true; if (box2.min().y <= box1.min().y && box1.min().y <= box2.max().y) return true; if (box2.min().y <= box1.max().y && box1.max().y <= box2.max().y) return true; if (box1.min().y <= box2.min().y && box2.min().y <= box1.max().y) return true; if (box1.min().y <= box2.max().y && box2.max().y <= box1.max().y) return true; } if (box1.min().y == box2.max().y || box1.max().y == box2.min().y) { //if box1.minx or box1.maxx lies between box2.maxx and box2.minx, return true; //if box2.minx or box2.maxx lies between box1.maxx and box1.minx, return true; if (box2.min().x <= box1.min().x && box1.min().x <= box2.max().x) return true; if (box2.min().x <= box1.max().x && box1.max().x <= box2.max().x) return true; if (box1.min().x <= box2.min().x && box2.min().x <= box1.max().x) return true; if (box1.min().x <= box2.max().x && box2.max().x <= box1.max().x) return true; } return false; }
// static FrustumUtils::IntersectionResult FrustumUtils::intersectBoundingBox( const BoundingBox3f& box, Plane3f planes[ 6 ] ) { auto boxCorners = box.corners(); // by default, we assume the box is completely inside IntersectionResult result = INSIDE; // and keep track, for each corner of the box // how many vertices are inside vs outside int nVerticesInside; int nVerticesOutside; // for each plane do ... for( int i = 0; i < 6; ++i ) { // reset counters for corners nVerticesInside and nVerticesOutside nVerticesInside = 0; nVerticesOutside = 0; // for each corner of the box do ... // get nVerticesOutside of the cycle as soon as a box as corners // both inside and nVerticesOutside of the frustum for( int k = 0; k < 8 && ( nVerticesInside == 0 || nVerticesOutside == 0 ); k++ ) { // is the corner inside or outside? float d = planes[ i ].distance( boxCorners[ k ] ); if( d < 0 ) { ++nVerticesInside; } else { ++nVerticesOutside; } } // if none of the box corners are on the inside halfspace // then it's guaranteed to be outside, done if( nVerticesInside == 0 ) { return OUTSIDE; } // otherwise, at least some of them are inside // but if some of them are *also* outside // then we know for now that it intersects this plane // (but it's not guaranteed to actually intersect the entire frustum) else if( nVerticesOutside != 0 ) { result = INTERESECTING; } // otherwise, we know that some vertices are inside // and none are outside // --> this box is completely inside (for this plane anyway) else { assert( nVerticesInside == 8 ); assert( nVerticesOutside == 0 ); } } return result; }
// virtual Matrix4f DirectionalLight::lightMatrix( const Camera& camera, const BoundingBox3f& sceneBoundingBox ) { const float feather = 1.01; Matrix3f lightLinear = lightBasis(); Vector3f eye = camera.getEye(); // get the corners of the view frustum in light coordinates // with the z = 0 plane at the eye QVector< Vector3f > frustumCorners = camera.getFrustumCorners(); BoundingBox3f frustumBB; for( int i = 0; i < frustumCorners.size(); ++i ) frustumBB.enlarge(frustumCorners[i]); BoundingBox3f sceneAndFrustum = BoundingBox3f::intersect(frustumBB, sceneBoundingBox); QVector< Vector3f > sceneCorners = sceneBoundingBox.corners(); QVector< Vector3f > sceneAndFrustumCorners = sceneAndFrustum.corners(); for( int i = 0; i < sceneAndFrustumCorners.size(); ++i ) { sceneAndFrustumCorners[ i ] = lightLinear * ( sceneAndFrustumCorners[ i ] - eye ); sceneCorners[ i ] = lightLinear * ( sceneCorners[ i ] - eye ); } BoundingBox3f inLightCoordinates; for(int i = 0; i < sceneAndFrustumCorners.size(); ++i) inLightCoordinates.enlarge(sceneAndFrustumCorners[i]); Vector3f maxCorner = inLightCoordinates.maximum(); Vector3f minCorner = inLightCoordinates.minimum(); Vector3f center = inLightCoordinates.center(); maxCorner = center + feather * (maxCorner - center); minCorner = center + feather * (minCorner - center); // add eye point for(int j = 0; j < 3; ++j) { maxCorner[j] = qMax( maxCorner[ j ], 0.0f ); minCorner[j] = qMin( minCorner[ j ], 0.0f ); } // bound the near plane to the scene for( int i = 0; i < sceneCorners.size(); ++i ) { minCorner[2] = qMin( minCorner[2], sceneCorners[ i ][ 2 ] ); } // finally, compute the full light matrix Matrix4f lightMatrix; lightMatrix.setSubmatrix3x3( 0, 0, lightLinear ); Vector3f origin = 0.5 * ( minCorner + maxCorner ); origin[2] = minCorner[2]; lightMatrix.setCol( 3, Vector4f( -origin, 1.f ) - Vector4f( lightLinear * eye, 0.f ) ); for(int i = 0; i < 3; ++i) { lightMatrix.setRow( i, lightMatrix.getRow( i ) * ( ( i == 2 ) ? 1.f : 2.f ) / ( maxCorner[i] - minCorner[i] ) ); } return lightMatrix; }
void LoadBalancer::service() { boost::mutex::scoped_lock overloadedRegionsListLock(mOverloadedRegionsListMutex); boost::mutex::scoped_lock underloadedRegionsListLock(mUnderloadedRegionsListMutex); //splitting overloaded regions for (std::vector<SegmentedRegion*>::iterator it = mOverloadedRegionsList.begin(); it != mOverloadedRegionsList.end(); it++) { uint32 availableSvrIndex = getAvailableServerIndex(); if (availableSvrIndex != INT_MAX) { ServerID availableServer = mAvailableServers[availableSvrIndex].mServer; mAvailableServers[availableSvrIndex].mAvailable = false; SegmentedRegion* overloadedRegion = *it; overloadedRegion->mLeftChild = new SegmentedRegion(overloadedRegion); overloadedRegion->mRightChild = new SegmentedRegion(overloadedRegion); BoundingBox3f region = overloadedRegion->mBoundingBox; float minX = region.min().x; float minY = region.min().y; float maxX = region.max().x; float maxY = region.max().y; float minZ = region.min().z; float maxZ = region.max().z; assert(overloadedRegion->mParent == NULL || overloadedRegion->mSplitAxis != SegmentedRegion::UNDEFINED); if (overloadedRegion->mSplitAxis == SegmentedRegion::Y) { overloadedRegion->mLeftChild->mBoundingBox = BoundingBox3f( region.min(), Vector3f( (minX+maxX)/2.0, maxY, maxZ) ); overloadedRegion->mRightChild->mBoundingBox = BoundingBox3f( Vector3f( (minX+maxX)/2.0,minY,minZ), region.max() ); overloadedRegion->mLeftChild->mSplitAxis = overloadedRegion->mRightChild->mSplitAxis = SegmentedRegion::X; } else { overloadedRegion->mLeftChild->mBoundingBox = BoundingBox3f( region.min(), Vector3f( maxX, (minY+maxY)/2.0, maxZ) ); overloadedRegion->mRightChild->mBoundingBox = BoundingBox3f( Vector3f( minX,(minY+maxY)/2.0,minZ), region.max() ); overloadedRegion->mLeftChild->mSplitAxis = overloadedRegion->mRightChild->mSplitAxis = SegmentedRegion::Y; } overloadedRegion->mLeftChild->mServer = overloadedRegion->mServer; overloadedRegion->mRightChild->mServer = availableServer; std::cout << "Split\n"; std::cout << overloadedRegion->mServer << " : " << overloadedRegion->mLeftChild->mBoundingBox << "\n"; std::cout << availableServer << " : " << overloadedRegion->mRightChild->mBoundingBox << "\n"; mCSeg->mWholeTreeServerRegionMap.erase(overloadedRegion->mServer); mCSeg->mWholeTreeServerRegionMap.erase(availableServer); mCSeg->mLowerTreeServerRegionMap.erase(overloadedRegion->mServer); mCSeg->mLowerTreeServerRegionMap.erase(availableServer); std::vector<SegmentationInfo> segInfoVector; SegmentationInfo segInfo, segInfo2; segInfo.server = overloadedRegion->mServer; segInfo.region = mCSeg->serverRegion(overloadedRegion->mServer); segInfoVector.push_back( segInfo ); segInfo2.server = availableServer; segInfo2.region = mCSeg->serverRegion(availableServer); segInfoVector.push_back(segInfo2); Thread thrd(boost::bind(&DistributedCoordinateSegmentation::notifySpaceServersOfChange,mCSeg,segInfoVector)); mOverloadedRegionsList.erase(it); return; //enough work for this iteration. No further splitting or merging. } else { //No idle servers are available at this time... break; } } //merging underloaded regions for (std::vector<SegmentedRegion*>::iterator it = mUnderloadedRegionsList.begin(); it != mUnderloadedRegionsList.end(); it++) { SegmentedRegion* underloadedRegion = *it; if (underloadedRegion->mParent == NULL) { mUnderloadedRegionsList.erase(it); break; } bool isRightChild = (underloadedRegion->mParent->mRightChild == underloadedRegion); SegmentedRegion* sibling = NULL; if (isRightChild) { sibling = underloadedRegion->mParent->mLeftChild; } else { sibling = underloadedRegion->mParent->mRightChild; } std::vector<SegmentedRegion*>::iterator sibling_it = std::find(mUnderloadedRegionsList.begin(), mUnderloadedRegionsList.end(), sibling); if (sibling_it == mUnderloadedRegionsList.end()) { mUnderloadedRegionsList.erase(it); break; } SegmentedRegion* parent = underloadedRegion->mParent; parent->mServer = parent->mLeftChild->mServer; for (uint32 i=0; i<mAvailableServers.size(); i++) { if (mAvailableServers[i].mServer == parent->mRightChild->mServer) { mAvailableServers[i].mAvailable = true; break; } } mCSeg->mWholeTreeServerRegionMap.erase(parent->mRightChild->mServer); mCSeg->mLowerTreeServerRegionMap.erase(parent->mRightChild->mServer); mCSeg->mWholeTreeServerRegionMap.erase(parent->mLeftChild->mServer); mCSeg->mLowerTreeServerRegionMap.erase(parent->mLeftChild->mServer); std::vector<SegmentationInfo> segInfoVector; SegmentationInfo segInfo, segInfo2; segInfo.server = parent->mRightChild->mServer; segInfo.region = mCSeg->serverRegion(parent->mRightChild->mServer); segInfoVector.push_back( segInfo ); segInfo2.server = parent->mLeftChild->mServer; segInfo2.region = mCSeg->serverRegion(parent->mLeftChild->mServer); segInfoVector.push_back(segInfo2); Thread thrd(boost::bind(&DistributedCoordinateSegmentation::notifySpaceServersOfChange,mCSeg,segInfoVector)); mUnderloadedRegionsList.erase(it); sibling_it = std::find(mUnderloadedRegionsList.begin(), mUnderloadedRegionsList.end(), sibling); mUnderloadedRegionsList.erase(sibling_it); std::cout << "Merged " << parent->mLeftChild->mServer << " : " << parent->mRightChild->mServer << "!\n"; delete parent->mLeftChild; delete parent->mRightChild; parent->mLeftChild = NULL; parent->mRightChild = NULL; break; } }