void doArcball( double * _viewMatrix, double const * _rotationCenter, double const * _projectionMatrix, double const * _initialViewMatrix, //double const * _currentViewMatrix, double const * _initialMouse, double const * _currentMouse, bool screenSpaceRadius, double radius) { Eigen::Map<Eigen::Vector3d const> rotationCenter(_rotationCenter); Eigen::Map<Eigen::Matrix4d const> initialViewMatrix(_initialViewMatrix); //Eigen::Map<Eigen::Matrix4d const> currentViewMatrix(_currentViewMatrix); Eigen::Map<Eigen::Matrix4d const> projectionMatrix(_projectionMatrix); Eigen::Map<Eigen::Matrix4d> viewMatrix(_viewMatrix); Eigen::Vector2d initialMouse(_initialMouse); Eigen::Vector2d currentMouse(_currentMouse); Eigen::Quaterniond q; Eigen::Vector3d Pa, Pc; if (screenSpaceRadius) { double aspectRatio = projectionMatrix(1, 1) / projectionMatrix(0, 0); initialMouse(0) *= aspectRatio; currentMouse(0) *= aspectRatio; Pa = mapToSphere(initialMouse, radius); Pc = mapToSphere(currentMouse, radius); q.setFromTwoVectors(Pa - rotationCenter, Pc - rotationCenter); } else { Pa = mapToSphere(projectionMatrix.inverse(), initialMouse, rotationCenter, radius); Pc = mapToSphere(projectionMatrix.inverse(), currentMouse, rotationCenter, radius); Eigen::Vector3d a = Pa - rotationCenter, b = Pc - rotationCenter; #if 0 std::cout << "Mouse Initial Radius = " << sqrt(a.dot(a)) << " Current Radius = " << sqrt(b.dot(b)) << std::endl; #endif q.setFromTwoVectors(a, b); } Eigen::Matrix4d qMat4; qMat4.setIdentity(); qMat4.topLeftCorner<3, 3>() = q.toRotationMatrix(); Eigen::Matrix4d translate; translate.setIdentity(); translate.topRightCorner<3, 1>() = -rotationCenter; Eigen::Matrix4d invTranslate; invTranslate.setIdentity(); invTranslate.topRightCorner<3, 1>() = rotationCenter; viewMatrix = invTranslate * qMat4 * translate * initialViewMatrix; }
void GLWidget::mousePressEvent(QMouseEvent *event) { m_last_p2d = Imath::V2d(event->pos().x(), event->pos().y()); std::pair<bool, Imath::V3d> map; map = mapToSphere(m_last_p2d); m_last_pok = map.first; m_last_p3d = map.second; }
Quaternionf ArcBall::move(Vec2f p) { m_EndVector = mapToSphere(p); Vec3f perp = m_StartVector.cross(m_EndVector); if(perp.norm() > 1.0e-5f) { return Quaternionf( m_StartVector.dot(m_EndVector), perp.x(), perp.y(), perp.z() ); } return Quaternionf::Identity(); }
void GLWidget::mouseMoveEvent(QMouseEvent *event) { Imath::V2d newPoint2D(event->pos().x(), event->pos().y()); if ( ((newPoint2D.x < 0) || (newPoint2D.x > width()) || (newPoint2D.y < 0) || (newPoint2D.y > height())) ) { event->ignore(); } float value_y = 0; std::pair<bool, Imath::V3d> map; map = mapToSphere(m_last_p2d); bool newPoint_hitSphere = map.first; Imath::V3d newPoint3D = map.second; float dx = newPoint2D.x - m_last_p2d.x; float dy = newPoint2D.y - m_last_p2d.y; float w = width(); float h = height(); makeCurrent(); if ( (event->buttons() == Qt::LeftButton & event->modifiers() == Qt::ControlModifier) || (event->buttons() == Qt::RightButton & event->modifiers() == Qt::AltModifier) ) { m_camera.dolly(Imath::V2d(dx, dy)); } else if ( (event->buttons() & Qt::MidButton || (event->buttons() == Qt::LeftButton & event->modifiers() == Qt::ShiftModifier)) ) { m_camera.track(Imath::V2d(dx, dy)); } else if ( event->buttons() & Qt::LeftButton ) { m_rotating = true; m_camera.rotate(Imath::V2d(dx, dy)); } m_last_p2d = newPoint2D; m_last_p3d = newPoint3D; m_last_pok = newPoint_hitSphere; m_camera.apply(); updateGL(); }
void _XArcBall::drag(_XVector2 point,_XVector4& rotate) { mapToSphere(point,m_dragVector); //Map the point to the sphere //Return the quaternion equivalent to the rotation _XVector3 perp = m_clickVector * m_dragVector; //Compute the vector perpendicular to the begin and end vectors //Compute the length of the perpendicular vector if(perp.getLength() > (1.0e-5)) //if its non-zero //if(perp.getLength() >= 0.0f) //if its non-zero {//We're ok, so return the perpendicular vector as the transform after all rotate.x = perp.x; rotate.y = perp.y; rotate.z = perp.z; //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle rotate.w = m_clickVector.dot(m_dragVector); }else //if its zero {//The begin and end vectors coincide, so return an identity transform rotate.x = rotate.y = rotate.z = rotate.w = 0.0f; printf("Error!\n"); } }
TerrainPatchData::TerrainPatchData(TerrainQuadtree* tree) : tree(tree), tessellation(tree->getPlanetarySurface()->getTessellation()), vertices(tessellation + 3, std::vector<Ogre::Vector3>(tessellation + 3)), normals(tessellation + 3, std::vector<Ogre::Vector3>(tessellation + 3)), heights(tessellation + 3, std::vector<Ogre::Real>(tessellation + 3, 0.0)) { int patchSize = tree->getSize(); Ogre::Real halfPatchSize = Ogre::Real(patchSize / 2); Ogre::Real delta = (Ogre::Real)patchSize * (1.0 / (Ogre::Real)tessellation); Ogre::SceneNode* patchSceneNode = tree->getSceneNode(); Ogre::SceneNode* planetarySceneNode = tree->getPlanetarySurface()->getSceneNode(); Ogre::Real planetaryRadius = (Ogre::Real)tree->getPlanetarySurface()->getRadius(); for (int z = -1; z < tessellation + 2; ++z) { for (int x = -1; x < tessellation + 2; ++x) { Ogre::Vector3 position(-halfPatchSize + delta * x, 0.0, -halfPatchSize + delta * z); Ogre::Vector3 planetaryPosition = planetarySceneNode->convertWorldToLocalPosition(patchSceneNode->convertLocalToWorldPosition(position)); planetaryPosition = mapToSphere(planetaryPosition, planetaryRadius); Ogre::Vector3 normal = planetaryPosition.normalisedCopy(); Ogre::Real height = tree->getPlanetarySurface()->getNoiseFunction()->getValue(planetaryPosition); planetaryPosition = planetarySceneNode->convertLocalToWorldPosition(planetaryPosition); position = patchSceneNode->convertWorldToLocalPosition(planetaryPosition); normal = (tree->getRootSceneNode()->getOrientation().Inverse() * normal).normalisedCopy(); vertices[z + 1][x + 1] = position; normals[z + 1][x + 1] = normal; heights[z + 1][x + 1] = height; } } for (int z = 0; z < tessellation + 1; ++z) { for (int x = 0; x < tessellation + 1; ++x) { processedPositions.push_back(getVertex(x, z)); processedNormals.push_back(getVertexNormal(x, z)); processedTextureCoords.push_back(getNormal(x, z)); } } // Add triangles. for (int z = 0; z < tessellation; ++z) { int zOffset = z * (tessellation + 1); for (int x = 0; x < tessellation; ++x) { int indices[4] = { zOffset + x, zOffset + x + 1, zOffset + tessellation + 1 + x, zOffset + tessellation + 1 + x + 1 }; processedIndices.push_back(indices[0]); processedIndices.push_back(indices[2]); processedIndices.push_back(indices[1]); processedIndices.push_back(indices[2]); processedIndices.push_back(indices[3]); processedIndices.push_back(indices[1]); } } }
Ray PointLight::shootRay(){ double x, y, z; mapToSphere(randReal(), randReal(), x, y, z); return Ray(pos, Vector(x, y, z)); }
void ArcBall::start(Vec2f p) { m_StartVector = mapToSphere(p); }