//--------------------------------------------------- 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; }
/** * @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; }