//------------------------------ void LightImporter::importLight ( const COLLADAFW::Light* light ) { // Check if the light is already imported. const COLLADAFW::UniqueId& lightId = light->getUniqueId (); if ( findMayaLightNode ( lightId ) != 0 ) return; // Get the transform nodes, which work with this light instance. VisualSceneImporter* visualSceneImporter = getDocumentImporter ()->getVisualSceneImporter (); const UniqueIdVec* transformNodes = visualSceneImporter->findLightTransformIds ( lightId ); if ( transformNodes == 0 ) { std::cerr << "No transform node which implements this light!" << std::endl; return; } UniqueIdVec::const_iterator nodesIter = transformNodes->begin (); while ( nodesIter != transformNodes->end () ) { // Get the maya node of the current transform node. const COLLADAFW::UniqueId& transformNodeId = *nodesIter; MayaNodesList* mayaNodesList = visualSceneImporter->findMayaTransformNodes ( transformNodeId ); if ( mayaNodesList == 0 ) { std::cerr << "Cant find transform node!" << std::endl; return; } MayaNode* mayaTransformNode = (*mayaNodesList) [0]; String transformNodeName = mayaTransformNode->getName (); // Get the path to the parent transform node. String transformNodePath = mayaTransformNode->getNodePath (); // The first reference is a direct one, the others are instances. if ( nodesIter == transformNodes->begin() ) { // Create the current mesh node. createLight ( light, mayaTransformNode ); } else { // Get the path to the node. MayaNode* mayaLightNode = findMayaLightNode ( lightId ); String lightNodePath = mayaLightNode->getNodePath (); // parent -shape -noConnections -relative -addObject "|pCube1|pCubeShape1" "pCube2"; FILE* file = getDocumentImporter ()->getFile (); MayaDM::parentShape ( file, lightNodePath, transformNodePath, false, true, true, true ); } ++nodesIter; } }
//------------------------------ void LightImporter::createAndAddAmbientLight( const COLLADAFW::Light* light ) { if ( light->getLightType() == COLLADAFW::Light::AMBIENT_LIGHT ) { getDocumentImporter()->addAmbientColor(light->getColor()); } }
//------------------------------ void LightImporter::initialiseDefaultLightObjects () { // Get a reference to the current maya ascii file. FILE* file = getDocumentImporter ()->getFile (); // Create the default light linker mDefaultLightLinker.setFile ( file ); mDefaultLightLinker.setName ( DEFAULT_LIGHT_LINKER_NAME ); // Create a object for the default light list. mDefaultLightList.setFile ( file ); mDefaultLightList.setName ( ":" + DEFAULT_LIGHT_LIST_NAME ); // Create a object for the default light set. mDefaultLightSet.setFile ( file ); mDefaultLightSet.setName ( ":" + DEFAULT_LIGHT_SET_NAME ); }
// -------------------------- void LightImporter::connectLightObjects () { // The maya ascii file. FILE* file = getDocumentImporter ()->getFile (); size_t lightIndex = 0; size_t lightSetIndex = 0; UniqueIdMayaNodeMap::iterator it = mMayaLightNodesMap.begin (); while ( it != mMayaLightNodesMap.end () ) { const COLLADAFW::UniqueId& lightId = it->first; MayaNode* mayaNode = it->second; MayaDM::DependNode* dependNode = findMayaLight ( lightId ); MayaDM::Light* lightNode = ( MayaDM::Light* ) dependNode; dependNode->setName ( mayaNode->getNodePath () ); // Connect the light data of the lights (just real ones, no instances), with the light list. //connectAttr "|spotLight1|spotLightShape1.lightData" ":lightList1.lights" -nextAvailable; //connectAttr "spotLightShape2.lightData" ":lightList1.lights" -nextAvailable; connectAttr ( file, lightNode->getLightData (), mDefaultLightList.getLights ( lightIndex ) ); ++lightIndex; // Get the transform nodes, which work with this light instance. VisualSceneImporter* visualSceneImporter = getDocumentImporter ()->getVisualSceneImporter (); const UniqueIdVec* transformNodes = visualSceneImporter->findLightTransformIds ( lightId ); if ( transformNodes == 0 ) { std::cerr << "No transform node which implements this light!" << std::endl; return; } size_t nodeIndex = 0; UniqueIdVec::const_iterator nodesIter = transformNodes->begin (); while ( nodesIter != transformNodes->end () ) { // Get the maya transform nodes and read the path. const COLLADAFW::UniqueId& transformNodeId = *nodesIter; MayaNodesList* transformNodes = visualSceneImporter->findMayaTransformNodes ( transformNodeId ); if ( transformNodes->size () == 0 ) { std::cerr << "The referenced transform node doesn't exist!" << std::endl; return; } MayaNode* mayaTransformNode = (*transformNodes) [0]; String transformNodeName = mayaTransformNode->getName (); String transformNodePath = mayaTransformNode->getNodePath (); MayaDM::Transform transformNode ( file, transformNodePath, EMPTY_STRING, false, false ); // Connect the light transforms instance object groups with the default light set. //connectAttr "spotLight1.instObjGroups" ":defaultLightSet.dagSetMembers" -nextAvailable; //connectAttr "|spotLight2.instObjGroups" ":defaultLightSet.dagSetMembers" -nextAvailable; //connectAttr "spotLight3.instObjGroups" ":defaultLightSet.dagSetMembers" -nextAvailable; connectNextAttr ( file, transformNode.getInstObjGroups (), mDefaultLightSet.getDagSetMembers () ); //connectAttr ( file, transformNode.getInstObjGroups (0), mDefaultLightSet.getDagSetMembers (lightSetIndex) ); ++lightSetIndex; ++nodesIter; } ++it; } }
// -------------------------- void LightImporter::connectLightLinkers () { // The maya ascii file. FILE* file = getDocumentImporter ()->getFile (); size_t lightLinkerLinkIndex = 0; // Get the default light set. MayaDM::ObjectSet defaultLightSet ( file, DEFAULT_LIGHT_SET_NAME, EMPTY_STRING, false, false ); // Connect the existing shader engines with the first light linker link's object. MaterialImporter* materialImporter = getDocumentImporter ()->getMaterialImporter (); const MaterialImporter::ShadingDataMap& shadingDataMap = materialImporter->getShadingEnginesMap (); MaterialImporter::ShadingDataMap::const_iterator it = shadingDataMap.begin (); while ( it != shadingDataMap.end () ) { MaterialImporter::ShadingData* shadingData = it->second; const MayaDM::ShadingEngine& shadingEngine = shadingData->getShadingEngine (); // Connect the the default light set message with the next light linker link's light // connectAttr ":defaultLightSet.message" "lightLinker1.link[0].light"; connectAttr ( file, defaultLightSet.getMessage (), mDefaultLightLinker.getLight ( lightLinkerLinkIndex ) ); // Connect the current shading engine's message with the next light linker link's object. // connectAttr "lambert2SG.message" "lightLinker1.link[0].object"; connectAttr ( file, shadingEngine.getMessage (), mDefaultLightLinker.getObject ( lightLinkerLinkIndex ) ); // Connect the the default light set message with the next light linker shadow link's shadow light // connectAttr ":defaultLightSet.message" "lightLinker1.shadowLink[0].shadowLight"; connectAttr ( file, defaultLightSet.getMessage (), mDefaultLightLinker.getShadowLight ( lightLinkerLinkIndex ) ); // Connect the current shading engine's message with the next light linker shadow link's shadow object. // connectAttr "lambert2SG.message" "lightLinker1.shadowLink[0].shadowObject"; connectAttr ( file, shadingEngine.getMessage (), mDefaultLightLinker.getShadowObject ( lightLinkerLinkIndex ) ); // Increment the light linker index ++lightLinkerLinkIndex; ++it; } // Create the dummy object of the initial shading group. MayaDM::ShadingEngine initialShadingEngine ( file, ":" + MaterialImporter::INITIAL_SHADING_ENGINE_NAME, EMPTY_STRING, false, false ); // Connect the default light set message with the next light linker link's light // connectAttr ":defaultLightSet.message" "lightLinker1.link[1].light"; connectAttr ( file, defaultLightSet.getMessage (), mDefaultLightLinker.getLight ( lightLinkerLinkIndex ) ); // Connect the initial shading group message with the next light linker link's object // connectAttr ":initialShadingGroup.message" "lightLinker1.link[1].object"; connectAttr ( file, initialShadingEngine.getMessage (), mDefaultLightLinker.getObject ( lightLinkerLinkIndex ) ); // Connect the default light set message with the light linker shadow link's shadow light // connectAttr ":defaultLightSet.message" "lightLinker1.shadowLink[1].shadowLight"; connectAttr ( file, defaultLightSet.getMessage (), mDefaultLightLinker.getShadowLight ( lightLinkerLinkIndex ) ); // Connect the initial shading group message with the next light linker shadow link's shadow object // connectAttr ":initialShadingGroup.message" "lightLinker1.shadowLink[1].shadowObject"; connectAttr ( file, initialShadingEngine.getMessage (), mDefaultLightLinker.getShadowObject ( lightLinkerLinkIndex ) ); // Connect the light linker the initial light list link Nodes // connectAttr "lightLinker1.message" ":lightList1.linkNodes" -nextAvailable; connectAttr ( file, mDefaultLightLinker.getMessage (), mDefaultLightList.getLinkNodes (0) ); }
// -------------------------------------------- void LightImporter::createLight ( const COLLADAFW::Light* light, MayaNode* mayaTransformNode ) { // Check if the camera is already imported. const COLLADAFW::UniqueId& lightId = light->getUniqueId (); // Make the maya name unique and manage it in all necessary lists. String lightName = light->getName (); if ( lightName.empty () ) lightName = LIGHT_NAME; lightName = DocumentImporter::frameworkNameToMayaName ( lightName ); const ExtraDataCallbackHandler& callbackHandler = getDocumentImporter ()->getMayaIdCallbackHandler (); String originalMayaId = getOriginalMayaId ( callbackHandler, lightId, COLLADASaxFWL15::HASH_ELEMENT_LIGHT ); if ( !originalMayaId.empty () ) lightName = originalMayaId; lightName = generateUniqueDagNodeName ( lightName, mayaTransformNode ); // Create a maya node object of the current node and push it into the map. MayaNode* mayaLightNode = new MayaNode ( lightId, lightName, mayaTransformNode ); mMayaLightNodesMap [ lightId ] = mayaLightNode; FILE* file = getDocumentImporter ()->getFile (); MayaDM::Light* mayaLight = 0; COLLADAFW::Light::LightType lightType = light->getLightType (); switch ( lightType ) { case COLLADAFW::Light::AMBIENT_LIGHT: { mayaLight = new MayaDM::AmbientLight ( file, lightName, mayaTransformNode->getNodePath () ); } break; case COLLADAFW::Light::DIRECTIONAL_LIGHT: { mayaLight = new MayaDM::DirectionalLight ( file, lightName, mayaTransformNode->getNodePath () ); } break; case COLLADAFW::Light::POINT_LIGHT: { mayaLight = new MayaDM::PointLight ( file, lightName, mayaTransformNode->getNodePath () ); setPointLightAttributes ( light, mayaLight ); } break; case COLLADAFW::Light::SPOT_LIGHT: { mayaLight = new MayaDM::SpotLight ( file, lightName, mayaTransformNode->getNodePath () ); setSpotLightAttributes ( light, mayaLight ); } break; default: std::cerr << "Unknown light type!" << std::endl; return; } // Add the original id attribute. String colladaId = light->getOriginalId (); if ( !colladaId.empty () ) { MayaDM::addAttr ( file, COLLADA_ID_ATTRIBUTE_NAME, ATTRIBUTE_DATA_TYPE, ATTRIBUTE_TYPE_STRING ); MayaDM::setAttr ( file, COLLADA_ID_ATTRIBUTE_NAME, ATTRIBUTE_TYPE, ATTRIBUTE_TYPE_STRING, colladaId ); } // // TODO Add the attributes for all the extra tags. // setExtraData ( light->getExtraDataArray () ); // Set the standard light color. COLLADAFW::Color color = light->getColor (); mayaLight->setColor ( MayaDM::float3 ( (float)color.getRed (), (float)color.getGreen (), (float)color.getBlue () ) ); // Store the light in a map. appendLight ( lightId, mayaLight ); }
//------------------------------ StdMat2* MaterialCreator::createStandardMaterial( const COLLADAFW::EffectCommon& effectCommon, const String& name, const MaterialCreator::MaterialIdentifier& materialIdentifier ) { StdMat2* material = NewDefaultStdMat(); COLLADAFW::EffectCommon::ShaderType shaderType = effectCommon.getShaderType(); switch ( shaderType ) { case COLLADAFW::EffectCommon::SHADER_CONSTANT: material->SetFaceted(true); // BUG393: Max actually does not support a constant shader! case COLLADAFW::EffectCommon::SHADER_BLINN: material->SwitchShader(Class_ID(StandardMaterial::STD2_BLINN_SHADER_CLASS_ID, 0)); break; case COLLADAFW::EffectCommon::SHADER_LAMBERT: case COLLADAFW::EffectCommon::SHADER_PHONG: case COLLADAFW::EffectCommon::SHADER_UNKNOWN: default: material->SwitchShader(Class_ID(StandardMaterial::STD2_PHONG_CLASS_ID, 0)); break; } // Retrieve the shader parameter blocks Shader* materialShader = material->GetShader(); IParamBlock2* shaderParameters = (IParamBlock2*) materialShader->GetReference(0); IParamBlock2* extendedParameters = (IParamBlock2*) material->GetReference(StandardMaterial::EXTENDED_PB_REF); // Common material parameters material->SetName(name.c_str()); const COLLADAFW::ColorOrTexture& diffuse = effectCommon.getDiffuse(); if ( diffuse.isColor() ) material->SetDiffuse( toMaxColor(diffuse), 0); const COLLADAFW::ColorOrTexture& emission = effectCommon.getEmission(); if ( emission.isColor() ) { material->SetSelfIllumColorOn(TRUE); material->SetSelfIllumColor( toMaxColor(emission), 0); } else { material->SetSelfIllumColorOn(FALSE); material->SetSelfIllum( 0, 0 ); } float maxOpacity = 1; const COLLADAFW::ColorOrTexture& opacity = effectCommon.getOpacity(); if ( opacity.isColor() ) { const COLLADAFW::Color& opacityColor = opacity.getColor(); float averageTransparent = (float)(opacityColor.getRed() + opacityColor.getGreen() + opacityColor.getBlue())/3; maxOpacity = averageTransparent; } if ( getDocumentImporter()->getInvertTransparency() ) { maxOpacity = 1 - maxOpacity; } // Max seems to like to have opacity 0 for opacity textures if ( opacity.isTexture() ) { material->SetOpacity( 0, 0); } else { material->SetOpacity( maxOpacity, 0); } if (shaderType != COLLADAFW::EffectCommon::SHADER_CONSTANT && shaderType != COLLADAFW::EffectCommon::SHADER_UNKNOWN) { // Unlock the ambient and diffuse colors materialShader->SetLockAD(FALSE); materialShader->SetLockADTex(FALSE); material->LockAmbDiffTex(FALSE); material->SyncADTexLock(FALSE); // Lambert/Phong material parameters const COLLADAFW::ColorOrTexture& ambient = effectCommon.getAmbient(); if ( ambient.isColor() ) material->SetAmbient( toMaxColor(ambient), 0); } else { // Approximate constant shader, specular is the same color if ( diffuse.isColor() ) material->SetSpecular( toMaxColor(diffuse), 0 ); } const COLLADAFW::ColorOrTexture& specular = effectCommon.getSpecular(); const COLLADAFW::FloatOrParam& shininessFloatOrParam = effectCommon.getShininess(); float shininess = 1; if ( shininessFloatOrParam.getType() == COLLADAFW::FloatOrParam::FLOAT ) { shininess = shininessFloatOrParam.getFloatValue(); } if ( shaderType == COLLADAFW::EffectCommon::SHADER_PHONG || shaderType == COLLADAFW::EffectCommon::SHADER_BLINN) { // Phong material parameters if ( specular.isColor() ) material->SetSpecular( toMaxColor(specular), 0 ); material->SetShininess(ConversionFunctors::fromPercent(shininess), 0); material->SetShinStr(ConversionFunctors::fromPercent(shininess), 0); } //create and assign textures createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getAmbient, ID_AM, materialIdentifier.ambientMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getDiffuse, ID_DI, materialIdentifier.diffuseMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getSpecular, ID_SP, materialIdentifier.specularMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getEmission, ID_SI, materialIdentifier.emissionMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getOpacity, ID_OP, materialIdentifier.opacityMapChannel); return material; }