We're a community of 1076K IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,075,659 Members — Technology Publication meets Social Media

# polymorphism issue

Hello forum,

I believe that i have the design problem that i need to discuss about.

Intersectable is the super-class; Triangle and Sphere are the sub-classes of the Intersectable

i believe that you already realized class inheritance structure. I have the following pure virtual functions declared inside the INTERSECTABLE

virtual bool sampleDirection(const Intersection&,Vector3D&) = 0;

virtual float getPDF(const Intersection&,
const Intersection&) = 0;

Each of the sub-classes are defining the above functions.

There is another class called AreaLight that contains a std::vector as follows:

class LuminaireProbability
{
public:

LuminaireProbability() : mIntersectable(0),mMaterial(0),mLuminaireProbabilityValue(0.0f),
mCumulativeDistributionValue(0.0f)
{
}

~LuminaireProbability()
{
mIntersectable = 0;
mMaterial = 0;
}

//luminaire as an intersectable
Intersectable *mIntersectable;
//material of the intersectable
Material *mMaterial;
//probability of choosing the luminaire
float mLuminaireProbabilityValue;

//cumulative distribution value
float mCumulativeDistributionValue;

};

//the area light contains the reference
//to the geometric object to be the light source
//the geometric object in turn contains the emissive material
//thus providing the illumination
//in this way the type of geometric object automatically determines
//the type of light, in principle it allows any type of the geometric
//object to be a light source
//SOME OF THE ABOVE STATEMENTS DEMANS CHANGE
std::vector<LuminaireProbability*> mLightIntersectables;

//store the selected lumianire from the vector
LuminaireProbability *mSelectedLuminaire;

I have the std::vector populated with a pointer of intersectables of type triangle or sphere along with some other trivial information. Now i have the following function

//calcualate the world position based on the intersection point
bool AreaLight::calculateSampleDirection(const Intersection &intersection,Vector3D &sampleVector)
{

//choose the light intersectables based on the weight of the probaiblity
//that we have calculated in the prepare() function

float selectionProbability = 0.0f;

//create a random instance
RandomGenerator random = RandomGenerator::getRandomInstance();

//create a canonical random number between 0 and 1
selectionProbability = static_cast<float>(random.generateDouble(0,1));

CompareToCDF cdf;
//store the canonical random value
cdf.mRandomValue = selectionProbability;

//   CompareAreaLight cmpAreaLight;

//   //sort the light intersectables based on the luminaire probability value
//   std::sort(mLightIntersectables.begin(),mLightIntersectables.end(),cmpAreaLight);

std::vector<LuminaireProbability*>::iterator it;

it = std::find_if(mLightIntersectables.begin(),mLightIntersectables.end(),cdf);

assert(it != mLightIntersectables.end());

//store the selected luminaire
mSelectedLuminaire = *it;

//I AM GETTING A SEGMENTATION FAULT IN THE FOLLOWING FUNCTION - !!!!!
mSelectedLuminaire->mIntersectable->sampleDirection(intersection,sampleVector);

return true;
}

As mentioned in the code i am getting the segmentation fault that the debugger is not even giving any hint of.

I hope you will be able to help me find out the issue here that i am missing.
Is there any logical mistake i am doing here?

I tried the following as follows , but till i am having the segmentation fault .

...................
if(mSelectedLuminaire != 0)
{
if(mSelectedLuminaire->mIntersectable != 0)
mSelectedLuminaire->mIntersectable->sampleDirection(intersection,sampleVector);
}
......................

Then i ran the GDB and it gave me the following information.

(gdb) backtrace
#0  0x2efd85ba in ?? ()
#1  0x0804e018 in AreaLight::calculateSampleDirection (this=0x80c4d60,
intersection=..., sampleVector=...) at arealight.cpp:151
#2  0x080556ed in Intersection::getShadowRay (this=0xbfffedfc, light=0x80c4d60)
at intersection.cpp:152
#3  0x08069787 in PathTracer::computeDirectIllumination (this=0xbffff220,
intersection=...) at pathtracer.cpp:179
intersection=..., depth=5) at pathtracer.cpp:141
#5  0x0806a63f in PathTracer::trace (this=0xbffff220, ray=..., E=1)
at pathtracer.cpp:127
#6  0x0806a8e0 in PathTracer::tracePixel (this=0xbffff220, x=0, y=1)
at pathtracer.cpp:95
#7  0x0806aa14 in PathTracer::computeImage() [clone ._omp_fn.0] ()
at pathtracer.cpp:53
#8  0x0806ac46 in PathTracer::computeImage (this=0xbffff220)
at pathtracer.cpp:47
#9  0x0804c397 in main (argc=1, argv=0xbffff304) at main.cpp:504
(gdb)

I hope some one in the forum wil be able to help me to debug this issue.

Where should i look into now?

Regards

3
Contributors
4
Replies
2 Hours
Discussion Span
8 Months Ago
Last Updated
5
Views
sajis997
Newbie Poster
3 posts since Sep 2012
Reputation Points: 0
Skill Endorsements: 0

can you post the code for sampleDirection()?

NathanOliver
Posting Virtuoso
1,513 posts since Apr 2009
Reputation Points: 269
Skill Endorsements: 3

Hi

Since Sphere and Triangle are both the sub-class of intersectables , both of them is defining the sampleDirection() function as follows:

//get the sample point from the sphere
//based intersection point
bool Sphere::sampleDirection(const Intersection &intersection,Vector3D &sampleDirection)
{
//get the random instance
//to generate the canonical random number [0,1)
RandomGenerator random = RandomGenerator::getRandomInstance();

//declare a sphere center
Point3D center = Point3D(0.0f,0.0f,0.0f);
//transform the sphere center in the world space
Point3D centerWorld = mWorldTransform * center;

//get the intersection position in the world space
Point3D intersectionPoint = intersection.mPosition ;

//create a point from the intersection point to the center of the sphere
Point3D intersectionToCenter =  centerWorld - intersectionPoint;

//create the coordinate system for sampling - w, u, and v
//initialize a vector from the difference of points
Vector3D w = Vector3D(intersectionToCenter);

//get the length between the intersection point and
//sphere center
float d = w.length();

//if the length is less than the radius then return false

return false;

float sin_alpha_max = mRadius / d;
float cos_alpha_max = sqrt(std::max(1 - sin_alpha_max * sin_alpha_max,0.0f));

//generate two canonical numbers
float eps1 = random.generateDouble(0,1);
float eps2 = random.generateDouble(0,1);

float cos_alpha = 1 + eps1 * cos_alpha_max - eps1;
float sin_alpha = sqrt(std::max(1 - cos_alpha * cos_alpha,0.0f));
float phi = 2 * M_PI * eps2;

float cos_phi = cos(phi);
float sin_phi = sin(phi);

//the cos_phi and sin_phi azimuthal and polar angles in the local
//local coordinate system
//the sampling direction is in the local coordinate system
w.normalize();

/*
// FIRST OPTION
Vector3D v = w.cross(intersection.mNormal);
v.normalize();

Vector3D u = v.cross(w);
u.normalize();
*/

//SECOND OPTION - is better than the FIRST ONE
//i managed to remove those artifacts from the surface
//of the luminaire
Vector3D n(1.0f,0.0f,0.0f);
Vector3D m(0.0f,1.0f,0.0f);

Vector3D u = w.cross(n);

if(u.length() < ONB_EPSILON)
u = w.cross(m);

u.normalize();

Vector3D v = w.cross(u);
v.normalize();

//get the vector to the light source
Vector3D l = (u * cos_phi * sin_alpha) +
(v * sin_phi * sin_alpha) +
(w * cos_alpha);

//normalize the light direction
l.normalize();

//store the direction to the light
sampleDirection = l;

//sample found , so return true
return true;
}

And the for the Triangle

bool Triangle::sampleDirection(const Intersection &intersection,Vector3D &sampleDirection)
{
//create a random instance
//get the random instance
//to generate the canonical random number [0,1)
RandomGenerator random = RandomGenerator::getRandomInstance();

float temp =  sqrtf(1.0f - random.generateDouble(0,1));
float beta =  (1.0f - temp);
float gamma = random.generateDouble(0,1);

//now calculate the point on the light
Point3D lightPoint =  getVtxPosition(0) * (1 - beta - gamma)  +
getVtxPosition(1) * beta + getVtxPosition(2) * gamma;

Point3D intersectionToLightPoint = lightPoint - intersection.mPosition;

Vector3D toLight(intersectionToLightPoint);

toLight.normalize();

sampleDirection = toLight;

return true;

}

Regards

sajis997
Newbie Poster
3 posts since Sep 2012
Reputation Points: 0
Skill Endorsements: 0

Where do you initialize the mIntersectable member of the mSelectedLuminaire object? You are dereferencing it, but not verifying that it is not null.

rubberman
Posting Maven
2,571 posts since Mar 2010
Reputation Points: 365
Skill Endorsements: 51

I think mSelectedLuminaire is of type
LuminaireProbability *mSelectedLuminire

I m not instantiating any object with it from the beginning . mSelectedLuminaire is initialized to NULL in the constructor of arealight.

And i think i am checking it before de-referencing it as follows:

...................
if(mSelectedLuminaire != 0)
{
if(mSelectedLuminaire->mIntersectable != 0)
mSelectedLuminaire->mIntersectable->sampleDirection(intersection,sampleVector);
}
......................

Is there anything else i have to check here ? I m calling the sampleDirection() only after i am sure that they are not null

Thanks

sajis997
Newbie Poster
3 posts since Sep 2012
Reputation Points: 0