void ControllerExporter::export_morph_controller(Object *ob, Key *key)
{
	bool use_instantiation = this->export_settings->use_object_instantiation;
	Mesh *me;

	me = bc_get_mesh_copy(scene,
				ob,
				this->export_settings->export_mesh_type,
				this->export_settings->apply_modifiers,
				this->export_settings->triangulate);

	std::string controller_name = id_name(ob) + "-morph";
	std::string controller_id = get_controller_id(key, ob);

	openMorph(controller_id, controller_name,
	         COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation)));

	std::string targets_id = add_morph_targets(key, ob);
	std::string morph_weights_id = add_morph_weights(key, ob);
	
	COLLADASW::TargetsElement targets(mSW);

	COLLADASW::InputList &input = targets.getInputList();

	input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_TARGET, // constant declared in COLLADASWInputList.h
	                                 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, targets_id)));
	input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT,
	                                 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id)));
	targets.add();

	BKE_libblock_free_us(G.main, me);


	//support for animations
	//can also try the base element and param alternative
	add_weight_extras(key);
	closeMorph();
	closeController();
}
	//---------------------------------------------------------------
	void ControllerExporter::exportMorphController( ExportNode* exportNode, MorphController* morphController, const String& controllerId, const String& morphSource )
	{
		MorphR3* morpher = morphController->getMorph();


		FloatList listOfWeights;
		StringList listOfTargetIds;

		String weightsId = controllerId + WEIGHTS_SOURCE_ID_SUFFIX;

		size_t channelBankCount = morpher->chanBank.size();
		for ( size_t i = 0; i<channelBankCount; ++i)
		{
			morphChannel& channel = morpher->chanBank[i];
			
			if (!channel.mActive || channel.mNumPoints == 0) 
				continue;

			INode* targetINode = channel.mConnection;

			listOfWeights.push_back(ConversionFunctors::fromPercent(channel.cblock->GetFloat(morphChannel::cblock_weight_index, mDocumentExporter->getOptions().getAnimationStart())));

			Control* weightController = channel.cblock->GetController(morphChannel::cblock_weight_index);
			mDocumentExporter->getAnimationExporter()->addAnimatedFloat(weightController, weightsId, EMPTY_STRING, (int)i, true, &ConversionFunctors::fromPercent );

			if ( !targetINode )
			{
				MorphControllerHelperGeometry morphControllerHelperGeometry;
				morphControllerHelperGeometry.exportNode = exportNode;
				morphControllerHelperGeometry.controllerId = controllerId;
				morphControllerHelperGeometry.morphController = morphController;
				morphControllerHelperGeometry.channelBankindex = i;
				
				String targetId = ExportSceneGraph::getMorphControllerHelperId(morphControllerHelperGeometry);
				listOfTargetIds.push_back(targetId);
			}
			else
			{
				ExportNode* targetExportNode = mExportSceneGraph->getExportNode(targetINode);
				assert(targetExportNode);

				ExportNode* geometryExportNode = mDocumentExporter->getExportedObjectExportNode(ObjectIdentifier(targetExportNode->getInitialPose()));
				assert( geometryExportNode );
//				listOfTargetIds.push_back(geometryExportNode);
				listOfTargetIds.push_back(GeometriesExporter::getGeometryId(*geometryExportNode));
			}
		}

		openMorph(controllerId, EMPTY_STRING, morphSource);

		//export weights source
		String targetId = controllerId + TARGETS_SOURCE_ID_SUFFIX;
		COLLADASW::IdRefSource targetsSource(mSW);
		targetsSource.setId(targetId);
		targetsSource.setArrayId(targetId + ARRAY_ID_SUFFIX);
		targetsSource.setAccessorStride(1);
		targetsSource.getParameterNameList().push_back("MORPH_TARGET");
		targetsSource.setAccessorCount((unsigned long)listOfTargetIds.size());
		targetsSource.prepareToAppendValues();

		for ( StringList::const_iterator it = listOfTargetIds.begin(); it != listOfTargetIds.end(); ++it)
			targetsSource.appendValues(*it);

		targetsSource.finish();


		//export weights source
		COLLADASW::FloatSource weightsSource(mSW);
		weightsSource.setId(weightsId);
		weightsSource.setArrayId(weightsId + ARRAY_ID_SUFFIX);
		weightsSource.setAccessorStride(1);
		weightsSource.getParameterNameList().push_back("MORPH_WEIGHT");
		weightsSource.setAccessorCount((unsigned long)listOfWeights.size());
		weightsSource.prepareToAppendValues();
		
		for ( FloatList::const_iterator it = listOfWeights.begin(); it != listOfWeights.end(); ++it)
			weightsSource.appendValues(*it);
		
		weightsSource.finish();


		COLLADASW::TargetsElement targets(mSW);
		targets.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_TARGET, "#" + targetId));
		targets.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT, "#" + weightsId));
		targets.add();

		closeMorph();

	}