Example #1
0
/*!
SLRay::diffuseMC scatters a ray around hit normal (cosine distribution).
This is only used for photonmapping(russian roulette).
The random direction lies around z-Axis and is then transformed by a rotation 
matrix to lie along the normal. The direction is calculated according to MCCABE
*/
void SLRay::diffuseMC(SLRay* scattered)
{
    SLVec3f randVec;
    SLfloat eta1,eta2,eta1sqrt;

    scattered->setDir(hitNormal);
    scattered->origin = hitPoint;
    scattered->depth = depth+1;
    depthReached = scattered->depth;
   
    // for reflectance the start material stays the same
    scattered->originMat = hitMat;
    scattered->originNode = hitNode;
    scattered->originMesh = hitMesh;
    scattered->type = REFLECTED;

    //calculate rotation matrix
    SLMat3f rotMat;
    SLVec3f rotAxis((SLVec3f(0.0,0.0,1.0) ^ scattered->dir).normalize());
    SLfloat rotAngle=acos(scattered->dir.z); //z*scattered.dir()
    rotMat.rotation(rotAngle*180.0f/SL_PI, rotAxis);

    //cosine distribution
    eta1 = rnd01();
    eta2 = SL_2PI*rnd01();
    eta1sqrt = sqrt(1-eta1);
    //transform to cartesian
    randVec.set(eta1sqrt * cos(eta2),
                eta1sqrt * sin(eta2),
                sqrt(eta1));

    scattered->setDir(rotMat*randVec);
}
Example #2
0
/*!
SLRay::refractMC scatters a ray around perfect transmissive direction according 
to translucency (for higher translucency the ray is less scattered).
This is used for path tracing and distributed ray tracing as well as for photon 
scattering. The direction is calculated the same as with specular scattering
(see reflectMC). The created direction is along z-axis and then transformed to 
lie along transmissive direction with rotationMatrix rotMat. The rotation 
matrix must be precalculated (stays the same for each ray sample, needs to be 
be calculated only once)
*/
void SLRay::refractMC(SLRay* refracted,SLMat3f rotMat)
{
    SLfloat eta1, eta2;
    SLVec3f randVec;
    SLfloat translucency = hitMat->translucency();

    //scatter within transmissive lobe
    eta1 = rnd01();
    eta2 = SL_2PI*rnd01();
    SLfloat f1=sqrt(1.0f-pow(eta1,2.0f/(translucency+1.0f)));

    //transform to cartesian
    randVec.set(f1*cos(eta2),
                f1*sin(eta2),
                pow(eta1,1.0f/(translucency+1.0f)));

    //ray needs to be reset if already hit a scene node
    if(refracted->hitNode)
    {   refracted->length = FLT_MAX;
        refracted->hitNode = 0;
        refracted->hitMesh = 0;
        refracted->hitPoint = SLVec3f::ZERO;
        refracted->hitNormal = SLVec3f::ZERO;
    }
   
    refracted->setDir(rotMat*randVec);
}
Example #3
0
/*!
SLRay::reflectMC scatters a ray around perfect specular direction according to 
shininess (for higher shininess the ray is less scattered). This is used for 
path tracing and distributed ray tracing as well as for photon scattering. 
The direction is calculated according to MCCABE. The created direction is 
along z-axis and then transformed to lie along specular direction with 
rotationMatrix rotMat. The rotation matrix must be precalculated (stays the 
same for each ray sample, needs to be be calculated only once)
*/
bool SLRay::reflectMC(SLRay* reflected,SLMat3f rotMat)
{
    SLfloat eta1, eta2;
    SLVec3f randVec;
    SLfloat shininess = hitMat->shininess();

    //scatter within specular lobe
    eta1 = rnd01();
    eta2 = SL_2PI*rnd01();
    SLfloat f1 = sqrt(1.0f-pow(eta1, 2.0f/(shininess+1.0f)));

    //tranform to cartesian
    randVec.set(f1 * cos(eta2),
                f1 * sin(eta2),
                pow(eta1, 1.0f/(shininess+1.0f)));

    //ray needs to be reset if already hit a scene node
    if(reflected->hitNode)
    {  reflected->length = FLT_MAX;
        reflected->hitNode = 0;
        reflected->hitMesh = 0;
        reflected->hitPoint = SLVec3f::ZERO;
        reflected->hitNormal = SLVec3f::ZERO;
    }
   
    //apply rotation
    reflected->setDir(rotMat*randVec);
   
    //true if in direction of normal
    return (hitNormal * reflected->dir >= 0.0f);
}
Example #4
0
static void randomize(cube21_conf *cp) 
{
  int i, j, s;
  int matches[12];
  for(i = 0; i<SHUFFLE; i++) {
    s = rnd01();
    find_matches(cp->pieces, matches, s);
    j = matches[0]-1;
    j = random()%j;
    j = matches[j+1];
    rot_face(cp->pieces, cp->cind, s, j);
    s = rnd01();
    rot_halves(cp->pieces, cp->cind, cp->hf, s);
  }
}
Example #5
0
SLfloat SLLightRect::shadowTestMC(SLRay* ray, // ray of hit point
                                  const SLVec3f& L, // vector from hit point to light
                                  const SLfloat lightDist) // distance to light
{
    SLVec3f SP; // vector hit point to sample point in world coords

    SLfloat randX = rnd01();
    SLfloat randY = rnd01();

    // choose random point on rect as sample
    SP.set(updateAndGetWM().multVec(SLVec3f((randX*_width)-(_width*0.5f), (randY*_height)-(_height*0.5f), 0)) - ray->hitPoint);
    SLfloat SPDist = SP.length();
    SP.normalize();
    SLRay shadowRay(SPDist, SP, ray);

    SLScene::current->root3D()->hitRec(&shadowRay);

    if (shadowRay.length >= SPDist - FLT_EPSILON)
        return 1.0f;
    else
        return 0.0f;
}
Example #6
0
static void finish(cube21_conf *cp) 
{
  int j, s;
  int matches[12];
  switch(cp->state) {
    case CUBE21_PAUSE1:
      s = rnd01();
      find_matches(cp->pieces, matches, s);
      j = matches[0]-1;
      j = random()%j;
      j = matches[j+1];
      if(j==6 && rnd01()) j = -6;
      cp->state = CUBE21_ROT_BASE+s;
      cp->tmax = 30.0*abs(j);
      cp->fr[0] = cp->fr[1] = 0;
      cp->rface = s;
      cp->ramount = j;
      break;
    case CUBE21_ROT_TOP:
    case CUBE21_ROT_BOTTOM:
      rot_face(cp->pieces, cp->cind, s = cp->rface, cp->ramount);
      cp->fr[s] = 1;
      s ^= 1;
      if(!cp->fr[s] && rnd01()) {
        find_matches(cp->pieces, matches, s);
        j = matches[0]-1;
        j = random()%j;
        j = matches[j+1];
        if(j==6 && rnd01()) j = -6;
        cp->state = CUBE21_ROT_BASE+s;
        cp->tmax = 30.0*abs(j);
        cp->rface = s;
        cp->ramount = j;        
        break;
      } else {
        cp->state = CUBE21_PAUSE2;
        cp->tmax = twait;
        break;
      }
    case CUBE21_PAUSE2:
      s = rnd01();
      cp->ramount = -rnd01();       /* 0 or -1, only sign is significant in this case */
      cp->state = CUBE21_HALF_BASE+s;
      cp->tmax = 180.0;
      cp->rface = s;
      break;
    case CUBE21_HALF1:
    case CUBE21_HALF2:
      rot_halves(cp->pieces, cp->cind, cp->hf, cp->rface);
      cp->state = CUBE21_PAUSE1;
      cp->tmax = twait;
      break;
  }
  cp->t = 0;
}
Example #7
0
static void 
randomize(rubikblocks_conf *cp) 
{
  int axis, side;
  int i, j;
  for(i = 0; i < SHUFFLE; i++)
  {
    axis = (random()%3)+1;
    side = rnd01()*2-1;
    flag_pieces(cp->pieces, axis, side);
    for(j = 1; j < 4; j++)
      cp->qfram[j] = 0;
    cp->qfram[0] = M_SQRT1_2;
    cp->qfram[axis] = M_SQRT1_2;
    for(j = 0; j < 27; j++)
    {
      if(cp->pieces[j].act)
        mult_quat(cp->qfram, cp->pieces[j].qr);
    }
  }
}
Example #8
0
static void 
finish(rubikblocks_conf *cp) 
{
  static int axis = 1;
  int side, angle;
  int i, j;
  if(cp->pause)
  {
    switch(axis) 
    {
      case 1:
        axis = rnd01()+2;
        break;
      case 2:
        axis = 2*rnd01()+1;
        break;
      default:
        axis = rnd01()+1;
    }
    side = rnd01()*2-1;
    angle = rnd01()+1;
    flag_pieces(cp->pieces, axis, side);
    cp->pause = False;
    cp->tmax = 90.0*angle;
    for(i = 1; i < 4; i++)
      cp->qfram[i] = 0;
    cp->qfram[0] = cos(tspeed*M_PI/360);
    cp->qfram[axis] = sin((rnd01()*2-1)*tspeed*M_PI/360);
  }
  else
  {
    for(i = 0; i < 27; i++)
    {
      for(j = 0; j < 4; j++)
      {
        cp->pieces[i].qr[j] = settle_value(cp->pieces[i].qr[j]);
      }
    }
    cp->pause = True;
    cp->tmax = twait;
  }
  cp->t = 0;
}