...
The actual work of this extension is done in intersect. This is the speed critical routine. Make every effort to optimize this function. Do not allocate memory in it. Avoid any OS and/or SDK function calls in this critical routine. Most of the memory can be pre-allocated in initializeForRendering. If you want to access the global scene pointer, store it in initializeForRendering and use it later. This can save a huge amount of time.
...
One of the other three functions getProxyDisplay* should be implemented if the extension writer wants to draw an approximate proxy of the object in the Studio viewport. For example, the MaxwellGrass extension uses getProxyDisplayLines to draw some lines representing grass strands.
...
virtual void getBoundingBox( Cpoint *bboxPoints, float time ) = 0;
Return the bounding box of the extension object, enclosing all subvolumes. This box should be arbitrarily oriented in order to be the smallest box that surrounds the object.
The ordering of the box points is as follows:
The points must be in local coordinates of the extension object.
Arguments
Cpoint* bboxPoints: output, 0-based array of eight points.
float time : input, time of evaluation of the box.
getNumSubVolumes
virtual dword getNumSubVolumes( void );
Return the number of subvolumes that the object is subdivided into.
Arguments
None
Returns
Number of subvolumes.
getSubVolumeBoundingBox
virtual void getSubVolumeBoundingBox( Cpoint *bboxPoints, dword subVolumeIndex, float time );
Return the bounding box of the subvolume, in local coordinates of the extension object, as a 0-based array of eight points, at the given time.
Arguments
Cpoint* bboxPoints : output, 0-based array of eight points.
dword subVolumeIndex : input, index of the subvolume to return its box.
float time : input, time of evaluation of the box.
Returns
Nothing.
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
#include <math.h> #include "extensionmanager.h" #include "geometryextension.h" #include "maxwell.h" #ifndef DEG2RAD #define DEG2RAD(d) ((d) * 3.14159265358979323846 / 180.0) #endif class SphereRenderExtension : public CgeometryProceduralExtension { DECLARE_EXTENSION_METHODS( "SphereRenderExample", SphereRenderExtension, 1 ) Cmaxwell* pMaxwellLocal; double radius; public: SphereRenderExtension() { getExtensionData()->createDouble( "Radius", 1.00, 0, 1000000 ); } ~SphereRenderExtension() { } bool initializeForRendering ( Cmaxwell* pMaxwell ) { pMaxwellLocal = pMaxwell; getExtensionData()->getDouble( "Radius", radius ); return true; } //Helper function to spit messages to maxwell. void printMessage( const char* text, const int code ) { if( pMaxwellLocal != NULL ) { char pMessage[ 1024 ]; sprintf ( pMessage, "[Extension %s] %s", getName(), text ); pMaxwellLocal->printMessage( pMessage, code ); } } dword getNumSubVolumes( void ) { return 1;//We just have one region surrounding the whole sphere }; bool intersect( Cmaxwell::Cobject* object, const Cpoint& origin, const Cvector& dir, real time, const dword subVolumeIndex, Cvector* pNormal, Cvector* pLocalImpact, CfVector &data, Cvector& parametricUVW, Cvector& tangentU, Cvector& tangentV ) { real dist, a, b, disc, t0, t1, sqr; dist = -1.0; //Assume sphere centered in ( 0, 0, 0 ) in local coordinates a = 2*( dir.x*origin.x + dir.y*origin.y + dir.z*origin.z ); b = origin.x*origin.x + origin.y*origin.y + origin.z*origin.z - radius*radius; disc = a*a - 4*b; if ( disc < 0.0 ) { return false; } sqr = sqrt ( disc ); t0 = ( -a - sqr ) * 0.5; t1 = ( -a + sqr ) * 0.5; if ( t0 <= 0.0 ) { if ( t1 > 0.0 ) { dist = t1; } else { return false; } } else { if ( t0 < t1 ) dist = t0; else dist = t1; } Cvector p; p.assign( origin + dir * dist );//Point of intersection in local coordinates pLocalImpact->assign( p ); Cvector normal; normal.assign( p ); pNormal->assign( normal );//No need to normalize. Done later on demand. return true; } void getBoundingBox( Cvector& bmin, Cvector& bmax, float time ) { bmin.assign( -radius, -radius, -radius ); bmax.assign( radius, radius, radius ); } }; EXPORT_GEOMETRY_PROCEDURAL_EXTENSION( SphereRenderExtension ) |