Sphere Sphere::calculateBoundingSphere( const vector<Vec3f> &points ) { // compute minimal and maximal bounds Vec3f min(points[0]), max(points[0]); for( size_t i = 1; i < points.size(); ++i ) { if( points[i].x < min.x ) min.x = points[i].x; else if( points[i].x > max.x ) max.x = points[i].x; if( points[i].y < min.y ) min.y = points[i].y; else if( points[i].y > max.y ) max.y = points[i].y; if( points[i].z < min.z ) min.z = points[i].z; else if( points[i].z > max.z ) max.z = points[i].z; } // compute center and radius Vec3f center = 0.5f * ( min + max ); float maxDistance = center.distanceSquared( points[0] ); for( size_t i = 1; i < points.size(); ++i ) { float dist = center.distanceSquared( points[i] ); if( dist > maxDistance ) maxDistance = dist; } return Sphere( center, math<float>::sqrt( maxDistance ) ); }
float RayMarcher::sampleDensity( const Vec3f &v ) { float d = 0.0f; for( vector<Sphere>::const_iterator sphIt = mSpheres.begin(); sphIt != mSpheres.end(); ++sphIt ) { float rSquared = sphIt->getRadius() * sphIt->getRadius(); float dSquared = v.distanceSquared( sphIt->getCenter() ); if( dSquared < rSquared ) { d = std::max( d, 1.0f - math<float>::sqrt( dSquared / rSquared ) ); // d += 1.0f - math<float>::sqrt( dSquared / rSquared ); } } if( d > 0.001f ) { d *= d * 4; d *= 0.3f + mPerlin.fBm( v * 0.93f ) * 0.7f; } return d; }