Beispiel #1
0
void CLocalFrame::euler2iang (const CVector &eulerAngle, const SPosition &pos, CVector &tmp_iang) {
  // TODO - Transform orientation to local coordinates, in iang 
  // this is a rotation  
  //
  // 1) transform local position to inertial position
  double rad_pos_x = arcseconds_lat2radians (pos.lat); // rad
  double rad_pos_y = arcseconds_lat2radians (pos.lon); // rad
  double tmp_pos_z = EQUATORIAL_RADIUS_FEET + pos.alt; // ft
  double inert_pos_x = tmp_pos_z * cos (rad_pos_x) * cos (rad_pos_y); // ft
  double inert_pos_y = tmp_pos_z * cos (rad_pos_x) * sin (rad_pos_y); // ft
  double inert_pos_z = tmp_pos_z * sin (rad_pos_x);                   // ft
  //
  // 2) transform local orientation to inertial orientation
  double rot_angle_x = HALF_PI - rad_pos_x;
  double rot_angle_y = HALF_PI + rad_pos_y;
  double sin_half_pos_x = sin (rot_angle_x / 2);
  double sin_half_pos_y = sin (rot_angle_y / 2);
  double cos_half_pos_x = cos (rot_angle_x / 2);
  double cos_half_pos_y = cos (rot_angle_y / 2);
  //
  double sin_half_rot_p = sin (eulerAngle.x / 2);
  double sin_half_rot_r = sin (eulerAngle.y / 2); // RH
  double sin_half_rot_h = sin (eulerAngle.z / 2); // RH
  //double sin_half_rot_r = sin (eulerAngle.z / 2); // LH
  //double sin_half_rot_h = sin (eulerAngle.y / 2); // LH
  double cos_half_rot_p = cos (eulerAngle.x / 2);
  double cos_half_rot_r = cos (eulerAngle.y / 2); // RH
  double cos_half_rot_h = cos (eulerAngle.z / 2); // RH
  //double cos_half_rot_r = cos (eulerAngle.z / 2); // LH
  //double cos_half_rot_h = cos (eulerAngle.y / 2); // LH

    #ifdef _DEBUG_FRAME_MANAGER	
    {	FILE *fp_debug;
	    if(!(fp_debug = fopen("__DDEBUG_AERO_frames.txt", "a")) == NULL)
	    {
		    fprintf(fp_debug, "%f %f pos(%.2f %.2f %.2f %.2f) rot(%.2f %.2f %.2f %.2f %.2f %.2f)\n",
          rot_angle_x,  rot_angle_y,
          sin_half_pos_x, sin_half_pos_y, cos_half_pos_x, cos_half_pos_y,
          sin_half_rot_p, sin_half_rot_r, sin_half_rot_h, cos_half_rot_p, cos_half_rot_r, cos_half_rot_h
         );
		    fclose(fp_debug); 
    }	}
    #endif

  CQuaternion lon     (cos_half_pos_y,              0, 0, sin_half_pos_y),
              lat     (cos_half_pos_x, sin_half_pos_x, 0,              0),
              heading (cos_half_rot_h,              0, 0, sin_half_rot_h),
              pitch   (cos_half_rot_p, sin_half_rot_p, 0,              0),
              banking (cos_half_rot_r,              0, sin_half_rot_r, 0);

  CQuaternion pb, hpb, lahpb, all;
  pb.QuaternionProduct    (&pitch, &banking);
  hpb.QuaternionProduct   (&heading, &pb);
  lahpb.QuaternionProduct (&lat, &hpb);
  all.QuaternionProduct   (&lon, &lahpb);
    #ifdef _DEBUG_FRAME_MANAGER	
    {	FILE *fp_debug;
	    if(!(fp_debug = fopen("__DDEBUG_AERO_frames.txt", "a")) == NULL)
	    {
		    fprintf(fp_debug, "pb(%.2f %.2f %.2f %.2f) hpb(%.2f %.2f %.2f %.2f) lahpb(%.2f %.2f %.2f %.2f) all(%.2f %.2f %.2f %.2f)\n",
          pb.w, pb.v.x, pb.v.y, pb.v.z,
          hpb.w, hpb.v.x, hpb.v.y, hpb.v.z,
          lahpb.w, lahpb.v.x, lahpb.v.y, lahpb.v.z,
          all.w, all.v.x, all.v.y, all.v.z
          );
		    fclose(fp_debug); 
    }	}
    #endif

  CRotMatrix rot;
  //rot.Setup (
  //  arcseconds_lon2radians (pos.lon),
  //  arcseconds_lat2radians (pos.lat)
  //);
  rot.QuaternionToRotMat (all);
    #ifdef _DEBUG_FRAME_MANAGER	
    {	FILE *fp_debug;
	    if(!(fp_debug = fopen("__DDEBUG_AERO_frames.txt", "a")) == NULL)
	    {
		    fprintf(fp_debug, " %.5f %.5f %.5f\n %.5f %.5f %.5f\n %.5f %.5f %.5f\n",
          rot.m11, rot.m12, rot.m13,
          rot.m21, rot.m22, rot.m23,
          rot.m31, rot.m32, rot.m33
          );
		    fclose(fp_debug); 
    }	}
    #endif
  //
  tmp_iang.p = safeAsin /*asin*/  (rot.m23);
  //tmp_iang.r = safeAtan2 (-rot.m13, rot.m33); // LH
  //tmp_iang.h = safeAtan2 (-rot.m21, rot.m22); // LH
  tmp_iang.h = safeAtan2 (-rot.m13, rot.m33); // RH
  tmp_iang.r = safeAtan2 (-rot.m21, rot.m22); // RH

  //rot.TransformItoB (eulerAngle, tmp_iang);

    #ifdef _DEBUG_FRAME_MANAGER	
    {	FILE *fp_debug;
	    if(!(fp_debug = fopen("__DDEBUG_AERO_frames.txt", "a")) == NULL)
	    {
		    fprintf(fp_debug, "euler2iang == lon=%f lat=%f euler(%.2f %.2f %.2f %.2f %.2f %.2f) iang(%.2f %.2f %.2f)\n",
          arcseconds_lon2radians (pos.lon),
          arcseconds_lat2radians (pos.lat),
          eulerAngle.x, eulerAngle.y, eulerAngle.z, eulerAngle.p, eulerAngle.h, eulerAngle.r,
          tmp_iang.x, tmp_iang.y, tmp_iang.z
         );
		    fprintf(fp_debug, "======================================================================================\n");
		    fclose(fp_debug); 
    }	}
    #endif
}
// 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 );
}