Exemplo n.º 1
0
void FloatPlacement::initFloatTypeCO(FloatList const & floats)
{
	if (float_list_ == &floats)
		return;

	float_list_ = &floats;
	floatTypeCO->clear();
	FloatList::const_iterator it = floats.begin();
	FloatList::const_iterator const end = floats.end();
	for (; it != end; ++it) {
		floatTypeCO->addItem(qt_(it->second.name()),
				     toqstr(it->second.floattype()));
	}
}
Exemplo n.º 2
0
	void GenerateSampledAnimation(FCDSceneNode* node)
	{
		sampleKeys.clear();
		sampleValues.clear();

		FCDAnimatedList animateds;
		// Special case for rotation angles: need to check for changes that are greater than 180 degrees.
		Int32List angleIndices;
		
		// Collect all the animation curves
		size_t transformCount = node->GetTransformCount();
		for (size_t t = 0; t < transformCount; ++t)
		{
			FCDTransform* transform = node->GetTransform(t);
			FCDAnimated* animated = transform->GetAnimated();
			if (animated != NULL)
			{
				if (animated->HasCurve()) animateds.push_back(animated);

				// Figure out whether this is a rotation and then, which animated value contains the angle.
				if (!transform->HasType(FCDTRotation::GetClassType())) angleIndices.push_back(-1);
				else angleIndices.push_back((int32) animated->FindQualifier(".ANGLE"));
			}
		}
		if (animateds.empty()) return;

		// Make a list of the ordered key times to sample
		size_t animatedsCount = animateds.size();
		for (size_t i = 0; i < animatedsCount; ++i)
		{
			FCDAnimated* animated = animateds[i];
			int32 angleIndex = angleIndices[i];

			const FCDAnimationCurveListList& allCurves = animated->GetCurves();
			size_t valueCount = allCurves.size();
			for (size_t curveIndex = 0; curveIndex < valueCount; ++curveIndex)
			{
				const FCDAnimationCurveTrackList& curves = allCurves[curveIndex];
				if (curves.empty()) continue;

				size_t curveKeyCount = curves.front()->GetKeyCount();
				const FCDAnimationKey** curveKeys = curves.front()->GetKeys();
				size_t sampleKeyCount = sampleKeys.size();
				
				// Merge this curve's keys in with the sample keys
				// This assumes both key lists are in increasing order
				size_t s = 0, c = 0;
				while (s < sampleKeyCount && c < curveKeyCount)
				{
					float sampleKey = sampleKeys[s], curveKey = curveKeys[c]->input;
					if (IsEquivalent(sampleKey, curveKey)) { ++s; ++c; }
					else if (sampleKey < curveKey) { ++s; }
					else
					{
						// Add this curve key to the sampling key list
						sampleKeys.insert(sampleKeys.begin() + (s++), curveKeys[c++]->input);
						sampleKeyCount++;
					}
				}

				// Add all the left-over curve keys to the sampling key list
				while (c < curveKeyCount) sampleKeys.push_back(curveKeys[c++]->input);

				// Check for large angular rotations..
				if (angleIndex == (intptr_t) curveIndex)
				{
					for (size_t c = 1; c < curveKeyCount; ++c)
					{
						const FCDAnimationKey* previousKey = curveKeys[c - 1];
						const FCDAnimationKey* currentKey = curveKeys[c];
						float halfWrapAmount = (currentKey->output - previousKey->output) / 180.0f;
						halfWrapAmount *= FMath::Sign(halfWrapAmount);
						if (halfWrapAmount >= 1.0f)
						{
							// Need to add sample times.
							size_t addSampleCount = (size_t) floorf(halfWrapAmount);
							for (size_t d = 1; d <= addSampleCount; ++d)
							{
								float fd = (float) d;
								float fid = (float) (addSampleCount + 1 - d);
								float addSampleTime = (currentKey->input * fd + previousKey->input * fid) / (fd + fid);
								
								// Sorted insert.
								float* endIt = sampleKeys.end();
								for (float* sampleKeyTime = sampleKeys.begin(); sampleKeyTime != endIt; ++sampleKeyTime)
								{
									if (IsEquivalent(*sampleKeyTime, addSampleTime)) break;
									else if (*sampleKeyTime > addSampleTime)
									{
										sampleKeys.insert(sampleKeyTime, addSampleTime);
										break;
									}
								}
							}
						}
					}
				}
			}
		}
		size_t sampleKeyCount = sampleKeys.size();
		if (sampleKeyCount == 0) return;

		// Pre-allocate the value array;
		sampleValues.reserve(sampleKeyCount);
		
		// Sample the scene node transform
		for (size_t i = 0; i < sampleKeyCount; ++i)
		{
			float sampleTime = sampleKeys[i];
			for (FCDAnimatedList::iterator it = animateds.begin(); it != animateds.end(); ++it)
			{
				// Sample each animated, which changes the transform values directly
				(*it)->Evaluate(sampleTime);
			}

			// Retrieve the new transform matrix for the COLLADA scene node
			sampleValues.push_back(node->ToMatrix());
		}
	}
	//---------------------------------------------------------------
	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();

	}