Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This kind of extensions implement camera lenses. This class is defined in mx_cameraextension.h. 

Code Block
class CcameraLensExtension : public CbaseExtension
{
public:
    virtual bool initializeForRendering( Cmaxwell::Ccamera& camera, Cmaxwell* pMaxwell ) = 0;
    
    virtual bool getCameraRay( Cpoint& origin, Cvector& direction, const Cvector2D& bufferPoint ) = 0;

    virtual bool hasArea( void ) const
    {
        return ( false );
    }

    virtual bool supportsBPT( void ) const
    {
        return ( false );
    }

    virtual real onLensToFilm( Cvector2D& filmPoint, const Cvector& direction )
    {
        return ( 0.0 );
    }
};

The most important part of the extension functionality resides in getCameraRay, which must be implemented. The rest are optional functions. hasArea, as it name says, returns whether the lens has area or is it a pinhole kind of lens. supportsBPT tells maxwell if the lens supports bi-directional path tracing.

onLensToFilm does two things. First, returns a point in the film, and second, calculates the probability density function of the input direction. If the direction is not valid, the pdf should be 0.0.

The class extension constructor is used mainly to create the extension parameters (look at the example below) and, possibly, allocate data structures needed throughout the life of the extension. These data structures must be freed in the class destructor. initializeForRendering is called just before rendering starts, and the incoming pMaxwell (always check != NULL ) is useful for accessing the scene if needed.

getCameraRay

virtual bool getCameraRay( Cpoint& origin, Cvector& direction, const Cvector2D& bufferPoint ) = 0;

This is the main function of the extension. Given a point in the film (in [0,xRes-1],[0,yRes-1] range) returns a camera ray with its origin and direction (normalized) in world coordinates. This function is speed critical, so don´t do system calls, allocate or free memory and access files from here.

Arguments

Cpoint& origin, Cvector& direction : output, references to the origin and direction of the ray.

const Cvector2D& bufferPoint :input, point in the 2D buffer from which the ray will start.

Returns

true if the ray is valid, false otherwise.

hasArea

virtual bool hasArea( void ) const;

Returns true if the lens has real area or false if this is an ideal lens (pinhole, spherical, etc).

supportsBPT

virtual bool supportsBPT( void ) const;

Returns true if the lens supports Bidirectional Path Tracing.

onLensToFilm

virtual real onLensToFilm( Cvector2D& filmPoint, const Cvector& direction );

Returns by reference a 2D point in the film in [1,1] coordinates and by value the PDF associated to the given input direction. If the returned PDF is 0.0 the direction is not valid.

Arguments

const Cvector& direction : input, direction for which the PDF and point in the film will be calculated.

Cvector2D& filmPoint : output, point in the film, in the range [0,1]x[0,1].

Returns

PDF of the given input direction.

 

Code Block
titleLens Test Example
class LensExtensionTest : public CcameraLensExtension
{
    DECLARE_EXTENSION_METHODS( "Lens Test", LensExtensionTest, 1 )
public:
    LensExtensionTest();
    ~LensExtensionTest()    { cleanup( pMaxwell_ );    }
    bool initializeForRendering( Cmaxwell::Ccamera& camera, Cmaxwell* pMaxwell );
    void cleanup( Cmaxwell* pMaxwell ){}
    bool getCameraRay( Cpoint& origin, Cvector& direction, const Cvector2D& onDevice );
    bool hasArea( void ) const
    {
        return ( false );
    }
    bool supportsBPT( void ) const
    {
        return ( true );
    }
    /// DATA
    Cmaxwell* pMaxwell_;
    Cbase base_;
    Cpoint to_;
    real scaleToWindow_;
};

Cbase getCameraBase( Cmaxwell::Ccamera& camera, const dword& iStep, Cbase& base, Cpoint& to )
{
    Cpoint from;
    Cvector up;
    real fl, fStop, stepTime;
    camera.getStep( iStep, from, to, up, fl, fStop, stepTime );
    // Calculate base 
    real    cosAng;
    Cpoint focal;
    base.origin = from;
    focal.assign( to );

    base.zAxis.substract( from, to );
    real focalDistance = base.zAxis.norm();
    base.zAxis.scale( 1.0 / focalDistance );
    cosAng = fabs( up.dot( base.zAxis ) );
    if( cosAng > 1.0 - Cnumeric::tolerance )
    {
        up.assign( 0.0, 1.0, 0.0 );
        cosAng = fabs( up.dot( base.zAxis ) );
        if( cosAng > 1.0 - Cnumeric::tolerance )
        {
            up.assign( 0.0, 0.0, 1.0 );
        }
    }
    base.xAxis.cross( up, base.zAxis );
    base.xAxis.normalize();
    base.yAxis.cross( base.zAxis, base.xAxis );
    return ( base );
}

void getFilmData( Cmaxwell::Ccamera& camera, const dword& iStep, real& scaleToWindow, real& scaleToFilm )
{
    if( camera.isNull() )
        return;
    Cpoint from, to;
    Cvector up;
    real fl, fStop, stepTime;
    camera.getStep( iStep, from, to, up, fl, fStop, stepTime );
    Cvector fromToDist;
    fromToDist.substract( from, to ); // FIXED: new base
    real focalDistance = fromToDist.norm();
    real focalLength = fl;

    real radius = 0.5 * ( focalLength / fStop );
    real radius2 = radius * radius;
    real filmDistance = fabs( ( focalLength * focalDistance ) / ( focalDistance - focalLength ) );
    scaleToWindow = 1.0 - ( focalDistance + filmDistance ) / filmDistance;
    scaleToFilm = 1.0 - ( focalDistance + filmDistance ) / focalDistance;
}

LensExtensionTest::LensExtensionTest()
{
    pMaxwell_ = NULL;
}

bool LensExtensionTest::initializeForRendering( Cmaxwell::Ccamera& camera, Cmaxwell* pMaxwell )
{
    pMaxwell_ = pMaxwell;
    real scaleToFilm;
    base_ = getCameraBase( camera, 0, base_, to_ );
    getFilmData( camera, 0, scaleToWindow_, scaleToFilm );
    return ( true );
}

bool LensExtensionTest::getCameraRay( Cpoint& origin, Cvector& direction, const Cvector2D& filmPoint )
{
    // Just a simple pinhole lens test
    origin.assign( base_.origin );
    Cvector2D   scale;
    scale.x = filmPoint.x * scaleToWindow_;
    scale.y = filmPoint.y * scaleToWindow_;
    Cpoint onWindow;
    onWindow.x = to_.x + base_.xAxis.x * scale.x + base_.yAxis.x * scale.y;
    onWindow.y = to_.y + base_.xAxis.y * scale.x + base_.yAxis.y * scale.y;
    onWindow.z = to_.z + base_.xAxis.z * scale.x + base_.yAxis.z * scale.y;
    direction.x = onWindow.x - base_.origin.x;
    direction.y = onWindow.y - base_.origin.y;
    direction.z = onWindow.z - base_.origin.z;
    direction.normalize();
    return ( true );
}

extern "C" ALWAYSEXPORT int getSdkVersion()
{
    return MAXWELL_SDK_VERSION;
}

extern "C" ALWAYSEXPORT int StartExtension( CextensionManager& extensionManager )
{
    int i = 0;
    if( extensionManager.registerCameraLensExtension( new LensExtensionText ) ) i++;
    return i;
}