//---------------------------------------------------
    void DagHelper::setArrayPlugSize ( MPlug& plug, uint size )
    {
        if ( plug.node().isNull() ) return;

#if MAYA_API_VERSION >= 800
        MStatus status = plug.setNumElements ( size );
        CHECK_STAT ( status );

#else
        MObject node = plug.node();
        MString plugPath = plug.info();
        if ( node.hasFn ( MFn::kDagNode ) )
        {
            MFnDagNode dagFn ( node );
            int dot = plugPath.index ( '.' );
            plugPath = dagFn.fullPathName() + plugPath.substring ( dot, plugPath.length() );
        }

        MString command = MString ( "setAttr -s " ) + size + " \"" + plugPath + "\";";

        MGlobal::executeCommand ( command );
#endif // MAYA 8.00+
    }
    // ------------------------------------
    bool LightExporter::exportLight ( const MDagPath& dagPath )
    {
        if ( !ExportOptions::exportLights() ) return false;

        MObject lightNode = dagPath.node();

        // Retrieve the Maya light object
        MStatus status;
        MFnLight lightFn(lightNode, &status); CHECK_STAT(status);
        if (status != MStatus::kSuccess) return false;

        // Get the maya light id.
        String mayaLightId = mDocumentExporter->dagPathToColladaId ( dagPath );

        // Generate a COLLADA id for the new object
        String colladaLightId;
        
        // Check if there is an extra attribute "colladaId" and use this as export id.
        MString attributeValue;
        DagHelper::getPlugValue ( lightNode, COLLADA_ID_ATTRIBUTE_NAME, attributeValue );
        if ( attributeValue != EMPTY_CSTRING )
        {
            // Generate a valid collada name, if necessary.
            colladaLightId = mDocumentExporter->mayaNameToColladaName ( attributeValue, false );
        }
        else
        {
            // Generate a COLLADA id for the new object
            colladaLightId = mDocumentExporter->dagPathToColladaId ( dagPath );
        }
        // Make the id unique and store it in a map.
        colladaLightId = mLightIdList.addId ( colladaLightId );
        mMayaIdColladaIdMap [ mayaLightId ] = colladaLightId;

        // Get a pointer to the stream writer.
        COLLADASW::StreamWriter* streamWriter = mDocumentExporter->getStreamWriter();

        // The light name
        String lightName = mDocumentExporter->dagPathToColladaName ( dagPath );

        // Figure out the type of light and create it
        COLLADASW::Light* light = NULL;
        MFn::Type type = lightNode.apiType();
        switch (type)
        {
        case MFn::kAmbientLight: 
            light = new COLLADASW::AmbientLight( streamWriter, colladaLightId, lightName ); 
            break; 
        case MFn::kDirectionalLight: 
            light = new COLLADASW::DirectionalLight( streamWriter, colladaLightId, lightName ); 
            break;
        case MFn::kSpotLight: 
            light = new COLLADASW::SpotLight( streamWriter, colladaLightId, lightName ); 
            break;
        case MFn::kPointLight: // Intentional pass-through
        default: 
            light = new COLLADASW::PointLight( streamWriter, colladaLightId, lightName ); 
            break;
        }

        // Export the original maya name.
        light->addExtraTechniqueParameter ( PROFILE_MAYA, PARAMETER_MAYA_ID, mayaLightId );

        // Get a pointer to the animation exporter.
        AnimationExporter* anim = mDocumentExporter->getAnimationExporter();
        bool animated = false;
        
        // Color/Intensity are the common attributes of all lights
        MColor mayaColor = lightFn.color ( &status ); CHECK_STAT(status);
        COLLADASW::Color lightColor ( mayaColor.r, mayaColor.g, mayaColor.b, mayaColor.a );
        animated = anim->addNodeAnimation ( lightNode, ATTR_COLOR, kColour, RGBA_PARAMETERS );
        light->setColor( lightColor, animated );

        float intensity = lightFn.intensity ( &status ); CHECK_STAT(status);
        animated = anim->addNodeAnimation ( lightNode, ATTR_INTENSITY, kSingle );
        light->setIntensity( intensity, animated );
		
		// Export light intensity
		light->addExtraTechniqueParameter(PROFILE_MAYA, ATTR_INTENSITY, intensity);


        // Add the type specific attributes
        if (lightNode.hasFn(MFn::kNonAmbientLight))
        {
            // Needed Point and Spot light types parameters: Attenuation and Attenuation_Scale
            // Attenuation in COLLADA is equal to Decay in Maya.
            MFnNonAmbientLight naLightFn(lightNode);
            int decayRate = naLightFn.decayRate(&status); CHECK_STAT(status);
            decayRate = std::min ( decayRate, 2 ); 
            decayRate = std::max ( decayRate, 0 );

            light->setConstantAttenuation ( ( decayRate == 0 ) ? 1.0f : 0.0f);
            light->setLinearAttenuation ( ( decayRate == 1 ) ? 1.0f : 0.0f);
            light->setQuadraticAttenuation ( ( decayRate == 2 ) ? 1.0f : 0.0f);
        }
        else if (lightNode.hasFn(MFn::kAmbientLight))
        {
            MFnAmbientLight ambientLightFn ( lightNode );
            float ambientShade = ambientLightFn.ambientShade();
            String paramSid = EMPTY_STRING;
            animated = anim->addNodeAnimation ( lightNode, ATTR_AMBIENT_SHADE, kSingle );
            if ( animated ) paramSid = ATTR_AMBIENT_SHADE;
            light->addExtraTechniqueParameter ( PROFILE_MAYA, MAYA_AMBIENTSHADE_LIGHT_PARAMETER, ambientShade, paramSid );
        }

        if (lightNode.hasFn(MFn::kSpotLight))
        {
            // Put in the needed spot light type attributes : Falloff, Falloff_Scale and Angle
            MFnSpotLight spotFn(lightNode);

            float fallOffAngle = COLLADABU::Math::Utils::radToDegF ( (float)spotFn.coneAngle( &status ) ); CHECK_STAT(status);
            animated = anim->addNodeAnimation ( lightNode, ATTR_CONE_ANGLE, ( SampleType ) ( kSingle | kAngle ) );
            light->setFallOffAngle ( fallOffAngle, animated );

            light->setFallOffExponent ( 1.0f );

            float penumbraValue = COLLADABU::Math::Utils::radToDegF ( (float)spotFn.penumbraAngle( &status ) ); CHECK_STAT(status);
            animated = anim->addNodeAnimation ( lightNode, ATTR_PENUMBRA_ANGLE, ( SampleType ) ( kSingle | kAngle ) );


			// Export spot setting
			float dropOff = (float)spotFn.dropOff(&status); CHECK_STAT(status);
			light->addExtraTechniqueParameter(PROFILE_MAYA, MAYA_PENUMBRA_LIGHT_PARAMETER, penumbraValue);
			light->addExtraTechniqueParameter(PROFILE_MAYA, MAYA_DROPOFF_LIGHT_PARAMETER, dropOff);


			// TODO
//            FCDLightTools::LoadPenumbra(light, penumbraValue, colladaLight->GetOuterAngle().GetAnimated());

            // TODO
//             animated = anim->addNodeAnimation ( lightNode, ATTR_DROP_OFF, kSingle );
//             light->setDropOff ( (float) spotFn.dropOff ( &status ), animated ); CHECK_MSTATUS(status);
        }
        
        SceneElement* sceneElement = NULL;
        SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph();
        sceneElement = sceneGraph->findElement(dagPath);
        exportExtraAttributes(sceneElement, light);

        addLight ( *light );
        delete light;

        return true;
    }
Exemplo n.º 3
0
/**
 * @brief Checks to see if can equip/remove an outfit from a slot.
 *
 *    @param p Pilot to check if can equip.
 *    @param s Slot being checked to see if it can equip/remove an outfit.
 *    @param o Outfit to check.
 *    @param add Whether or not to consider it's being added or removed.
 *    @return NULL if can swap, or error message if can't.
 */
const char* pilot_canEquip( Pilot *p, PilotOutfitSlot *s, Outfit *o, int add )
{
   /* Just in case. */
   if ((p==NULL) || (o==NULL))
      return "Nothing selected.";

   /* Check slot type. */
   if ((s != NULL) && !outfit_fitsSlot( o, &s->sslot->slot ))
      return "Does not fit slot.";

   /* Adding outfit. */
   if (add) {
      if ((outfit_cpu(o) > 0) && (p->cpu < outfit_cpu(o)))
         return "Insufficient CPU";

      /* Can't add more than one outfit of the same type if the outfit type is limited. */
      if ((o->limit != NULL) && pilot_hasOutfitLimit( p, o->limit ))
         return "Already have an outfit of this type installed";

      /* Must not drive some things negative. */
      if (outfit_isMod(o)) {
         /*
          * Movement.
          */
         /* TODO fix this to work with ship stats.
         CHECK_STAT_R( o->u.mod.thrust, o->u.mod.thrust_rel, p->ship->thrust, "Insufficient thrust" );
         CHECK_STAT_R( o->u.mod.turn, o->u.mod.turn_rel, p->ship->turn, "Insufficient turn" );
         CHECK_STAT_R( o->u.mod.speed, o->u.mod.speed_rel, p->ship->speed, "Insufficient speed" );
         */

         /*
          * Health.
          */
         /* Max. */
         /* TODO fix this to work with ship stats.
         CHECK_STAT_R( o->u.mod.armour, o->u.mod.armour_rel, p->armour_max, "Insufficient armour" );
         CHECK_STAT_R( o->u.mod.shield, o->u.mod.shield_rel, p->shield_max, "Insufficient shield" );
         CHECK_STAT_R( o->u.mod.energy, o->u.mod.energy_rel, p->energy_max, "Insufficient energy" );
         */
         /* Regen. */
         /* TODO fix this to work with ship stats.
         CHECK_STAT( o->u.mod.armour_regen, p->armour_regen, "Insufficient armour regeneration" );
         CHECK_STAT( o->u.mod.shield_regen, p->shield_regen, "Insufficient shield regeneration" );
         CHECK_STAT( o->u.mod.energy_regen, p->energy_regen, "Insufficient energy regeneration" );
         */

         /*
          * Misc.
          */
         CHECK_STAT( o->u.mod.fuel, p->fuel_max, "Insufficient fuel" );
         CHECK_STAT( o->u.mod.cargo, p->cargo_free, "Insufficient cargo space" );
      }
   }
   /* Removing outfit. */
   else {
      if ((outfit_cpu(o) < 0) && (p->cpu < fabs(outfit_cpu(o))))
         return "Lower CPU usage first";

      /* Must not drive some things negative. */
      if (outfit_isMod(o)) {
         /*
          * Movement.
          */
         /* TODO fix this to work with ship stats.
         if (((o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust) > 0) &&
               (o->u.mod.thrust + o->u.mod.thrust_rel * p->ship->thrust > p->thrust))
            return "Increase thrust first";
         if (((o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed) > 0) &&
               (o->u.mod.speed + o->u.mod.speed_rel * p->ship->speed > p->speed))
            return "Increase speed first";
         if (((o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > 0) &&
               (fabs(o->u.mod.turn + o->u.mod.turn_rel * p->ship->turn * p->ship->mass/p->solid->mass) > p->turn_base))
            return "Increase turn first";
         */

         /*
          * Health.
          */
         /* Max. */
         /* TODO fix this to work with ship stats.
         if ((o->u.mod.armour > 0) &&
               (o->u.mod.armour > p->armour_max))
            return "Increase armour first";
         if ((o->u.mod.shield > 0) &&
               (o->u.mod.shield > p->shield_max))
            return "Increase shield first";
         if ((o->u.mod.energy > 0) &&
               (o->u.mod.energy > p->energy_max))
            return "Increase energy first";
         */
         /* Regen. */
         /* TODO fix this to work with ship stats.
         if ((o->u.mod.armour_regen > 0) &&
               (o->u.mod.armour_regen > p->armour_regen))
            return "Lower energy usage first";
         if ((o->u.mod.shield_regen > 0) &&
               (o->u.mod.shield_regen > p->shield_regen))
            return "Lower shield usage first";
         if ((o->u.mod.energy_regen > 0) &&
               (o->u.mod.energy_regen > p->energy_regen))
            return "Lower energy usage first";
         */

         /*
          * Misc.
          */
         if ((o->u.mod.fuel > 0) &&
               (o->u.mod.fuel > p->fuel_max))
            return "Increase fuel first";
         if ((o->u.mod.cargo > 0) &&
               (o->u.mod.cargo > p->cargo_free))
            return "Increase free cargo space first";

      }
      else if (outfit_isFighterBay(o)) {
         if ((s!=NULL) && (s->u.ammo.deployed > 0))
            return "Recall the fighters first";
      }
   }

   /* Can equip. */
   return NULL;
}