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; }
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; }
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()); }
/******************************************************************************* 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); }
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); }
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)); }
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(); }
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); } }
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()); }
//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); }
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; }
/******************************************************************************* 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); }
//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]; }
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; }
// 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); }
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); }
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())); }
//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; } } }
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.)); }
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(); }
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; }
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(); }