#include <math.h>
#include "extensionmanager.h"
#include "geometryextension.h"
#include "maxwell.h"
#include "maxwellversions.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, Cmaxwell::Cobject& proceduralObject )
{
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 );
}
};
extern "C" ALWAYSEXPORT int getSdkVersion()
{
return MAXWELL_SDK_VERSION;
}
extern "C" ALWAYSEXPORT int StartExtension( CextensionManager& extensionManager )
{
int i = 0;
if ( extensionManager.registerGeometryProceduralExtension( new SphereRenderExtension ) ) i++;
return i;
} |