...
Given a ray (direction and origin), calculate and return a point and normal on the surface of the object.
Arguments
Cmaxwell::Cobject& object
: input, reference to the extension object.
const Cpoint& rayOrigin
: input, origin of the ray in local coordinates of the extension object.
const Cvector& rayDir
: input, direction of the ray in local coordinates of the extension object.
real time
: input, ranges from 0.0 to 1.0, time of the frame at which the intersection is evaluated.
const dword subVolumeIndex
: input, index of the current subvolume.
Cvector* pNormal
: output, return here the calculated normal direction to the surface at the intersection point, in local coordinates of the extension object.
Cvector* pLocalImpact
: output, intersection point in local coordinates of the extension object.
CfVector& data
: private, don't use.
Cvector& parametricUVW
: output, in case of analytical surfaces, return here the natural parametric coordinates of the intersection point. Needed later to calculate texture coordinates if using custom UV generators.
Cvector& tangentU, tangentV
: output, tangent vectors to the surface. If P=p(u,v), then tu = dP/du and tv = dP/dv;
Returns
true
on intersection, false
otherwise.
getBoundingBox
virtual void getBoundingBox( Cpoint *bboxPoints, float time ) = 0;
...
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.
Returns
Nothing.
getNumSubVolumes
virtual dword getNumSubVolumes( void );
Return the number of subvolumes that the object is subdivided into.
Arguments
None
Returns
Number of subvolumes.
getSubVolumeBoundingBox
...
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. See getBoundingBox for the point ordering.
dword subVolumeIndex
: input, index of the subvolume to return its box.
float time
: input, time of evaluation of the box.
Returns
Nothing.
getNumberOfUVGenerators
...
Returns the number of implemented custom UV generators.
Arguments
None.
Returns
Number of UV generators. Max 255.
...
Return a string with the name of the UV generator.
Arguments
byte index
: input, index of the generator, max 255.
Returns
String with the generator name. If index > numberOfUVGenerators or index < 0, return NULL.
...
Calculates the UV texture coordinates for the given point "point
". When dealing with analytical surfaces, it's often more convenient to use "parametricUVW
" as input data. "normal
" is the normal at the intersection point.
Arguments
CfVector& uvw
: output, calculated texture coordinates, values range from 0.0 to 1.0.
const Cpoint& point
: input, intersection point.
const Cpoint& normal
: input, normal at intersection point.
dword dword iGenerator
: input, index of the chosen generator.
dword subVolIndex
: input, index of the subvolume.
const Cvector& parametricUVW
: input, natural parametric coordinates of the surface, calculated in intersect.
Returns
1 on success, 0 otherwise.
...
Helper function for the render engine. Tests whether the box given by "bboxPoints
" and that of the subvolume indexed by "subVolumeIndex
" overlap.
Arguments
Cpoint* bboxPoints
: input, 0-based array of eight points. See getBoundingBox for the point ordering.
dword subVolumeIndex
: input, index of the subvolume to compare its box to.
bool forceHalfTime
: input, type of subvolume box for evaluation. If forceHalfTime is true, the subvolume box to comapre is at time 0.5. If true, it is the smallest box that encloses the swept space of the object in the subvolume from time 0.0 to time 1.0.
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 ) |