Example #1
0
bool intersectTriangle(const Point3D &o, const Vector3D &d, float *t, const Point3D &p0,  const Point3D &p1,  const Point3D &p2){
  Vector3D e1, e2;
  e1.difference(p1, p0);
  e2.difference(p2, p0);

  Vector3D p;
  p.cross(d, e2);

  double a = e1.dot(p);
  if (fabs(a) < EPSILON)
    return false;

  double f = 1/a;
  Vector3D s;
  s.difference(o, p0);
  double u = f * s.dot(p);
  if((u < 0.0) || (u > 1.0))
    return false;

  Vector3D q;
  q.cross(s, e1);

  double v = f * d.dot(q);
  if((v < 0.0) || ((u + v) > 1.0))
    return false;

  *t = f*e2.dot(q);
  return true;
}
Example #2
0
 Quaternion(Vector3D v1, Vector3D v2) {
     const double k = v2.norm() / v1.norm();
     const Vector3D d1 = v1.direction();
     const Vector3D d2 = v2.direction();
     if ( (d1 + d2).norm() < PRECISION ) {
         Vector3D n;
         srand( (unsigned int) time(0));
         do {
             double x = (double) rand() / RAND_MAX;
             double y = (double) rand() / RAND_MAX;
             double z = (double) rand() / RAND_MAX;
             Vector3D v = Vector3D(x, y, z);
             n = v - v1.direction()*(v*v1)/v1.norm();
         } while (n.norm() < PRECISION );
         init( 0.0, n.direction() );
     } else if ( (d1 - d2).norm() < PRECISION ) {
         init( 1.0, Vector3D(0.0, 0.0, 0.0) );
     } else {
         double phi = acos( v1.direction()*v2.direction() );
         Vector3D a = v1.cross(v2).direction();
         assert(a.norm() > PRECISION);
         double w = cos(phi/2) * sqrt(k);
         Vector3D u = a * sin(phi/2) * sqrt(k);
         init(w, u);
     }
 }
Example #3
0
//obtains the orientation matrix based on the unitary vector x, 
//the vector vv corrspondent to y. z is cw defined, and vv corrected
OrientationMatrix::OrientationMatrix(Vector3D vu, Vector3D vv)
{
	vu.normalize();
	Vector3D vw=vu.cross(vv);
	vw.normalize();
	vv=vw.cross(vu);
	mat[0][0]=vu[0];mat[1][0]=vu[1];mat[2][0]=vu[2];
	mat[0][1]=vv[0];mat[1][1]=vv[1];mat[2][1]=vv[2];
	mat[0][2]=vw[0];mat[1][2]=vw[1];mat[2][2]=vw[2];
}
Example #4
0
AffineTrans3D initInvViewMatrix( Point3D const& eye, Vector3D view, Vector3D up) {
    AffineTrans3D mat; 
    Vector3D w;
    view.normalize();
    up = up - up.dot(view)*view;
    up.normalize();
    w = view.cross(up);

    mat.A.col(0) = w.v;
    mat.A.col(1) = up.v;
    mat.A.col(2) = -view.v;

    mat.t = eye.v;

    return mat; 
}
Example #5
0
void CObjectView::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (GetCapture() == this && (nFlags & MK_LBUTTON)){
    if (mode == PAN){
      Point2D pL, pC;
      screenToFrustum(&pL, lastPt);
      screenToFrustum(&pC, point);

      //  update translate
      tr[0] += (pC.x - pL.x)*1000.0/scale;
      tr[1] += (pC.y - pL.y)*1000.0/scale;
      }
    else if (mode == ROTATE || mode == LIGHT){
      Vector3D vL, vC;
      screenToVector(&vL, lastPt);
      screenToVector(&vC, point);

      //  calculate angle prop to length mouse movement
      float dX = vC.x - vL.x;
      float dY = vC.y - vL.y;
      float dZ = vC.z - vL.z;
      float ang = 90.0 * sqrt(dX*dX + dY*dY + dZ*dZ);

      // vector is just cross product
      Vector3D v;
      v.cross(vL, vC);
      v.norm();

      if (mode == ROTATE)
        applyRotation(m, ang, v);
      else
        applyRotation(mL, ang, v);
      }

    lastPt = point;
    RedrawWindow();
    }
	
	CView ::OnMouseMove(nFlags, point);
}
Example #6
0
RGBAPixel GeometricObject::rayTrace(PointLight& lightSrc, Point3D& pt, Ray& viewRay, vector<GeometricObject*>& shapes){
    
    RGBAPixel color = material.color;
    if(texture != NULL)
        color = *mapToTexture(pt);
    
    Vector3D dir(lightSrc.o,pt);
    dir.normalize();
    
    Point3D tempPt(pt+dir.reflect()*0.01);
    Ray backtraceRay(tempPt,dir.reflect(), "shadow"); //from hit point on shape to light source
    double tHitLight = lightSrc.o.distance(pt);
    bool shadow = false;
    
    Point3D trash(0,0,0);
    for(int i = 0; i < shapes.size(); i++){
        if(shapes[i]->isLightSrc)
            continue;
        double tHitAnotherShape = shapes[i]->hit(backtraceRay,trash);
        if(tHitAnotherShape < tHitLight && tHitAnotherShape > 0){
            shadow = true;
            break;
        }
    }
    
    //pt's intersection with viewRay and geometry
    Vector3D n(this->getNormal(pt));
    n.normalize();
    
    double r = 0.0;
    double g = 0.0;
    double b = 0.0;
    
    //Ambient Lighting
    r += 0.04 * 30;
    g += 0.04 * 30;
    b += 0.04 * 30;
    
    RGBAPixel temp(r*color.red, g*color.green ,b*color.blue);
    
    if(shadow){
        return temp;
    }
    
    
    //Diffuse Lighting
    Vector3D reflectRay = (dir.reflect()).hat();
    double product = reflectRay.dot(n);
    if (product > 0){
        r += color.red*product * material.kd;
        g += color.green*product * material.kd;
        b += color.blue*product * material.kd;
    }
    
    //Specular Lighting
    
    
    double epsilon = 10.0;
    Vector3D rVec(dir - (n*dir.dot(n)*2.0));
    double spec = rVec.dot(viewRay.d.reflect());
    double rw0e;
    if(spec > 0)
        rw0e = pow(spec,epsilon);
    else
        rw0e = 0;
    if(product > 0){
        r += color.red*rw0e * material.ks * 0.5;
        g += color.green*rw0e * material.ks * 0.5;
        b += color.blue*rw0e * material.ks * 0.5;
    }
    r = r*material.directScale;
    g = g*material.directScale;
    b = b*material.directScale;
    
    //Reflections
    double minTime = 100000.0;
    double tHitAnotherShape = 0.0;
    Vector3D recViewDir(viewRay.d - (2*viewRay.d*n)*n); //direction of mirror reflection
    recViewDir.normalize();
    
    Ray recViewRay(pt,recViewDir, "view");
    recViewRay.recurseLevel = viewRay.recurseLevel+1;
    Point3D recPt;
    RGBAPixel recColor;
    
    //Mirror Reflection
    if(material.reflectProperty == "mirror" && viewRay.recurseLevel < 3){
        
        GeometricObject* nextShape = NULL;
        
        for(int k = 0; k < shapes.size(); k++){
            if(shapes[k] == this)
                continue;
            
            tHitAnotherShape = shapes[k]->hit(recViewRay,recPt);
            if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){
                nextShape = shapes[k];
                minTime = tHitAnotherShape;
            }
        }
        if(nextShape != NULL){
            recColor = nextShape->rayTrace(lightSrc, recPt, recViewRay, shapes);
            r += (recColor.red); //* (1-material.directScale);
            g += (recColor.green);// * (1-material.directScale);
            b += (recColor.blue);// * (1-material.directScale);
        }
    }
    if(material.reflectProperty == "glossy" && viewRay.recurseLevel < 3){
        
        double tempR = 0.0;
        double tempG = 0.0;
        double tempB = 0.0;
        
        Vector3D axisA = Vector3D(1,0,0).cross(recViewDir).hat() * 1;
        Vector3D axisB = axisA.cross(recViewDir).hat() * 1;

        Point3D tempPt = pt + recViewDir - 0.5*axisA - 0.5*axisB;
        Rectangle rect(tempPt, axisA, axisB);
        
        vector<Point3D> samplepts = rect.generatePoints(100);
        
        for(int i = 0; i < samplepts.size(); i++){
            Vector3D indirectDir(pt,samplepts[i]);
            Ray indirectRay(pt,indirectDir);
            indirectRay.recurseLevel = viewRay.recurseLevel + 1;
            
            GeometricObject* nextShape = NULL;
            double minTime = 100000.0;
            double tHitAnotherShape = 0.0;
            for(int k = 0; k < shapes.size(); k++){
                if(shapes[k] == this)
                    continue;
                
                tHitAnotherShape = shapes[k]->hit(indirectRay,recPt);
                if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){
                    nextShape = shapes[k];
                    minTime = tHitAnotherShape;
                }
                if(nextShape != NULL && nextShape->material.transparency == 0){
                    recColor = nextShape->rayTrace(lightSrc, recPt, recViewRay, shapes);
                    tempR += (recColor.red);
                    tempG += (recColor.green);
                    tempB += (recColor.blue);
                }
            }
        }
        r += tempR / samplepts.size();
        g += tempG / samplepts.size();
        b += tempB / samplepts.size();
    }
    
    if(material.transparency > 0 && viewRay.recurseLevel == 0){
        double tempR = 255;
        double tempG = 255;
        double tempB = 255;
        
        Vector3D invNormal = n.reflect();
        Ray inverseRay(pt,invNormal);
        inverseRay.recurseLevel = viewRay.recurseLevel + 1;
        GeometricObject* nextShape = NULL;
        double minTime = 100000.0;
        double tHitAnotherShape = 0.0;
        for(int k = 0; k < shapes.size(); k++){
            if(shapes[k] == this)
                continue;
            
            tHitAnotherShape = shapes[k]->hit(inverseRay,recPt);
            if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){
                nextShape = shapes[k];
                minTime = tHitAnotherShape;
            }
            if(nextShape != NULL && nextShape != this){
                recColor = nextShape->rayTrace(lightSrc, recPt, inverseRay, shapes);
                tempR = (recColor.red);
                tempG = (recColor.green);
                tempB = (recColor.blue);
            }
        }
        r = tempR * material.transparency + (r*(1-material.transparency));
        g = tempG * material.transparency + (g*(1-material.transparency));
        b = tempB * material.transparency + (b*(1-material.transparency));
    }
    
    //cap off maximum color values
    r =std::min((int)r,255);
    g =std::min((int)g,255);
    b =std::min((int)b,255);
    
    temp(r,g,b);
    return temp;
}
inline Vector3D cross(const Vector3D& a, const Vector3D& b) 
{
  return a.cross(b);
}
Example #8
0
void a4_render(// What to render
               SceneNode* root,
               // Where to output the image
               const std::string& filename,
               // Image size
               int width, int height,
               // Viewing parameters
               const Point3D& eye, const Vector3D& view,
               const Vector3D& up, double fov,
               // Lighting parameters
               const Colour& ambient,
               const std::list<Light*>& lights
               )
{
    // Fill in raytracing code here.
    Image img(width, height, 3);
    Matrix4x4 inv_transf;
    //pinhole camera
    Vector3D m_cx = (view.cross(up));
    m_cx.normalize();
    Vector3D m_cy = (-up);

    double m_fovrad = (fov*M_PI)/360.0;
    double m_cw = tan(m_fovrad);
    double a =(double(width)/double(height));
    double m_ch = m_cw;

    //for percent display
    float done = 0;
#pragma omp parallel for default(shared) reduction(+:done) schedule(guided)
    for (int y = 0; y < height; y++) {
        done = done + 1.0f;
        display_percentage( done, (float)height);
        for (int x = 0; x < width; x++) {
            //background color
            // Red: increasing from top to bottom
            double red = (double)y / height;
            // Green: increasing from top and bottom to middle
            double green = ((red <= 0.5) ? 2.0*red : (2.0 - 2.0*red));
            // Blue: decreasing from top to bottom
            double blue = 1.0 - red;
            Colour back(red,green,blue);
            //antialiasing  http://www.codermind.com/articles/Raytracer-in-C++-Part-II-Specularity-post-processing.html
            double sampleRatio= 0.25;
            Colour aux(0.0, 0.0, 0.0);
            for (double fragmentx = double(x) ; fragmentx < x + 1.0; fragmentx += 0.5 )
                for (double fragmenty = double(y) ; fragmenty < y + 1.0; fragmenty += 0.5 )
                {
                    Vector3D m_raydir;
                    //get primary ray direction
                    m_raydir = view + (fragmentx / (double(width))*2.0 -1.0 )*m_cw*a*m_cx + ((fragmenty) / (double(height))*2.0 - 1.0) * m_ch*m_cy;
                    m_raydir.normalize();
                    //m_raydir = Vector3D(0.0,0.0,-1.0);
                    Ray r(eye,m_raydir);
                    //Ray r(Point3D(x,y,800),m_raydir);
                    double coef = 1.0;
                    int level = 0;
                    bool hit = false;
                    Colour tmp(0.0, 0.0, 0.0);
                    do{
                        // find the closest intersection
                        Intersection closest_isect;
                        hit = root->closest_intersect(r,closest_isect,inv_transf);
                        //if(!hit) cout<< "fail hit"<< endl;
                        if(hit){
                            //cout<< "success hit"<< endl;
                            // put color to pixel
                            Colour diffuse(0.0, 0.0, 0.0);
                            Colour specular(0.0, 0.0, 0.0);
                            Ray reflected_ray;//reflected ray
                            reflected_ray.origin()= closest_isect.position();

                            for (std::list<Light*>::const_iterator cl = lights.begin(); cl != lights.end(); ++cl){

                                Vector3D L = (*cl)->position - closest_isect.position();
                                double light_dist = L.length();
                                if((L.dot(closest_isect.normal())) <= 0.0 || light_dist < 0.0)// test if the point if lighted
                                    continue;
                                L.normalize();
                                reflected_ray.direction()=L;

                                // attenuation factor
                                double fatt = 1.0/((*cl)->falloff[0]+ (*cl)->falloff[1]*light_dist
                                                   + (*cl)->falloff[2]*light_dist*light_dist);
                                coef = fatt;
                                if(coef < double(1e-6)) break;

                                // test if point is in shadow
                                bool in_shadow = false;
                                Intersection aux_isect;
                                if(root->closest_intersect(reflected_ray,aux_isect,inv_transf,light_dist))
                                    in_shadow = true;

                                //ilumination
                                if(!in_shadow){
                                    double lambert = reflected_ray.direction().dot(closest_isect.normal())*fatt;
                                    diffuse = diffuse + (lambert*(*cl)->colour)*closest_isect.mtrl()->get_diffuse();
                                    // reflection by blinn-phong model reference:http://www.codermind.com/
                                    Vector3D blinnDir = reflected_ray.direction() - r.direction();
                                    double temp = blinnDir.length2();
                                    if (temp != 0.0 )
                                    {
                                        blinnDir.normalize();
                                        double blinnTerm = max(blinnDir.dot(closest_isect.normal()), 0.0);
                                        blinnTerm = pow(blinnTerm ,closest_isect.mtrl()->get_shininess())*fatt;

                                        specular =specular + blinnTerm*closest_isect.mtrl()->get_specular()*(*cl)->colour;
                                    }
                                }
                            }
                            tmp = tmp + ambient*closest_isect.mtrl()->get_diffuse() + diffuse + specular;
                            if(closest_isect.mtrl()->get_shininess() < eps)
                                break;
                            double reflet = 2.0*(r.direction().dot(closest_isect.normal()));
                            r.origin() = closest_isect.position() + eps*closest_isect.normal();
                            r.direction() = (r.direction() - reflet * closest_isect.normal());
                            r.direction().normalize();
                            level++;
                        }
                    }while((coef > double(1e-6)) && level < 5 && hit);

                    aux =aux + sampleRatio*tmp;
                }
            if(aux.R()!=0.0 || aux.G()!= 0.0 || aux.B()!= 0.0)
                back = aux;

            img(x, y, 0) = back.R();
            img(x, y, 1) =back.G();
            img(x, y, 2) = back.B();
        }
    }

    std::cerr << "Stub: a4_render(" << root << ",\n     "
              << filename << ", " << width << ", " << height << ",\n     "
              << eye << ", " << view << ", " << up << ", " << fov << ",\n     "
              << ambient << ",\n     {";

    for (std::list<Light*>::const_iterator I = lights.begin(); I != lights.end(); ++I) {
        if (I != lights.begin()) std::cerr << ", ";
        std::cerr << **I;
    }
    std::cerr << "});" << std::endl;
    img.savePng(filename);
}
Example #9
0
Vector3D TrackSimulator::lorentz_force(const Vector3D& vel, const Vector3D& ef, const Vector3D& bf, const double chg)
{
    return chg * (ef + vel.cross(bf));
}