static GfRay _ComputeUntransformedRay(GfFrustum::ProjectionType projectionType, const GfRange2d &window, const GfVec2d &windowPos) { // Compute position on window, from provided normalized // (-1 to 1) coordinates. double winX = _Rescale(windowPos[0], -1.0, 1.0, window.GetMin()[0], window.GetMax()[0]); double winY = _Rescale(windowPos[1], -1.0, 1.0, window.GetMin()[1], window.GetMax()[1]); // Compute the camera-space starting point (the viewpoint) and // direction (toward the point on the window). GfVec3d pos; GfVec3d dir; if (projectionType == GfFrustum::Perspective) { pos = GfVec3d(0); dir = GfVec3d(winX, winY, -1.0).GetNormalized(); } else { pos.Set(winX, winY, 0.0); dir = -GfVec3d::ZAxis(); } // Build and return the ray return GfRay(pos, dir); }
GfRay GfFrustum::ComputeRay(const GfVec3d &worldSpacePos) const { GfVec3d camSpaceToPos = ComputeViewMatrix().Transform(worldSpacePos); // Compute the camera-space starting point (the viewpoint) and // direction (toward the point camSpaceToPos). GfVec3d pos; GfVec3d dir; if (_projectionType == Perspective) { pos = GfVec3d(0); dir = camSpaceToPos.GetNormalized(); } else { pos.Set(camSpaceToPos[0], camSpaceToPos[1], 0.0); dir = -GfVec3d::ZAxis(); } // Transform these by the inverse of the view matrix. const GfMatrix4d &viewInverse = ComputeViewInverse(); GfVec3d rayFrom = viewInverse.Transform(pos); GfVec3d rayDir = viewInverse.TransformDir(dir); // Build and return the ray return GfRay(rayFrom, rayDir); }
GfRay GfFrustum::ComputePickRay(const GfVec3d &worldSpacePos) const { GfVec3d camSpaceToPos = ComputeViewMatrix().Transform(worldSpacePos); // Compute the camera-space starting point (the viewpoint) and // direction (toward the point camSpaceToPos). GfVec3d pos; GfVec3d dir; if (_projectionType == Perspective) { pos = GfVec3d(0); dir = camSpaceToPos.GetNormalized(); } else { pos.Set(camSpaceToPos[0], camSpaceToPos[1], 0.0); dir = -GfVec3d::ZAxis(); } return _ComputePickRayOffsetToNearPlane(pos, dir); }
GfQuaternion GfMatrix3d::ExtractRotationQuaternion() const { // This was adapted from the (open source) Open Inventor // SbRotation::SetValue(const SbMatrix &m) int i; // First, find largest diagonal in matrix: if (_mtx[0][0] > _mtx[1][1]) i = (_mtx[0][0] > _mtx[2][2] ? 0 : 2); else i = (_mtx[1][1] > _mtx[2][2] ? 1 : 2); GfVec3d im; double r; if (_mtx[0][0] + _mtx[1][1] + _mtx[2][2] > _mtx[i][i]) { r = 0.5 * sqrt(_mtx[0][0] + _mtx[1][1] + _mtx[2][2] + 1); im.Set((_mtx[1][2] - _mtx[2][1]) / (4.0 * r), (_mtx[2][0] - _mtx[0][2]) / (4.0 * r), (_mtx[0][1] - _mtx[1][0]) / (4.0 * r)); } else { int j = (i + 1) % 3; int k = (i + 2) % 3; double q = 0.5 * sqrt(_mtx[i][i] - _mtx[j][j] - _mtx[k][k] + 1); im[i] = q; im[j] = (_mtx[i][j] + _mtx[j][i]) / (4 * q); im[k] = (_mtx[k][i] + _mtx[i][k]) / (4 * q); r = (_mtx[j][k] - _mtx[k][j]) / (4 * q); } return GfQuaternion(GfClamp(r, -1.0, 1.0), im); }