0

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
#4  0x0806a3df in PathTracer::computeRadiance (this=0xbffff220, 
    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?

Is there any more information you need please ask for it.

Regards
Sajjad

3
Contributors
4
Replies
6
Views
4 Years
Discussion Span
Last Post by sajis997
0

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

   if(d < mRadius)
      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;

   }

Let me know if you need any more information.

Regards
Sajjad

0

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

0

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
Sajjad

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.