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
1.5.6