Ejemplo n.º 1
0
Archivo: frustum.cpp Proyecto: JT-a/USD
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);
}
Ejemplo n.º 2
0
Archivo: frustum.cpp Proyecto: JT-a/USD
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);
}
Ejemplo n.º 3
0
Archivo: frustum.cpp Proyecto: JT-a/USD
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);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
Archivo: ray.cpp Proyecto: JT-a/USD
bool
GfRay::Intersect(const GfVec3d &origin,
                 const GfVec3d &axis,
                 const double radius, 
                 const double height,
                 double *enterDistance,
                 double *exitDistance) const
{ 
    GfVec3d unitAxis = axis.GetNormalized();
    
    // Apex of cone
    GfVec3d apex = origin + height * unitAxis;
    
    GfVec3d delta = _startPoint - apex;
    GfVec3d u =_direction - GfDot(_direction, unitAxis) * unitAxis;
    GfVec3d v = delta - GfDot(delta, unitAxis) * unitAxis;
    
    double p = GfDot(_direction, unitAxis);
    double q = GfDot(delta, unitAxis);
    
    double cos2 = GfSqr(height) / (GfSqr(height) + GfSqr(radius));
    double sin2 = 1 - cos2;
    
    double a = cos2 * GfDot(u, u) - sin2 * GfSqr(p);
    double b = 2.0 * (cos2 * GfDot(u, v) - sin2 * p * q);
    double c = cos2 * GfDot(v, v) - sin2 * GfSqr(q);
    
    if (!_SolveQuadratic(a, b, c, enterDistance, exitDistance)) {
        return false;
    }
    
    // Eliminate any solutions on the double cone
    bool enterValid = GfDot(unitAxis, GetPoint(*enterDistance) - apex) <= 0.0;
    bool exitValid = GfDot(unitAxis, GetPoint(*exitDistance) - apex) <= 0.0;
    
    if ((!enterValid) && (!exitValid)) {
        
        // Solutions lie only on double cone
        return false;
    }
    
    if (!enterValid) {
        *enterDistance = *exitDistance;
    }
    else if (!exitValid) {
        *exitDistance = *enterDistance;
    }
        
    return true;
}
Ejemplo n.º 6
0
Archivo: ray.cpp Proyecto: JT-a/USD
bool
GfRay::Intersect(const GfVec3d &origin,
                 const GfVec3d &axis,
                 const double radius,
                 double *enterDistance,
                 double *exitDistance) const
{
    GfVec3d unitAxis = axis.GetNormalized();
    
    GfVec3d delta = _startPoint - origin;
    GfVec3d u = _direction - GfDot(_direction, unitAxis) * unitAxis;
    GfVec3d v = delta - GfDot(delta, unitAxis) * unitAxis;
    
    // Quadratic equation for implicit infinite cylinder
    double a = GfDot(u, u);
    double b = 2.0 * GfDot(u, v);
    double c = GfDot(v, v) - GfSqr(radius);
    
    return _SolveQuadratic(a, b, c, enterDistance, exitDistance);
}
Ejemplo n.º 7
0
Archivo: frustum.cpp Proyecto: JT-a/USD
GfFrustum &
GfFrustum::Transform(const GfMatrix4d &matrix)
{
    // We'll need the old parameters as we build up the new ones, so, work
    // on a newly instantiated frustum. We'll replace the contents of
    // this frustum with it once we are done. Note that _dirty is true
    // by default, so, there is no need to initialize it here.
    GfFrustum frustum;

    // Copy the projection type
    frustum._projectionType = _projectionType;

    // Transform the position of the frustum
    frustum._position = matrix.Transform(_position);

    // Transform the rotation as follows:
    //   1. build view and direction vectors
    //   2. transform them with the given matrix
    //   3. normalize the vectors and cross them to build an orthonormal frame
    //   4. construct a rotation matrix
    //   5. extract the new rotation from the matrix
    
    // Generate view direction and up vector
    GfVec3d viewDir = ComputeViewDirection();
    GfVec3d upVec   = ComputeUpVector();

    // Transform by matrix
    GfVec3d viewDirPrime = matrix.TransformDir(viewDir);
    GfVec3d upVecPrime = matrix.TransformDir(upVec);

    // Normalize. Save the vec size since it will be used to scale near/far.
    double scale = viewDirPrime.Normalize();
    upVecPrime.Normalize();

    // Cross them to get the third axis. Voila. We have an orthonormal frame.
    GfVec3d viewRightPrime = GfCross(viewDirPrime, upVecPrime);
    viewRightPrime.Normalize();

    // Construct a rotation matrix using the axes.
    //
    //  [ right     0 ]
    //  [ up        1 ]
    //  [ -viewDir  0 ]
    //  [ 0  0   0  1 ]
    GfMatrix4d rotMatrix;
    rotMatrix.SetIdentity();
    // first row
    rotMatrix[0][0] = viewRightPrime[0];
    rotMatrix[0][1] = viewRightPrime[1];
    rotMatrix[0][2] = viewRightPrime[2];

    // second row
    rotMatrix[1][0] = upVecPrime[0];
    rotMatrix[1][1] = upVecPrime[1];
    rotMatrix[1][2] = upVecPrime[2];

    // third row
    rotMatrix[2][0] = -viewDirPrime[0];
    rotMatrix[2][1] = -viewDirPrime[1];
    rotMatrix[2][2] = -viewDirPrime[2];

    // Extract rotation
    frustum._rotation = rotMatrix.ExtractRotation();

    // Since we applied the matrix to the direction vector, we can use
    // its length to find out the scaling that needs to applied to the
    // near and far plane. 
    frustum._nearFar = _nearFar * scale;

    // Use the same length to scale the view distance
    frustum._viewDistance = _viewDistance * scale;

    // Transform the reference plane as follows:
    //
    //   - construct two 3D points that are on the reference plane 
    //     (left/bottom and right/top corner of the reference window) 
    //   - transform the points with the given matrix
    //   - move the window back to one unit from the viewpoint and
    //     extract the 2D coordinates that would form the new reference
    //     window
    //
    //     A note on how we do the last "move" of the reference window:
    //     Using similar triangles and the fact that the reference window
    //     is one unit away from the viewpoint, one can show that it's 
    //     sufficient to divide the x and y components of the transformed
    //     corners by the length of the transformed direction vector.
    //
    //     A 2D diagram helps:
    //
    //                            |
    //                            |
    //               |            |
    //       * ------+------------+
    //      vp       |y1          |
    //                            |
    //       \--d1--/             |y2
    //
    //       \-------d2----------/
    //
    //     So, y1/y2 = d1/d2 ==> y1 = y2 * d1/d2 
    //     Since d1 = 1 ==> y1 = y2 / d2
    //     The same argument applies to the x coordinate.
    //
    // NOTE: In an orthographic projection, the last step (division by
    // the length of the vector) is skipped.
    //
    // XXX NOTE2:  The above derivation relies on the
    // fact that GetReferecePlaneDepth() is 1.0.
    // If we ever allow this to NOT be 1, we'll need to fix this up.

    const GfVec2d &min = _window.GetMin();
    const GfVec2d &max = _window.GetMax();

    // Construct the corner points in 3D as follows: construct a starting 
    // point by using the x and y coordinates of the reference plane and 
    // -1 as the z coordinate. Add the position of the frustum to generate 
    // the actual points in world-space coordinates.
    GfVec3d leftBottom = 
        _position + _rotation.TransformDir(GfVec3d(min[0], min[1], -1.0));
    GfVec3d rightTop = 
        _position + _rotation.TransformDir(GfVec3d(max[0], max[1], -1.0));

    // Now, transform the corner points by the given matrix
    leftBottom = matrix.Transform(leftBottom);
    rightTop   = matrix.Transform(rightTop);

    // Subtract the transformed frustum position from the transformed
    // corner points. Then, rotate the points using the rotation that would
    // transform the view direction vector back to (0, 0, -1). This brings 
    // the corner points from the woorld coordinate system into the local 
    // frustum one.
    leftBottom -= frustum._position;
    rightTop   -= frustum._position;
    leftBottom = frustum._rotation.GetInverse().TransformDir(leftBottom);
    rightTop   = frustum._rotation.GetInverse().TransformDir(rightTop);

    // Finally, use the similar triangles trick to bring the corner
    // points back at one unit away from the point. These scaled x and
    // y coordinates can be directly used to construct the new
    // transformed reference plane.  Skip the scaling step for an
    // orthographic projection, though.
    if (_projectionType == Perspective) {
        leftBottom /= scale;
        rightTop   /= scale;
    }

    frustum._window.SetMin(GfVec2d(leftBottom[0], leftBottom[1]));
    frustum._window.SetMax(GfVec2d(rightTop[0],   rightTop[1]));

    // Note that negative scales in the transform have the potential
    // to flip the window.  Fix it if necessary.
    GfVec2d wMin = frustum._window.GetMin();
    GfVec2d wMax = frustum._window.GetMax();
    // Make sure left < right
    if ( wMin[0] > wMax[0] ) {
        std::swap( wMin[0], wMax[0] );
    }
    // Make sure bottom < top
    if ( wMin[1] > wMax[1] ) {
        std::swap( wMin[1], wMax[1] );
    }
    frustum._window.SetMin( wMin );
    frustum._window.SetMax( wMax );

    *this = frustum;

    return *this;
}
Ejemplo n.º 8
0
/* static */
GT_DataArrayHandle
GusdPrimWrapper::convertPrimvarData( const UsdGeomPrimvar& primvar, UsdTimeCode time ) {

    SdfValueTypeName typeName = primvar.GetTypeName();
    if( typeName == SdfValueTypeNames->Int )
    {
        int usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Int32Array( &usdVal, 1, 1 );
    }
    else if( typeName == SdfValueTypeNames->Int64 )
    {
        int64_t usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Int64Array( &usdVal, 1, 1 );
    }
    else if( typeName == SdfValueTypeNames->Float )
    {
        float usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( &usdVal, 1, 1 );
    }
    else if( typeName == SdfValueTypeNames->Double )
    {
        double usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( &usdVal, 1, 1 );
    }
    else if( typeName == SdfValueTypeNames->Float3 )
    {
        GfVec3f usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( usdVal.data(), 1, 3 );
    }
    else if( typeName == SdfValueTypeNames->Double3 )
    {
        GfVec3d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.data(), 1, 3 );
    }
    else if( typeName == SdfValueTypeNames->Color3f )
    {
        GfVec3f usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( usdVal.data(), 1, 3, GT_TYPE_COLOR );
    }
    else if( typeName == SdfValueTypeNames->Color3d )
    {
        GfVec3d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.data(), 1, 3, GT_TYPE_COLOR );
    }
    else if( typeName == SdfValueTypeNames->Normal3f )
    {
        GfVec3f usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( usdVal.data(), 1, 3, GT_TYPE_NORMAL );
    }
    else if( typeName == SdfValueTypeNames->Normal3d )
    {
        GfVec3d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.data(), 1, 3, GT_TYPE_NORMAL );
    }
    else if( typeName == SdfValueTypeNames->Point3f )
    {
        GfVec3f usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( usdVal.data(), 1, 3, GT_TYPE_POINT );
    }
    else if( typeName == SdfValueTypeNames->Point3d )
    {
        GfVec3d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.data(), 1, 3, GT_TYPE_POINT );
    }
    else if( typeName == SdfValueTypeNames->Float4 )
    {
        GfVec4f usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( usdVal.data(), 1, 4 );
    }
    else if( typeName == SdfValueTypeNames->Double4 )
    {
        GfVec4d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.data(), 1, 4 );
    }
    else if( typeName == SdfValueTypeNames->Quatf )
    {
        GfVec4f usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real32Array( usdVal.data(), 1, 4, GT_TYPE_QUATERNION );
    }
    else if( typeName == SdfValueTypeNames->Quatd )
    {
        GfVec4d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.data(), 1, 4, GT_TYPE_QUATERNION );
    }
    else if( typeName == SdfValueTypeNames->Matrix3d )
    {
        GfMatrix3d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.GetArray(), 1, 9, GT_TYPE_MATRIX3 );
    }
    else if( typeName == SdfValueTypeNames->Matrix4d ||
             typeName == SdfValueTypeNames->Frame4d )
    {
        GfMatrix4d usdVal;
        primvar.Get( &usdVal, time );

        return new GT_Real64Array( usdVal.GetArray(), 1, 16, GT_TYPE_MATRIX );
    }
    else if( typeName == SdfValueTypeNames->String )
    {
        string usdVal;
        primvar.Get( &usdVal, time );

        auto     gtString = new GT_DAIndexedString( 1 );
        gtString->setString( 0, 0, usdVal.c_str() );
        return gtString;
    }
    else if( typeName == SdfValueTypeNames->StringArray )
    {
        VtArray<string> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        auto gtString = new GT_DAIndexedString( usdVal.size() );
        for( size_t i = 0; i < usdVal.size(); ++i )
            gtString->setString( i, 0, usdVal[i].c_str() );
        return gtString;
    }
    else if( typeName == SdfValueTypeNames->IntArray )
    {
        VtArray<int> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<int>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Int64Array )
    {
        VtArray<int64_t> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<int64_t>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->FloatArray )
    {
        VtArray<float> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<float>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->DoubleArray )
    {
        VtArray<double> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<double>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Float2Array )
    {
        VtArray<GfVec2f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec2f>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Double2Array )
    {
        VtArray<GfVec2d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec2d>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Float3Array )
    {
        VtArray<GfVec3f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3f>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Double3Array )
    {
        VtArray<GfVec3d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3d>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Color3fArray )
    {
        VtArray<GfVec3f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3f>(usdVal,GT_TYPE_COLOR);
    }
    else if( typeName == SdfValueTypeNames->Color3dArray )
    {
        VtArray<GfVec3d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3d>(usdVal,GT_TYPE_COLOR);
    }
    else if( typeName == SdfValueTypeNames->Vector3fArray )
    {
        VtArray<GfVec3f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3f>(usdVal, GT_TYPE_VECTOR);
    }
    else if( typeName == SdfValueTypeNames->Vector3dArray )
    {
        VtArray<GfVec3d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3d>(usdVal, GT_TYPE_VECTOR);
    }
    else if( typeName == SdfValueTypeNames->Normal3fArray )
    {
        VtArray<GfVec3f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3f>(usdVal, GT_TYPE_NORMAL);
    }
    else if( typeName == SdfValueTypeNames->Normal3dArray )
    {
        VtArray<GfVec3d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3d>(usdVal, GT_TYPE_NORMAL);
    }
    else if( typeName == SdfValueTypeNames->Point3fArray )
    {
        VtArray<GfVec3f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3f>(usdVal, GT_TYPE_POINT);
    }
    else if( typeName == SdfValueTypeNames->Point3dArray )
    {
        VtArray<GfVec3d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec3d>(usdVal, GT_TYPE_POINT);
    }
    else if( typeName == SdfValueTypeNames->Float4Array )
    {
        VtArray<GfVec4f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec4f>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->Double4Array )
    {
        VtArray<GfVec4d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec4d>(usdVal);
    }
    else if( typeName == SdfValueTypeNames->QuatfArray )
    {
        VtArray<GfVec4f> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec4f>(usdVal, GT_TYPE_QUATERNION);
    }
    else if( typeName == SdfValueTypeNames->QuatdArray )
    {
        VtArray<GfVec4d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfVec4d>(usdVal, GT_TYPE_QUATERNION);
    }
    else if( typeName == SdfValueTypeNames->Matrix3dArray )
    {
        VtArray<GfMatrix3d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfMatrix3d>(usdVal, GT_TYPE_MATRIX3);
    }
    else if( typeName == SdfValueTypeNames->Matrix4dArray ||
             typeName == SdfValueTypeNames->Frame4dArray )
    {
        VtArray<GfMatrix4d> usdVal;
        primvar.ComputeFlattened( &usdVal, time );
        return new GusdGT_VtArray<GfMatrix4d>(usdVal, GT_TYPE_MATRIX);
    }
    return NULL;
}
Ejemplo n.º 9
0
void
GfPlane::Set(const GfVec3d &normal, const GfVec3d &point)
{
    _normal = normal.GetNormalized();
    _distance = GfDot(_normal, point);
}