MetaBall.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   MetaBall.cpp
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Spring 2008
00006    
00007    @brief
00008       A MetaObject exerts a positive or negative 'charge' in a scalar field, 
00009    whose isocontours (level sets) define blobby surfaces with different 
00010    threshold values corresponding to the contour level.  MetaObjects positively
00011    or negatively affect their neighboring MetaObjects depending on their 
00012    'strength' and 'negative' attributes.
00013       A MetaBall exerts a non-zero charge (aka influence) over a spherical 
00014    region emanating from a single point, 'position', out to a maximum distance 
00015    of 'radius'.
00016    
00017    @param
00018       position - center of sphere defining region of influence
00019    @param
00020       radius   - maximum extent of influence
00021    
00022    @see also Blob
00023    @see also MetaObject
00024    <!-------------------------------------------------------------------->**/
00025 
00026 #include "MetaBall.h"
00027 
00028 #define MAX_UNIT_DISTANCE           (create_real(0.707))
00029 #define MAX_UNIT_DISTANCE_SQUARED   (create_real(0.5))
00030 
00031 void MetaBall::init() {
00032    MetaObject::init();
00033    
00034    const Vector3 &position = getValue<Vector3>("position", Vector3(m_position.data));
00035    
00036    m_position = Point3(position[0], position[1], position[2]);
00037    m_radius   = getValue<real_t> ("radius", m_radius);
00038    
00039    ASSERT(m_radius >= 0);
00040    
00041    const real_t maxDist  = MAX_UNIT_DISTANCE * m_radius;
00042    const Vector3 &offset = Vector3(maxDist, maxDist, maxDist);
00043    
00044    m_aabb = AABB(position - offset, position + offset);
00045    //cerr << "MetaBall: " << m_aabb << endl;
00046    //cerr << "\t" << "radius: " << m_radius << endl;
00047 }
00048 
00049 AABB MetaBall::getAABB() const {
00050    return m_aabb;
00051 }
00052 
00053 real_t MetaBall::evaluate(const Point3 &pt) const {
00054    real_t distSquared = (pt - m_position).getMagnitude2();
00055    distSquared       /= m_radius * m_radius;
00056    
00057    // same as if sqrt(distSquared) < MAX_UNIT_DISTANCE
00058    if (distSquared < MAX_UNIT_DISTANCE_SQUARED) {
00059       // charge(x)    = m_strength * intensity(||x - origin||)
00060       // intensity(d) = d^4 - d^2 + 0.25
00061       // 
00062       // note: (d^2 * (d^2 - 1)) = (d^2)^2 - (d^2) = d^4 - d^2
00063       
00064       return m_strength * (distSquared * (distSquared - 1) + 0.25);
00065    }
00066    
00067    return 0;
00068 }
00069 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6