Beispiel #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;
}
Beispiel #2
0
Matrix4x4 a4_get_unproject_matrix(int width, int height, double fov, double d, Point3D eye, Vector3D view, Vector3D up)
{
  double fov_r = fov * M_PI / 180.0;
  double h = 2.0*d*tan(fov_r / 2.0); // height of projection plane based field of view and distance to the plane
  
  // First translate the pixel so that it is centered at the origin in the projection plane (origin is in the middle of the screen)
  Matrix4x4 viewport_translate = Matrix4x4().translate(-(double)width / 2.0, -(double)height / 2.0, d);

  // Then scale it to the projection plane such that aspect ratio is maintained and we have a right handed coordinate system
  Matrix4x4 viewport_scale = Matrix4x4().scale(-h / (double)height, -h / (double)height, 1.0);

  // Calculate the basis for the view coordinate system
  view.normalize();
  up.normalize();
  Vector3D u = up.cross(view);
  u.normalize();
  Vector3D v = view.cross(u);
  v.normalize();

  // Create the view rotation and translation matrix
  Matrix4x4 view_rotate = Matrix4x4(Vector4D(u, 0.0), Vector4D(v, 0.0), Vector4D(view, 0.0), Vector4D(0.0, 0.0, 0.0, 1.0)).transpose();
  Matrix4x4 view_translate = Matrix4x4().translate(Vector3D(eye));

  // Now multiply these together to form the pixel to 3D point transformation matrix
  Matrix4x4 unproject = view_translate * view_rotate * viewport_scale * viewport_translate;

  return unproject;
}
Beispiel #3
0
Matrix4x4 pixel_from_vcs_to_wcs(int width, int height, double fov, double d, Point3D eye, Vector3D view, Vector3D up){
   Matrix4x4 step1_translate = Matrix4x4(
    Vector4D(1.0, 0.0, 0.0, -width/2),
    Vector4D(0.0, 1.0, 0.0, -height/2),
    Vector4D(0.0, 0.0, 1.0, d),
    Vector4D(0.0, 0.0, 0.0, 1.0));

 double h= 2.0 * d* tan(fov*M_PI / 360.0f);
// Matrix4x4 step2_scale = Matrix4x4().scale(-h / height, -h / height, 1.0);
  Matrix4x4 step2_scale = Matrix4x4(
    Vector4D(-h/width, 0.0, 0.0, 0.0),
    Vector4D(0.0, -h/height, 0.0, 0.0),
    Vector4D(0.0, 0.0, 1.0, 0.0),
    Vector4D(0.0, 0.0, 0.0, 1.0));
view.normalize();
 up.normalize();
Vector3D u = up.cross(view);
  u.normalize();
  Vector3D v = view.cross(u);


  v.normalize();
 
 // Matrix4x4 step3_rotate=Matrix4x4(Vector4D(u, 0.0), Vector4D(v, 0.0), Vector4D(view, 0.0), Vector4D(0.0, 0.0, 0.0, 1.0)).transpose();
Matrix4x4 step3_rotate=Matrix4x4(Vector4D(u[0], v[0], view[0], 0.0),Vector4D(u[1], v[1], view[1], 0.0),Vector4D(u[2], v[2], view[2], 0.0),Vector4D(0.0, 0.0, 0.0, 1.0));
 // Matrix4x4 step4_translate=Matrix4x4().translate(eye[0],eye[1],eye[2]);
 Matrix4x4 step4_translate= Matrix4x4(
    Vector4D(1.0, 0.0, 0.0, eye[0]),
  Vector4D(0.0, 1.0, 0.0, eye[1]),
    Vector4D(0.0, 0.0, 1.0, eye[2]),
    Vector4D(0.0, 0.0, 0.0, 1.0));

  return step4_translate* step3_rotate *step2_scale* step1_translate;
} 
double SinValue(const Vector3D& a, const Vector3D& b, const Vector3D& c)
{
    Vector3D ba = b-a;
    Vector3D ca = c-a;
    Vector3D t= ba.cross(ca);
    return t.norm()/(ba.norm()*ca.norm());
}
Beispiel #5
0
/*******************************************************************************
 
  Purpose - 

 *******************************************************************************/
Line3D LinearForm3D::collide(LinearForm3D other)
{
    /* special solution is cross product of normals */
    Vector3D spec;
    spec.cross(createNormalVector(), other.createNormalVector());

    if (abs(spec.length()) <= DBL_EPSILON) // planes are parallel
        return Line3D::invalid();

    /* particular solution can be found by solving the equation set of the two
     * planes, and another perpendicular plane
     */
    Array2D<double> matrixA(3, 3, 0.0f);
    matrixA[0][0] = A;       matrixA[0][1] = B;       matrixA[0][2] = C;
    matrixA[1][0] = other.A; matrixA[1][1] = other.B; matrixA[1][2] = other.C;
    matrixA[2][0] = spec.x;  matrixA[2][1] = spec.y;  matrixA[2][2] = spec.z;

    /* offset of perp plane can be 0, goes through the origin */
    Array2D<double> matrixB(3, 1, 0.0f);
    matrixB[0][0] = -D; matrixB[1][0] = -other.D; matrixB[2][0] = 0;

    /* Note: in C++ JAMA, we don't have Matrix.solve. Looking at the Java JAMA
     * source, it seems that because matrixA is square, we use LU decomposition.
     */
    LU<double> lu(matrixA);
    Array2D<double> res = lu.solve(matrixB);

    return Line3D(Point3D(res[0][0], res[1][0], res[2][0]), spec);
}
Beispiel #6
0
void * a4_trace_ray_set(void * render_directive)
{
    RenderDirective *rd = static_cast<RenderDirective*>(render_directive);

    // calculate change of basis
    Vector3D w = (*rd->world->view);
    w.normalize();
    Vector3D u = rd->world->up->cross(w);
    u.normalize();
    Vector3D v = w.cross(u);

    // for each pixel requested to render
    for (int i = rd->start_pixel; i < rd->num_pixels + rd->start_pixel; i++) {
        // determine which pixel to render based on index
        int x = i % rd->img->get_width();
        int y = i/rd->img->get_width();

        // DEFER: extend to non-axis aligned rendering

        // create ray using perspective
        Ray ray;
        // origin is the eye
        ray.origin = rd->world->get_eye();

        // Calculate view-plane-height = 2 * d * tan ( fovy / 2 )
        double view_plane_height = 2.0*rd->world->view->z()*tan((rd->world->get_fov()*M_PI/180.0)/2);
        double view_plane_width  = view_plane_height * rd->img->get_width()/rd->img->get_height();

        // direction is 
        // DEFER: not sure if this calculate is quite correct ...
        ray.direction = Vector3D(
                -(view_plane_width/rd->img->get_width())*((double)x - 0.5 * rd->img->get_width()),
                (view_plane_height/rd->img->get_height())*((double)y - 0.5 * rd->img->get_height()),
                rd->world->view->z());

        ray.direction.normalize();

        // trace the ray onto given image
        Shading shade(*rd->world);
        shade.ray = ray;
        double tmin = 10E24;
        rd->world->scene->hit(ray, tmin, shade);

        if (shade.hit_object) {
            // use the material to apply shading
            Colour point_colour = shade.material->shade(shade);

            // set the colour on image
            rd->img->set(x, y, point_colour.R(), point_colour.G(), point_colour.B());
        } else {
            // clear pixel to background color
            Colour bg_pixel = background(x,y,rd->img->get_width(),rd->img->get_height());
            rd->img->set(x,y,bg_pixel.R(), bg_pixel.G(), bg_pixel.B());
        }

        increase_pixel_count(rd->img->get_width()*rd->img->get_height());
    }

    return NULL;
}
void CameraDoubleTapHandler::onDown(const G3MEventContext *eventContext,
                                    const TouchEvent& touchEvent,
                                    CameraContext *cameraContext) {
  // compute globe point where user tapped
  const Vector2I pixel = touchEvent.getTouch(0)->getPos();
  Camera* camera = cameraContext->getNextCamera();
  const Vector3D initialPoint = camera->pixel2PlanetPoint(pixel);
  if (initialPoint.isNan()) return;
  
  // compute central point of view
  const Vector3D centerPoint = camera->getXYZCenterOfView();
  
  // compute drag parameters
  const Vector3D axis = initialPoint.cross(centerPoint);
  const Angle angle   = Angle::fromRadians(- IMathUtils::instance()->asin(axis.length()/initialPoint.length()/centerPoint.length()));
  
  // compute zoom factor
  const double height   = camera->getGeodeticPosition()._height;
  const double distance = height * 0.6;
  
  // create effect
  Effect* effect = new DoubleTapEffect(TimeInterval::fromSeconds(0.75), axis, angle, distance);
  
  EffectTarget* target = cameraContext->getNextCamera()->getEffectTarget();
  eventContext->getEffectsScheduler()->startEffect(effect, target);
}
Beispiel #8
0
std::tuple<bool, Ray> a4_reflect_perturbed(const Ray& reflected, const Vector3D& normal, double glossiness, const std::function<double()>& uniform)
{
  Vector3D r = reflected.direction();
  Vector3D na = -r;
  Vector3D U, V;

  // Get the basis vectors for the square of size <glossiness>x<glossiness>
  if(na[2] > na[0] && na[2] > na[1]) U = Vector3D(-na[1], na[0], 0.0);
  else if(na[1] > na[0]) U = Vector3D(-na[2], 0.0, na[0]);
  else U = Vector3D(0.0, -na[2], na[1]);
  U.normalized();

  V = na.cross(U).normalized();

  // Randomly generate a 2D point on the square
  double u = -(glossiness * 0.5) + uniform() * glossiness;
  double v = -(glossiness * 0.5) + uniform() * glossiness;

  // Use the 2D point and the basis vectors for the square to perturb the reflection ray to point to a location on the square
  Point3D rp = Point3D(r[0], r[1], r[2]) + u * U + v * V;

  // Set the new perturbed direction vector for the ray
  r = Vector3D(rp[0], rp[1], rp[2]);

  // Check if the perturbed ray is below the surface
  return std::tuple<bool, Ray>(normal.dot(r) < 0, Ray(reflected.origin(), r)); 
}
Beispiel #9
0
void Mesh::walk_gl(bool picking){

    glBegin(GL_TRIANGLES);
        for (std::vector<Mesh::Face>::const_iterator I = m_faces.begin(); I != m_faces.end(); ++I) {
            for(size_t v=1;v< (*I).size()-1;v++){
                Vector3D ab = m_verts[(*I)[v]] - m_verts[(*I)[0]];
                Vector3D ac = m_verts[(*I)[v+1]] - m_verts[(*I)[0]];
                Vector3D n = ab.cross(ac);
                n.normalize();
                // Vertex one
                glNormal3d(n[0],n[1],n[2]);
                glVertex3d(m_verts[(*I)[0]][0],m_verts[(*I)[0]][1],m_verts[(*I)[0]][2]);
                // Vertex two
                glNormal3d(n[0],n[1],n[2]);
                glVertex3d(m_verts[(*I)[v]][0],m_verts[(*I)[v]][1],m_verts[(*I)[v]][2]);
                // Vertex three
                glNormal3d(n[0],n[1],n[2]);
                glVertex3d(m_verts[(*I)[v+1]][0],m_verts[(*I)[v+1]][1],m_verts[(*I)[v+1]][2]);
            }
        }
    glEnd();

    //draw bounding box
    m_bbox->walk_gl(picking);
    gen_controlpoints(5,5,5);
}
std::list<Vector3D> SphericalPlanet::computeCurve(const Vector3D& start,
                                                  const Vector3D& stop,
                                                  double granularity) const {
  if (granularity <= 0.0) {
    //throw new ArgumentOutOfRangeException("granularity", "Granularity must be greater than zero.");
    return std::list<Vector3D>();
  }

  const Vector3D normal = start.cross(stop).normalized();
  const double theta = start.angleBetween(stop)._radians;

  //int n = max((int)(theta / granularity) - 1, 0);
  int n = ((int) (theta / granularity) - 1) > 0 ? (int) (theta / granularity) - 1 : 0;

  std::list<Vector3D> positions;

  positions.push_back(start);

  for (int i = 1; i <= n; ++i) {
    double phi = (i * granularity);

    positions.push_back(scaleToGeocentricSurface(start.rotateAroundAxis(normal, Angle::fromRadians(phi))));
  }

  positions.push_back(stop);

  return positions;
}
/**
 *  Draw Torso.
 *
 *  This function draws a box that represents the torso of the
 *  player.
 */
void NeutralModel :: drawTorso ()
{
    Vector3D a;
    Vector3D b;
    Vector3D c;
    Vector3D d;

    Vector3D ab;
    Vector3D ac;

    Vector3D n;

    a = Vector3D (joint[LSHOULDER]);
    b = Vector3D (joint[RSHOULDER]);
    c = Vector3D (joint[RHIP]);
    d = Vector3D (joint[LHIP]);

    ab = b - a;
    ac = c - a;

    n = ab.cross(ac);
    n.normalize();

    glPushMatrix();
        glBegin(GL_QUADS);
            glNormal3f(n.x, n.y, n.z);
            glVertex3f(a.x, a.y, a.z);
            glVertex3f(b.x, b.y, b.z);
            glVertex3f(c.x, c.y, c.z);
            glVertex3f(d.x, d.y, d.z);
        glEnd();
    glPopMatrix();
}
Beispiel #12
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);
     }
 }
Beispiel #13
0
Vector3D Vector3D::projectionInPlane(const Vector3D& normal) const
{
  Vector3D axis = normal.cross(*this);
  MutableMatrix44D m = MutableMatrix44D::createRotationMatrix(Angle::fromDegrees(90), axis);
  Vector3D projected = normal.transformedBy(m, 0).normalized();
  return projected.times(this->length());
}
Beispiel #14
0
//Rotates the vector by the indicated number of degrees about the specified axis
Vector3D rotate(Vector3D v, Vector3D axis, float degrees) {
	axis.normalize();
	float radians = degrees * M_PI / 180;
	float s = sin(radians);
	float c = cos(radians);
	return c * v + (1 - c) * axis.dot(v) * axis + s * v.cross(axis);
}
Beispiel #15
0
void CameraFocusSceneLighting::modifyGLState(GLState* glState, const G3MRenderContext* rc) {

  const Camera* cam = rc->getCurrentCamera();
  const Vector3D camDir = cam->getViewDirection();
  const Vector3D up = cam->getUp();
  if (_cameraDirX == camDir._x && _cameraDirY == camDir._y && _cameraDirZ == camDir._z &&
      _upX == up._x && _upY == up._y && _upZ == up._z) {
    return;
  }

  const Vector3D cameraVector = camDir.times(-1);

  //Light slightly different of camera position
  const Vector3D rotationLightDirAxis = up.cross(cameraVector);
  const Vector3D lightDir = cameraVector.rotateAroundAxis(rotationLightDirAxis, Angle::fromDegrees(45.0));

  DirectionLightGLFeature* f = (DirectionLightGLFeature*) glState->getGLFeature(GLF_DIRECTION_LIGTH);
  if (f == NULL) {
    glState->clearGLFeatureGroup(LIGHTING_GROUP);
    glState->addGLFeature(new DirectionLightGLFeature(lightDir,
                                                      _diffuseColor,
                                                      _ambientColor),
                          false);
  }
  else{
    f->setLightDirection(lightDir);
  }

  //ADD MESH
  if (_meshRenderer != NULL) {
    Vector3D lastCamDir(_cameraDirX, _cameraDirY, _cameraDirZ);

    if (lastCamDir.angleBetween(lightDir)._degrees > 10) {

      FloatBufferBuilderFromCartesian3D* vertices = FloatBufferBuilderFromCartesian3D::builderWithFirstVertexAsCenter();
      vertices->add(cam->getCartesianPosition());
      vertices->add(cam->getCartesianPosition().add(lightDir.times(1000)) );

      DirectMesh* mesh = new DirectMesh(GLPrimitive::lines(),
                                        true,
                                        vertices->getCenter(),
                                        vertices->create(),
                                        (float)3.0,
                                        (float)1.0,
                                        new Color(Color::red()));
      _meshRenderer->addMesh(mesh);
    }
  }

  //SAVING STATE
  _cameraDirX = camDir._x;
  _cameraDirY = camDir._y;
  _cameraDirZ = camDir._z;
  
  _upX = up._x;
  _upY = up._y;
  _upZ = up._z;
  
}
Beispiel #16
0
/*******************************************************************************

  Purpose - 

 *******************************************************************************/
Vector3D LinearForm3D::collideToVector(LinearForm3D other)
{
    /* find the vector that occurs when both planes collide */
    Vector3D n = createNormalVector();
    n.cross(n, other.createNormalVector());

    return n;
}
void PeriodicBoundaryConditions::set(const Vector3D &e1, const Vector3D &e2,
                                     const Vector3D &e3,
                                     const Vector3D &origin) {
  myE1 = e1;
  myE2 = e2;
  myE3 = e3;
  myOrigin = origin;

  myV = fabs((e1.cross(e2)).dot(e3));
  if (myV < Constant::EPSILON)
    report << error <<
    "[PeriodicBoundaryConditions::set] No volume, aborting." << endr;
  if (myV >= Constant::REAL_INFINITY)
    report << error <<
    "[PeriodicBoundaryConditions::set] Infinite volume, aborting." << endr;

  myOrthogonal =
    !(e1.c[1] != 0.0 || e1.c[2] != 0.0 || e2.c[0] != 0.0 || e2.c[2] != 0.0 || e3.c[0] !=
      0.0 ||
      e3.c[1] != 0.0);

  Vector3D a1(e2.cross(e3));
  myE1r = a1 / e1.dot(a1);
  Vector3D a2(e3.cross(e1));
  myE2r = a2 / e2.dot(a2);
  Vector3D a3(e1.cross(e2));
  myE3r = a3 / e3.dot(a3);

  Vector3D a(origin - (e1 + e2 + e3) * 0.5);
  Vector3D b(origin + (e1 + e2 + e3) * 0.5);
  myMin.c[0] = min(a.c[0], b.c[0]);
  myMin.c[1] = min(a.c[1], b.c[1]);
  myMin.c[2] = min(a.c[2], b.c[2]);
  myMax.c[0] = max(a.c[0], b.c[0]);
  myMax.c[1] = max(a.c[1], b.c[1]);
  myMax.c[2] = max(a.c[2], b.c[2]);

  myDX = power<2>(e1.c[0] * 0.5);
  myDY = power<2>(e2.c[1] * 0.5);
  myDZ = power<2>(e3.c[2] * 0.5);
  myD = min(myDX, min(myDY, myDZ));
  myH = myMax - myMin;
  myH2 = myH * 0.5;
  report << debug(2) <<
  "[PeriodicBoundaryConditions] maximal safe distance=" << myD << endr;
}
Geodetic2D SphericalPlanet::getMidPoint (const Geodetic2D& P0, const Geodetic2D& P1) const
{
  const Vector3D v0 = toCartesian(P0);
  const Vector3D v1 = toCartesian(P1);
  const Vector3D normal = v0.cross(v1).normalized();
  const Angle theta = v0.angleBetween(v1);
  const Vector3D midPoint = scaleToGeocentricSurface(v0.rotateAroundAxis(normal, theta.times(0.5)));
  return toGeodetic2D(midPoint);
}
Beispiel #19
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];
}
Beispiel #20
0
bool Polygon::isPointWithinPolygonForEdge(
                                          const Point3D& p,
                                          const Point3D& p1,
                                          const Point3D& p2)
{
    Vector3D v = p1 - p2;
    Vector3D edgeNormal = v.cross(m_plane.m_plane_normal);
    
    return edgeNormal.dot(p - p1) < SMALL_EPSILON;
}
Beispiel #21
0
//  assign
void Plane::assign(const Point3D &p1, const Point3D &p2, const Point3D &p3){
  Vector3D v1, v2;
  v1.difference(p3, p2);
  v2.difference(p1, p2);

  Vector3D vC;
  vC.cross(v1, v2);
  vC.norm();

  assign(vC, p1);
}
Beispiel #22
0
void Cone::get_uv(const Point3D &pt, const Vector3D &normal,
		  Point2D &uv, Vector3D &u, Vector3D &v) const
{
  // This function handles UV's for the non-planar surface.
  const double theta = atan2(pt[1], pt[0]);
  const double z = pt[2];
  uv[0] = 0.5 + theta / 2 / M_PI;
  uv[1] = z * 0.5;
  v = Point3D() - pt;
  v.normalize();
  u = v.cross(normal);
}
MutableMatrix44D SphericalPlanet::drag(const Geodetic3D& origin, const Geodetic3D& destination) const
{
  const Vector3D P0 = toCartesian(origin);
  const Vector3D P1 = toCartesian(destination);
  const Vector3D axis = P0.cross(P1);
  if (axis.length()<1e-3) return MutableMatrix44D::invalid();

  const Angle angle = P0.angleBetween(P1);
  const MutableMatrix44D rotation = MutableMatrix44D::createRotationMatrix(angle, axis);
  const Vector3D rotatedP0 = P0.transformedBy(rotation, 1);
  const MutableMatrix44D traslation = MutableMatrix44D::createTranslationMatrix(P1.sub(rotatedP0));
  return traslation.multiply(rotation);
}
Beispiel #24
0
Angle Geodetic2D::angleTo(const Geodetic2D& other) const
{
  const double cos1 = _latitude.cosinus();
  const Vector3D normal1(cos1 * _longitude.cosinus(),
                         cos1 * _longitude.sinus(),
                         _latitude.sinus());
  const double cos2 = other._latitude.cosinus();
  const Vector3D normal2(cos2 * other._longitude.cosinus(),
                         cos2 * other._longitude.sinus(),
                         other._latitude.sinus());
  return Angle::fromRadians(asin(normal1.cross(normal2).squaredLength()));

}
Beispiel #25
0
//Generate a random map
void HM::randomize(){
	make_circle(50);
	//Calculate the normal
	for(int i =0;i<map_size-1;i+=1){ 
		for(int j = 0;j<map_size-1;j+=1){
			Vector3D x =  height_map[i+1][j]-height_map[i][j] ;
			Vector3D y =  height_map[i+1][j+1] - height_map[i+1][j];
			Vector3D n = x.cross(y);
			n.normalize();
			normal_map[i][j] = n;
		}
	}
}
Beispiel #26
0
void Cylinder::get_uv(const Point3D &pt, const Vector3D &normal,
		      Point2D &uv, Vector3D &u, Vector3D &v) const
{
  // This function handles uvs on the non-planar part.
  // Find theta, translate it into a coordinate from 0 to 1.
  const double theta = atan2(pt[1], pt[0]);
  const double z = pt[2];
  uv[0] = 0.5 + theta / 2 / M_PI;
  uv[1] = 0.25 + z * 0.25;
  v = Vector3D(0, 0, 1);
  u = v.cross(normal);
  assert(approx(v.dot(normal), 0.));
  assert(approx(u.dot(normal), 0.));
}
Beispiel #27
0
bool NonhierCylinder::intersection(Point3D rayOrigin, Vector3D rayDir, double ret[2], Point3D intersection[2], Vector3D normal[2]) {
	double a, b, c;
	double *roots = (double*)malloc(2*sizeof(double));

	Vector3D orgpos = rayOrigin - m_pos;

	Point3D bottom = m_pos;
	Point3D top = m_pos + Vector3D(0, m_height, 0);

	Vector3D AB = (top - bottom);
	Vector3D A0 = rayOrigin - bottom;
	Vector3D A0XAB = A0.cross(AB);
	Vector3D VXAB = rayDir.cross(AB);
	double ab2 = AB.dot(AB);

	a = VXAB.dot(VXAB);
	b = 2*(VXAB.dot(A0XAB));
	c = A0XAB.dot(A0XAB) - (m_radius*m_radius * ab2);

	size_t num_roots = quadraticRoots( a, b, c, roots);
	if (num_roots > 0) {

		if (roots[0] <= roots[1] || num_roots == 1) {
			ret[0] =  roots[0];
			ret[1] = roots[1];
		} else {
			ret[0] = roots[1];
			ret[1] = roots[0];
		}	

		intersection[0] = rayOrigin + ret[0]*rayDir;  
		intersection[1] = rayOrigin + ret[1]*rayDir;  

		Point3D projection = bottom + ((AB.dot(intersection[0] - bottom) / ab2) * AB);
		if ( (projection - bottom).length() + (top - projection).length() > AB.length()) {
			delete roots;
			return false;
		}

		normal[0] = intersection[0] - (m_pos + Vector3D(0, m_height / 2, 0));
		normal[1] = intersection[1] - (m_pos + Vector3D(0, m_height / 2, 0));

		delete roots;
		return true;
	}

	delete roots;
	return false;
}
    /*!
     Generate a coorinate system from a vector.
     This method is useful for generate a tangent space coordinate system for isotropic BRDFs.
     
     @param vector1 vector from which the coordinate system is constructed. This must be normalized.
     @param vector2 second axis obtained.
     @param vector3 third axis obtained.
     */
    inline static void generateCoodinateSystem(const Vector3D& vector1, Vector3D& vector2, Vector3D& vector3) {

        if (std::fabs(vector1.x) > std::fabs(vector1.y)) {
            
            vector2 = Vector3D(vector1.z, 0, -vector1.x);
        } else {
            
            vector2 = Vector3D(0, -vector1.z, vector1.y);
        }
        
        vector2.normalize();
        
        vector3 = vector1.cross(vector2);
        vector3.normalize();
    }
Beispiel #29
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; 
}
Beispiel #30
0
void Camera::calculatePosition()
{
//    _position.x() = _target.x() + _radius * cosf( _angle.x() ) * cos( _angle.y() );
//    _position.y() = _target.y() + _radius * sinf( _angle.y() );
//    _position.z() = _target.z() + _radius * sinf( _angle.x() ) * cos( _angle.y() );

    _position.x() = _target.x() + _radius * cosf( _angle.x() ) * sinf( _angle.y() );
    _position.z() = _target.z() + _radius * cosf( _angle.y() );
    _position.y() = _target.y() + _radius * sinf( _angle.x() ) * sinf( _angle.y() );

    Vector3D v = _target - _position;
    _right = v.cross( Vector3D( 0.0f, 0.0f, 1.0f ) );
    _right.normalize();
    _up = _right.cross( v );
    _up.normalize();
}