void HwShaderExporter::setTexture ( const PBBitmap * bitmap, COLLADASW::Sampler& sampler ) { if ( !bitmap ) { //:TODO: retrieve default values from fx file return; } // Set the texture format. //:TODO: read from BitmapInfo::Type () sampler.setFormat ( EffectTextureExporter::FORMAT ); // Get the necessary exporters. EffectExporter* effectExporter = mDocumentExporter->getEffectExporter (); EffectTextureExporter* textureExporter = effectExporter->getTextureExporter(); // The file name to connect to. #ifdef UNICODE String fileName = bitmap->bi.Name() ? COLLADASW::URI::nativePathToUri( COLLADABU::StringUtils::wideString2utf8String(bitmap->bi.Name()) ) : ""; #else String fileName = bitmap->bi.Name() ? COLLADASW::URI::nativePathToUri( bitmap->bi.Name() ) : ""; #endif // Export, if we have a file name. if ( !fileName.empty () ) { // Get the image path COLLADASW::URI shaderFxFileUri = mEffectProfile->getIncludeURI(); // Take the filename for the unique image name COLLADASW::URI sourceFileUri ( shaderFxFileUri, fileName ); if ( sourceFileUri.getScheme ().empty () ) sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); String maxImageId = /*DocumentExporter::mayaNameToColladaName*/ ( sourceFileUri.getPathFileBase().c_str () ); // Get the image id of the maya image String colladaImageId = textureExporter->findColladaImageId ( maxImageId ); if ( colladaImageId.empty () ) { colladaImageId = textureExporter->getImageIdList ().addId ( maxImageId ); textureExporter->getMaxIdColladaImageId () [maxImageId] = colladaImageId; } // Export the image COLLADASW::Image* colladaImage = textureExporter->exportImage ( maxImageId, colladaImageId, sourceFileUri ); // Get the image id of the exported collada image colladaImageId = colladaImage->getImageId(); // Set the image reference sampler.setImageId ( colladaImageId ); } }
//--------------------------------------------------------------- String EffectTextureExporter::exportImage ( const MObject &texture ) { // Retrieve the texture filename MFnDependencyNode textureNode ( texture ); MString mayaName = textureNode.name(); MPlug filenamePlug = textureNode.findPlug ( ATTR_FILE_TEXTURE_NAME ); // Get the maya image id. String mayaImageId = DocumentExporter::mayaNameToColladaName ( textureNode.name() ); // Generate a COLLADA id for the new light object String colladaImageId; // Check if there is an extra attribute "colladaId" and use this as export id. MString attributeValue; DagHelper::getPlugValue ( texture, COLLADA_ID_ATTRIBUTE_NAME, attributeValue ); if ( attributeValue != EMPTY_CSTRING ) { // Generate a valid collada name, if necessary. colladaImageId = mDocumentExporter->mayaNameToColladaName ( attributeValue, false ); } else { // Generate a COLLADA id for the new light object colladaImageId = DocumentExporter::mayaNameToColladaName ( textureNode.name() ); } // Make the id unique and store it in a map for refernences. colladaImageId = mImageIdList.addId ( colladaImageId ); mMayaIdColladaImageId [mayaImageId] = colladaImageId; // Get the maya filename with the path to the file. MString mayaFileName; filenamePlug.getValue ( mayaFileName ); if ( mayaFileName.length () == 0 ) return NULL; String sourceFile = mayaFileName.asChar (); COLLADASW::URI sourceFileUri ( COLLADASW::URI::nativePathToUri ( sourceFile ) ); if ( sourceFileUri.getScheme ().empty () ) sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); COLLADASW::Image* colladaImage = exportImage ( mayaImageId, colladaImageId, sourceFileUri ); if ( colladaImage == NULL ) return NULL; // Export the node type, because PSD textures don't behave the same as File textures. String nodeType = texture.hasFn ( MFn::kPsdFileTexture ) ? MAYA_TEXTURE_PSDTEXTURE : MAYA_TEXTURE_FILETEXTURE; colladaImage->addExtraTechniqueParameter ( PROFILE_MAYA, MAYA_TEXTURE_NODETYPE, nodeType ); // Export whether this image is in fact an image sequence MPlug imgSeqPlug = textureNode.findPlug ( ATTR_IMAGE_SEQUENCE ); bool isImgSeq = false; imgSeqPlug.getValue ( isImgSeq ); colladaImage->addExtraTechniqueParameter ( PROFILE_MAYA, MAYA_TEXTURE_IMAGE_SEQUENCE, isImgSeq ); return colladaImage->getImageId(); }
// ------------------------------------------------------------ COLLADASW::URI EffectTextureExporter::createTargetURI ( const COLLADASW::URI& sourceUri ) { // Target file String targetFile = mDocumentExporter->getFilename(); COLLADASW::URI targetUri ( COLLADASW::URI::nativePathToUri ( targetFile ) ); const String& targetScheme = targetUri.getScheme (); // Get the pure file name of the source file and set // the source file name to the target path targetUri.setPathFile ( sourceUri.getPathFile () ); if ( !targetScheme.empty () ) targetUri.setScheme ( targetScheme ); else targetUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); // Generate the target file name return targetUri; }
//--------------------------------------------------------------- void DocumentExporter::exportAsset() { COLLADASW::Asset asset ( &mStreamWriter ); // Add contributor information // Set the author String userName = getEnvironmentVariable ( "USERNAME" ); if ( userName.empty() ) userName = getEnvironmentVariable ( "USER" ); if ( !userName.empty() ) asset.getContributor().mAuthor = String ( userName ); const COLLADASW::URI maxFileUri = mExportSceneGraph->getMaxFileUri(); if ( !maxFileUri.getPathFile().empty() ) asset.getContributor().mSourceData = maxFileUri.getURIString(); asset.getContributor().mAuthoringTool = AUTHORING_TOOL; // set *system* unit information int systemUnitType; float systemUnitScale; GetMasterUnitInfo ( &systemUnitType, &systemUnitScale ); switch ( systemUnitType ) { case UNITS_INCHES: asset.setUnit ( "inch", systemUnitScale * 0.0254f ); break; case UNITS_FEET: asset.setUnit ( "feet", systemUnitScale * 0.3048f ); break; case UNITS_MILES: asset.setUnit ( "mile", systemUnitScale * 1609.344f ); break; case UNITS_MILLIMETERS: asset.setUnit ( "millimeter", systemUnitScale * 0.001f ); break; case UNITS_CENTIMETERS: asset.setUnit ( "centimeter", systemUnitScale * 0.01f ); break; case UNITS_METERS: asset.setUnit ( "meter", systemUnitScale ); break; case UNITS_KILOMETERS: asset.setUnit ( "kilometer", systemUnitScale * 1000.0f ); break; default: break; } asset.setUpAxisType ( COLLADASW::Asset::Z_UP ); asset.add(); }
// ------------------------------------------------------------ bool EffectTextureExporter::getTextureFileInfos ( const COLLADASW::URI &sourceUri, COLLADASW::URI &fullFileNameURI ) { bool returnValue = true; // Check if the file exist! String sourceUriString = sourceUri.toNativePath(); if ( ExportOptions::relativePaths() ) { // Different filename and URI, if we copy the textures to the destination directory! if ( ExportOptions::copyTextures() ) { // Get the URI of the COLLADA file. String targetColladaFile = mDocumentExporter->getFilename(); COLLADASW::URI targetColladaUri ( COLLADASW::URI::nativePathToUri ( targetColladaFile ) ); if ( targetColladaUri.getScheme ().empty () ) targetColladaUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); // Get the URI of the copied texture file. COLLADASW::URI textureUri = createTargetURI ( sourceUri ); // Get the texture URI relative to the COLLADA file URI. bool success = false; COLLADASW::URI targetUri = textureUri.getRelativeTo ( targetColladaUri, success ); if ( !success ) { String message = "Not able to generate a relative path from " + textureUri.getURIString() + " to " + targetColladaUri.getURIString() + ". An absolute path will be written! "; MGlobal::displayError ( message.c_str() ); targetUri = textureUri; returnValue = false; } // Get the file URI fullFileNameURI = targetUri; } else { // Get the URI of the COLLADA file. String targetColladaFile = mDocumentExporter->getFilename(); COLLADASW::URI targetColladaUri ( COLLADASW::URI::nativePathToUri ( targetColladaFile ) ); if ( targetColladaUri.getScheme ().empty () ) targetColladaUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); // Get the texture URI relative to the COLLADA file URI. bool success = false; COLLADASW::URI targetUri = sourceUri.getRelativeTo ( targetColladaUri, success ); if ( !success ) { String message = "Not able to generate a relative path from " + sourceUri.getURIString() + " to " + targetColladaUri.getURIString() + ". An absolute path will be written! "; MGlobal::displayError ( message.c_str() ); targetUri = sourceUri; returnValue = false; } // Get the file URI fullFileNameURI = targetUri; } } else { // Different filename and URI, if we copy the textures to the destination directory! if ( ExportOptions::copyTextures() ) { // Get the texture URI relative to the COLLADA file URI. COLLADASW::URI targetUri = createTargetURI ( sourceUri ); // Get the file URI fullFileNameURI = targetUri; } else { // Get the file URI fullFileNameURI = sourceUri; } } return returnValue; }
// ------------------------------- COLLADASW::Image* EffectTextureExporter::exportImage ( const String& mayaImageId, const String& colladaImageId, const COLLADASW::URI& sourceUri ) { // Get the file name and the URI COLLADASW::URI fullFileNameURI; bool sourceFileExist = getTextureFileInfos ( sourceUri, fullFileNameURI ); String fullFileName = fullFileNameURI.toNativePath (); // Have we seen this texture node before? ImageMap::iterator exportedImagesIter = mExportedImageMap.find ( fullFileName ); if ( exportedImagesIter != mExportedImageMap.end() ) { COLLADASW::Image* colladaImage = ( *exportedImagesIter ).second; return colladaImage; } // Check, if we should copy the texture to the destination folder. if ( ExportOptions::copyTextures() ) { // Get the target file from source file. COLLADASW::URI targetUri = createTargetURI ( sourceUri ); if ( !exists ( sourceUri.toNativePath() ) ) { String message = "The source texture file doesn't exist! Filename = " + sourceUri.toNativePath(); std::cerr << message << std::endl; } else { // Copy the texture, if it isn't already there... if ( !exists( targetUri.toNativePath () ) ) { try { // Create the target directory, if necessary. // Note: some systems (window$) requires the string to be // enclosed in quotes when a space is present. COLLADASW::URI targetPathUri ( targetUri.getPathDir() ); create_directory ( targetPathUri.toNativePath() ); // Throws: basic_filesystem_error<Path> if // from_fp.empty() || to_fp.empty() ||!exists(from_fp) || !is_regular(from_fp) || exists(to_fp) copy_file ( path ( sourceUri.toNativePath() ), path ( targetUri.toNativePath() ) ); } catch ( std::exception ex ) { String message = "Could not successful create directory and copy file: " + sourceUri.toNativePath(); MGlobal::displayError( message.c_str() ); std::cerr << "[ERROR] Could not copy file " << sourceUri.toNativePath() << std::endl; } } } } // Create a new image structure COLLADASW::Image* colladaImage = new COLLADASW::Image ( fullFileNameURI, colladaImageId, mayaImageId ); // Export the original maya name. colladaImage->addExtraTechniqueParameter ( PROFILE_MAYA, PARAMETER_MAYA_ID, mayaImageId ); // Add this texture to our list of exported images mExportedImageMap[ fullFileName ] = colladaImage; return colladaImage; }
//--------------------------------------------------------------- void DocumentExporter::exportAsset() { COLLADASW::Asset asset(&mStreamWriter); // Add contributor information // Set the author char* userName = getenv ( USERNAME ); if ( !userName || *userName == 0 ) { userName = getenv ( USER ); } if ( userName && *userName != 0 ) { asset.getContributor().mAuthor = NativeString( userName ).toUtf8String(); } // Source is the scene we have exported from String currentScene = MFileIO::currentFile().asChar(); if ( currentScene.size() > 0 ) { COLLADASW::URI sourceFileUri ( COLLADASW::URI::nativePathToUri ( currentScene ) ); if ( sourceFileUri.getScheme ().empty () ) sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); asset.getContributor().mSourceData = sourceFileUri.getURIString(); } std::size_t foundLast = COLLADABU::CURRENT_REVISION.find_last_of("."); std::size_t foundFirst = COLLADABU::CURRENT_REVISION.find_first_of("."); String versionMajor = COLLADABU::CURRENT_REVISION.substr(0, foundFirst); String versionMinor = COLLADABU::CURRENT_REVISION.substr(foundFirst + 1, foundLast - foundFirst -1 ); asset.getContributor().mAuthoringTool = AUTHORING_TOOL_NAME + MGlobal::mayaVersion().asChar() + (COLLADABU::CURRENT_REVISION.empty() ? "" : String("; ") + String("Version: ") + versionMajor + "." + versionMinor) + (COLLADABU::CURRENT_REVISION.empty() ? "" : String("; ") + String("Revision: ") + COLLADABU::CURRENT_REVISION.substr(foundLast + 1)); // comments MString optstr = MString("\n\t\t\tColladaMaya export options: ") + "\n\t\t\tbakeTransforms=" + ExportOptions::bakeTransforms() + ";relativePaths=" + ExportOptions::relativePaths() + ";preserveSourceTree=" + ExportOptions::preserveSourceTree() + ";copyTextures=" + ExportOptions::copyTextures() + ";exportTriangles=" + ExportOptions::exportTriangles() + ";exportCgfxFileReferences=" + ExportOptions::exportCgfxFileReferences() + ";\n\t\t\tisSampling=" + ExportOptions::isSampling() + ";curveConstrainSampling=" + ExportOptions::curveConstrainSampling() + ";removeStaticCurves=" + ExportOptions::removeStaticCurves() + ";exportPhysics=" + ExportOptions::exportPhysics() + ";exportConvexMeshGeometries=" + ExportOptions::exportConvexMeshGeometries() + ";exportPolygonMeshes=" + ExportOptions::exportPolygonMeshes() + ";exportLights=" + ExportOptions::exportLights() + ";\n\t\t\texportCameras=" + ExportOptions::exportCameras() + ";exportAnimationsOnly=" + ExportOptions::exportAnimationsOnly() + ";exportSeparateFile=" + ExportOptions::exportSeparateFile() + ";modelNameDAE=" + ExportOptions::getDAEmodelName() + ";exportJoints=" + ExportOptions::exportJoints() + ";exportSkin=" + ExportOptions::exportSkin() + ";exportAnimations=" + ExportOptions::exportAnimations() + ";exportOptimizedBezierAnimation=" + ExportOptions::exportOptimizedBezierAnimations() + ";exportInvisibleNodes=" + ExportOptions::exportInvisibleNodes() + ";exportDefaultCameras=" + ExportOptions::exportDefaultCameras() + ";\n\t\t\texportTexCoords=" + ExportOptions::exportTexCoords() + ";exportNormals=" + ExportOptions::exportNormals() + ";exportNormalsPerVertex=" + ExportOptions::exportNormalsPerVertex() + ";exportVertexColors=" + ExportOptions::exportVertexColors() + ";exportVertexColorsPerVertex=" + ExportOptions::exportVertexColorsPerVertex() + ";\n\t\t\texportTexTangents=" + ExportOptions::exportTexTangents() + ";exportTangents=" + ExportOptions::exportTangents() + ";exportReferencedMaterials=" + ExportOptions::exportReferencedMaterials() + ";exportMaterialsOnly=" + ExportOptions::exportMaterialsOnly() + ";\n\t\t\texportXRefs=" + ExportOptions::exportXRefs() + ";dereferenceXRefs=" + ExportOptions::dereferenceXRefs() + ";exportCameraAsLookat=" + ExportOptions::exportCameraAsLookat() + ";cameraXFov=" + ExportOptions::cameraXFov() + ";cameraYFov=" + ExportOptions::cameraYFov() + ";doublePrecision=" + ExportOptions::doublePrecision () + "\n\t\t"; asset.getContributor().mComments = optstr.asChar(); // Up axis if ( MGlobal::isYAxisUp() ) asset.setUpAxisType ( COLLADASW::Asset::Y_UP ); else if ( MGlobal::isZAxisUp() ) asset.setUpAxisType ( COLLADASW::Asset::Z_UP ); // Retrieve the linear unit name MString mayaLinearUnitName; MGlobal::executeCommand ( "currentUnit -q -linear -fullName;", mayaLinearUnitName ); String linearUnitName = mayaLinearUnitName.asChar(); // Get the UI unit type (internal units are centimeter, collada want // a number relative to meters). // All transform components with units will be in maya's internal units // (radians for rotations and centimeters for translations). MDistance testDistance ( 1.0f, MDistance::uiUnit() ); // Get the conversion factor relative to meters for the collada document. // For example, 1.0 for the name "meter"; 1000 for the name "kilometer"; // 0.3048 for the name "foot". double colladaConversionFactor = ( float ) testDistance.as ( MDistance::kMeters ); float colladaUnitFactor = float ( 1.0 / colladaConversionFactor ); asset.setUnit ( linearUnitName, colladaConversionFactor ); // Asset heraus schreiben asset.add(); }
//--------------------------------------- void MaterialExporter::setSetParamTexture ( const cgfxAttrDef* attribute, MObject texture, COLLADASW::Sampler::SamplerType samplerType, COLLADASW::ValueType::ColladaType samplerValueType ) { // Get a pointer to the current stream writer. COLLADASW::StreamWriter* streamWriter = mDocumentExporter->getStreamWriter(); // Get the image id MFnDependencyNode textureNode ( texture ); String plugName = textureNode.name().asChar(); // file1 // Get the file texture name MPlug filenamePlug = textureNode.findPlug ( ATTR_FILE_TEXTURE_NAME ); MString mayaFileName; filenamePlug.getValue ( mayaFileName ); if ( mayaFileName.length() == 0 ) return; String fileName = mayaFileName.asChar (); // Get the image path COLLADASW::URI shaderFxFileUri = getShaderFxFileUri (); // Take the filename for the unique image name COLLADASW::URI sourceFileUri ( shaderFxFileUri, fileName ); if ( sourceFileUri.getScheme ().empty () ) sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); String mayaImageId = DocumentExporter::mayaNameToColladaName ( sourceFileUri.getPathFileBase().c_str () ); // Get the image id of the maya image EffectExporter* effectExporter = mDocumentExporter->getEffectExporter (); String colladaImageId = effectExporter->findColladaImageId ( mayaImageId ); if ( colladaImageId.empty () ) { // Check if there is an extra attribute "colladaId" and use this as export id. MString attributeValue; DagHelper::getPlugValue ( texture, COLLADA_ID_ATTRIBUTE_NAME, attributeValue ); if ( attributeValue != EMPTY_CSTRING ) { // Generate a valid collada name, if necessary. colladaImageId = mDocumentExporter->mayaNameToColladaName ( attributeValue, false ); } else { // Generate a COLLADA id for the new light object colladaImageId = DocumentExporter::mayaNameToColladaName ( textureNode.name() ); } // Make the id unique and store it in a map for refernences. EffectTextureExporter* textureExporter = effectExporter->getTextureExporter (); colladaImageId = textureExporter->getImageIdList ().addId ( colladaImageId ); textureExporter->getMayaIdColladaImageId () [mayaImageId] = colladaImageId; } // Export the image EffectTextureExporter* textureExporter = mDocumentExporter->getEffectExporter()->getTextureExporter(); COLLADASW::Image* colladaImage = textureExporter->exportImage ( mayaImageId, colladaImageId, sourceFileUri ); mayaImageId = colladaImage->getImageId(); // Create the sampler and surface sid String samplerSid = mayaImageId + COLLADASW::Sampler::SAMPLER_SID_SUFFIX; String surfaceSid = mayaImageId + COLLADASW::Sampler::SURFACE_SID_SUFFIX; // Avoid export of dublicate sampler params if ( mSamplers.find ( samplerSid ) != mSamplers.end () ) return; mSamplers.insert ( samplerSid ); // Create the sampler and add the sampler <setparam> COLLADASW::Sampler sampler ( samplerType, samplerSid, surfaceSid ); sampler.setFormat ( EffectTextureExporter::FORMAT ); sampler.setImageId ( colladaImage->getImageId() ); sampler.addInSetParam ( streamWriter ); }
// ------------------------------- COLLADASW::Image* EffectTextureExporter::exportImage ( const String& mayaImageId, const String& colladaImageId, const COLLADASW::URI& sourceUri ) { // Get the file name and the URI COLLADASW::URI fullFileNameURI; bool sourceFileExist = getTextureFileInfos ( sourceUri, fullFileNameURI ); String fullFileName = fullFileNameURI.toNativePath (); // Have we seen this texture node before? ImageMap::iterator exportedImagesIter = mExportedImageMap.find ( fullFileName ); if ( exportedImagesIter != mExportedImageMap.end() ) { COLLADASW::Image* colladaImage = ( *exportedImagesIter ).second; return colladaImage; } // Check, if we should copy the texture to the destination folder. if ( mDocumentExporter->getOptions().getCopyImages() ) { // Get the target file from source file. COLLADASW::URI targetUri = createTargetURI ( sourceUri ); bool exists = COLLADABU::Utils::fileExistsAndIsReadable( sourceUri.toNativePath() ); if ( !exists ) { String message = "The source texture file doesn't exist! Filename = " + sourceUri.toNativePath(); GetCOREInterface()->Log()->LogEntry( SYSLOG_ERROR, DISPLAY_DIALOG, _M( "Image export problem" ),_M( "%s\n" ), message.c_str() ); } else { // Copy the texture, if it isn't already there... exists = COLLADABU::Utils::fileExistsAndIsReadable( targetUri.toNativePath() ); if ( !exists ) { try { // Create the target directory, if necessary. // Note: some systems (window$) requires the string to be // enclosed in quotes when a space is present. COLLADASW::URI targetPathUri ( targetUri.getPathDir() ); exists = COLLADABU::Utils::createDirectoryIfNeeded( targetPathUri.toNativePath() ); if( exists ) { // Throws: basic_filesystem_error<Path> if // from_fp.empty() || to_fp.empty() ||!exists(from_fp) || !is_regular(from_fp) || exists(to_fp) exists = COLLADABU::Utils::copyFile ( sourceUri.toNativePath(), targetUri.toNativePath() ); } } catch ( std::exception ex ) { exists = false; } if( !exists ) { String message = "Could not successful create directory and copy file: " + sourceUri.toNativePath(); GetCOREInterface()->Log()->LogEntry( SYSLOG_ERROR, DISPLAY_DIALOG, _M( "Image export problem" ),_M( "%s\nCould not copy file %s\n" ), message.c_str(), sourceUri.toNativePath().c_str() ); } } } } // Create a new image structure COLLADASW::Image* colladaImage = new COLLADASW::Image ( fullFileNameURI, colladaImageId, mayaImageId ); // Export the original maya name. // colladaImage->addExtraTechniqueParameter ( PROFILE_MAYA, PARAMETER_MAYA_ID, mayaImageId ); // Add this texture to our list of exported images mExportedImageMap[ fullFileName ] = colladaImage; return colladaImage; }