Ejemplo n.º 1
0
MTransformationMatrix SurfaceAttach::matrix(const MFnNurbsSurface &fnSurface, const int plugID, const double dataOffset,
                                            const bool dataReverse, const short dataGenus, const double dataStaticLength,
                                            const MMatrix &dataParentInverse, const short dataDirection) {
    // Do all the Fancy stuff to input UV values
    double parmU = this->uInputs[plugID];
    double parmV = this->vInputs[plugID];

    // Fix U Flipping from 1.0 to 0.0
    if (uInputs[plugID] == 1.0 && parmU == 0.0)
        parmU = 1.0;
    if (vInputs[plugID] == 1.0 && parmV == 0.0)
        parmV = 1.0;

    if (dataDirection == 0)
        this->calculateUV(plugID, dataOffset, dataReverse, dataGenus, dataStaticLength, parmU);
    else
        this->calculateUV(plugID, dataOffset, dataReverse, dataGenus, dataStaticLength, parmV);

    // Calculate transformations from UV values
    const MVector normal = fnSurface.normal(parmU, parmV, MSpace::Space::kWorld);

    MPoint point;
    fnSurface.getPointAtParam(parmU, parmV, point, MSpace::Space::kWorld);

    MVector tanU, tanV;
    fnSurface.getTangents(parmU, parmV, tanU, tanV, MSpace::Space::kWorld);

    const double dubArray[4][4] = { tanU.x, tanU.y, tanU.z, 0.0,
                                    normal.x, normal.y, normal.z, 0.0,
                                    tanV.x, tanV.y, tanV.z, 0.0,
                                    point.x, point.y, point.z, 1.0 };
    const MMatrix mat (dubArray);

    return MTransformationMatrix (mat * dataParentInverse);
}
Ejemplo n.º 2
0
MTransformationMatrix ffdPlanar::getXyzToStuTransformation( MBoundingBox& boundingBox )
{
    MTransformationMatrix transform = MTransformationMatrix();
    
    double scale[3] = { FFD_DIMENSIONS_S > 0 ? 1.f / boundingBox.width() : 1.f,
                        FFD_DIMENSIONS_T > 0 ? 1.f / boundingBox.height() : 1.f,
                        FFD_DIMENSIONS_U > 0 ? 1.f / boundingBox.depth() : 1.f };
    
    transform.addScale( scale, MSpace::kObject );
    
    MVector boundsMinOffset = MPoint::origin - boundingBox.min();
    transform.addTranslation( boundsMinOffset, MSpace::kObject );
    
    return transform;
}
Ejemplo n.º 3
0
// The compute() method does the actual work of the node using the inputs
// of the node to generate its output.
//
// Compute takes two parameters: plug and data.
// - Plug is the the data value that needs to be recomputed
// - Data provides handles to all of the nodes attributes, only these
//   handles should be used when performing computations.
//
MStatus motionPathNode::compute( const MPlug& plug, MDataBlock& data )
{
    double	f;
    MStatus status;

    // Read the attributes we need from the datablock.
    //
    double	uVal			= data.inputValue( uValue ).asDouble();
    bool	fractionModeVal	= data.inputValue( fractionMode ).asBool();
    bool	followVal		= data.inputValue( follow ).asBool();
    int		frontAxisVal	= data.inputValue( frontAxis ).asShort();
    int		upAxisVal		= data.inputValue( upAxis ).asShort();
    bool	bankVal			= data.inputValue( bank ).asBool();
    double  bankScaleVal	= data.inputValue( bankScale ).asDouble();
    double  bankThresholdVal= data.inputValue( bankThreshold ).asDouble();
    double	offsetVal		= data.inputValue( offset ).asDouble();
    double	wobbleRateVal	= data.inputValue( wobbleRate ).asDouble();

    // Make sure the value is fractional.
    //
    if ( fractionModeVal ) {
        f = uVal;
    } else {
        f = parametricToFractional( uVal, &status );
    }
    CHECK_MSTATUS_AND_RETURN_IT( status );

    // To compute the sample location on the path, first wrap the fraction
    // around the start of the the path in case it goes past the end
    // to prevent clamping, then compute the sample location on the path.
    //
    f = wraparoundFractionalValue( f, &status );
    CHECK_MSTATUS_AND_RETURN_IT( status );

    MPoint location = position( data, f, &status );
    CHECK_MSTATUS_AND_RETURN_IT( status );

    // Get the orthogonal vectors on the motion path.
    //
    const MVector worldUp = MGlobal::upAxis();
    MVector	front, side, up;
    CHECK_MSTATUS_AND_RETURN_IT( getVectors( data, f, front, side, up,
                                 &worldUp ) );

    // If follow (i.e. rotation) is enabled, check if banking is also
    // enabled and if so, bank into the turn.
    //
    if ( followVal && bankVal ) {
        MQuaternion bankQuat = banking( data, f, worldUp,
                                        bankScaleVal, bankThresholdVal, &status );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        up = up.rotateBy( bankQuat );
        side = front ^ up;
    }

    // Compute the wobble that moves the sphere back and forth as it
    // traverses the path.
    //
    if ( fabs( offsetVal ) > ALMOST_ZERO
            && fabs( wobbleRateVal ) > ALMOST_ZERO ) {
        double wobble = offsetVal * sin( TWO_PI * wobbleRateVal * f );
        MVector tmp = side * wobble;
        location += tmp;
    }

    // Write the result values to the output plugs.
    //
    data.outputValue( allCoordinates ).set( location.x, location.y,
                                            location.z );
    if ( followVal ) {
        MTransformationMatrix	resultOrientation = matrix( front, side,
                up, frontAxisVal, upAxisVal, &status );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        MTransformationMatrix::RotationOrder ro
            = (MTransformationMatrix::RotationOrder)
              ( data.inputValue( rotateOrder ).asShort() + 1 );
        double  rot[3];
        status = MTransformationMatrix( resultOrientation ).getRotation(
                     rot, ro );
        CHECK_MSTATUS_AND_RETURN_IT( status );
        data.outputValue( rotate ).set( rot[0], rot[1], rot[2] );
    }

    return( MS::kSuccess );
}