Esempio n. 1
0
void Tools::DisplayAnimation::DisplayChannels( FbxNode* i_node, FbxAnimLayer* i_animLayer, void (*DisplayCurve) (FbxAnimCurve* i_curve), void (*DisplayListCurve) (FbxAnimCurve* i_curve, FbxProperty* i_property), bool isSwitcher )
{
	FbxAnimCurve *animCurve = NULL;

	// Display general curves.
	if (!isSwitcher)
	{
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        TX\n" );
			DisplayCommon::DisplayString( "        TX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        TY\n" );
			DisplayCommon::DisplayString( "        TY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        TZ\n" );
			DisplayCommon::DisplayString( "        TZ" );
			DisplayCurve( animCurve );
		}

		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        RX\n" );
			DisplayCommon::DisplayString( "        RX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        RY\n" );
			DisplayCommon::DisplayString( "        RY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        RZ\n" );
			DisplayCommon::DisplayString( "        RZ" );
			DisplayCurve( animCurve );
		}

		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        SX\n" );
			DisplayCommon::DisplayString( "        SX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        SY\n" );
			DisplayCommon::DisplayString( "        SY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        SZ\n" );
			DisplayCommon::DisplayString( "        SZ" );
			DisplayCurve( animCurve );
		}
	}

	// Display curves specific to a light or marker.
	FbxNodeAttribute *nodeAttribute = i_node->GetNodeAttribute();

	if( nodeAttribute )
	{
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_RED );
		if( animCurve )
		{
			FBXSDK_printf( "        Red\n" );
			DisplayCommon::DisplayString( "        Red" );
			DisplayCurve( animCurve );
		}
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_GREEN );
		if( animCurve )
		{
			FBXSDK_printf( "        Green\n" );
			DisplayCommon::DisplayString( "        Green" );
			DisplayCurve( animCurve );
		}
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_BLUE );
		if( animCurve )
		{
			FBXSDK_printf( "        Blue\n" );
			DisplayCommon::DisplayString( "        Blue" );
			DisplayCurve( animCurve );
		}

		// Display curves specific to a light.
		FbxLight *light = i_node->GetLight();
		if( light )
		{
			animCurve = light->Intensity.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Intensity\n" );
				DisplayCommon::DisplayString( "        Intensity" );
				DisplayCurve( animCurve );
			}

			animCurve = light->OuterAngle.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Outer Angle\n" );
				DisplayCommon::DisplayString( "        Outer Angle" );
				DisplayCurve( animCurve );
			}

			animCurve = light->Fog.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Fog\n" );
				DisplayCommon::DisplayString( "        Fog" );
				DisplayCurve( animCurve );
			}
		}

		// Display curves specific to a camera.
		FbxCamera *camera = i_node->GetCamera();
		if( camera )
		{
			animCurve = camera->FieldOfView.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View\n" );
				DisplayCommon::DisplayString( "        Field of View" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->FieldOfViewX.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View X\n" );
				DisplayCommon::DisplayString( "        Field of View X" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->FieldOfViewY.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View Y\n" );
				DisplayCommon::DisplayString( "        Field of View Y" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->OpticalCenterX.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Optical Center X\n" );
				DisplayCommon::DisplayString( "        Optical Center X" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->OpticalCenterY.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Optical Center Y\n" );
				DisplayCommon::DisplayString( "        Optical Center Y" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->Roll.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Roll\n" );
				DisplayCommon::DisplayString( "        Roll" );
				DisplayCurve( animCurve );
			}
		}

		// Display curves specific to a geometry.
		if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh ||
			nodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbs ||
			nodeAttribute->GetAttributeType() == FbxNodeAttribute::ePatch)
		{
			FbxGeometry *geometry = (FbxGeometry*) nodeAttribute;

			int blendShapeDeformerCount = geometry->GetDeformerCount( FbxDeformer::eBlendShape );
			for( int blendShapeIndex = 0; blendShapeIndex<blendShapeDeformerCount; blendShapeIndex++ )
			{
				FbxBlendShape *blendShape = (FbxBlendShape*)geometry->GetDeformer( blendShapeIndex, FbxDeformer::eBlendShape );

				int blendShapeChannelCount = blendShape->GetBlendShapeChannelCount();
				for( int channelIndex = 0; channelIndex<blendShapeChannelCount; channelIndex++ )
				{
					FbxBlendShapeChannel *channel = blendShape->GetBlendShapeChannel( channelIndex );
					const char *channelName = channel->GetName();

					animCurve = geometry->GetShapeChannel( blendShapeIndex, channelIndex, i_animLayer, true );
					if( animCurve )
					{
						FBXSDK_printf( "        Shape %s\n", channelName );
						DisplayCommon::DisplayString( "        Shape ", channelName );
						DisplayCurve( animCurve );
					}
				}
			}
		}
	}

	// Display curves specific to properties
	FbxProperty lProperty = i_node->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		if( lProperty.GetFlag(FbxPropertyAttr::eUserDefined) )
		{
			FbxString lFbxFCurveNodeName  = lProperty.GetName();
			FbxAnimCurveNode* curveNode = lProperty.GetCurveNode( i_animLayer );

			if( !curveNode )
			{
				lProperty = i_node->GetNextProperty( lProperty );
				continue;
			}

			FbxDataType dataType = lProperty.GetPropertyDataType();
			if( dataType.GetType() == eFbxBool || dataType.GetType() == eFbxDouble || dataType.GetType() == eFbxFloat || dataType.GetType() == eFbxInt )
			{
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				};

				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
						DisplayCurve( animCurve );
				}
			}
			else if( dataType.GetType() == eFbxDouble3 || dataType.GetType() == eFbxDouble4 || dataType.Is(FbxColor3DT) || dataType.Is(FbxColor4DT) )
			{
				char* componentName1 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_RED : (char*)"X";
				char* componentName2 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_GREEN : (char*)"Y";
				char* componentName3 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_BLUE  : (char*)"Z";
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				}
				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName1 );
						DisplayCurve( animCurve );
					}
				}

				for( int c = 0; c < curveNode->GetCurveCount(1U); c++ )
				{
					animCurve = curveNode->GetCurve(1U, c);
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName2 );
						DisplayCurve( animCurve );
					}
				}

				for( int c = 0; c < curveNode->GetCurveCount(2U); c++ )
				{
					animCurve = curveNode->GetCurve( 2U, c );
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName3 );
						DisplayCurve( animCurve );
					}
				}
			}
			else if( dataType.GetType() == eFbxEnum )
			{
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				};
				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
						DisplayListCurve( animCurve, &lProperty );
				}
			}
		}

		lProperty = i_node->GetNextProperty( lProperty );
	} // while
}
Esempio n. 2
0
void FbxToHkxConverter::extractKeyFramesAndAnnotations(hkxScene *scene, FbxNode* fbxChildNode, hkxNode* newChildNode, int animStackIndex)
{
	FbxAMatrix bindPoseMatrix;
	FbxAnimStack* lAnimStack = NULL;
	int numAnimLayers = 0;
	FbxTimeSpan animTimeSpan;
	
	if (animStackIndex >= 0)
	{
		lAnimStack = m_curFbxScene->GetSrcObject<FbxAnimStack>(animStackIndex);
		numAnimLayers = lAnimStack->GetMemberCount<FbxAnimLayer>();
		animTimeSpan = lAnimStack->GetLocalTimeSpan();
	}

	// Find the time offset (in the "time space" of the FBX file) of the first animation frame
	FbxTime timePerFrame; timePerFrame.SetTime(0, 0, 0, 1, 0, m_curFbxScene->GetGlobalSettings().GetTimeMode());
	const FbxTime startTime = animTimeSpan.GetStart();
	const FbxTime endTime = animTimeSpan.GetStop();

	const hkReal startTimeSeconds = static_cast<hkReal>(startTime.GetSecondDouble());
	const hkReal endTimeSeconds = static_cast<hkReal>(endTime.GetSecondDouble());

	int numFrames = 0;
	bool staticNode = true;

	if (scene->m_sceneLength == 0)
	{
		bindPoseMatrix = fbxChildNode->EvaluateLocalTransform(startTime);
	}
	else
	{
		hkArray<hkStringOld> annotationStrings;
		hkArray<hkReal> annotationTimes;

		HK_ASSERT(0x0, newChildNode->m_keyFrames.getSize() == 0);

		// Sample each animation frame
		for (FbxTime time = startTime, priorSampleTime = endTime;
			 time < endTime;
			 priorSampleTime = time, time += timePerFrame, ++numFrames)
		{
			FbxAMatrix frameMatrix = fbxChildNode->EvaluateLocalTransform(time);
			staticNode = staticNode && (frameMatrix == bindPoseMatrix);

			hkMatrix4 mat;

			// Extract this frame's transform
			convertFbxXMatrixToMatrix4(frameMatrix, mat);
			newChildNode->m_keyFrames.pushBack(mat);

			// Extract all annotation strings for this frame using the deprecated
			// pipeline (new annotations are extracted when sampling attributes)
			if (m_options.m_exportAnnotations && numAnimLayers > 0)
			{
				FbxProperty prop = fbxChildNode->GetFirstProperty();
				while(prop.IsValid())
				{
					FbxString propName  = prop.GetName();
					FbxDataType lDataType = prop.GetPropertyDataType();
					hkStringOld name(propName.Buffer(), (int) propName.GetLen());
					if (name.asUpperCase().beginsWith("HK") && lDataType.GetType() == eFbxEnum)
					{
						FbxAnimLayer* lAnimLayer = lAnimStack->GetMember<FbxAnimLayer>(0);
						FbxAnimCurve* lAnimCurve = prop.GetCurve(lAnimLayer);

						int currentKeyIndex;
						const int keyIndex = (int) lAnimCurve->KeyFind(time, &currentKeyIndex);
						const int priorKeyIndex = (int) lAnimCurve->KeyFind(priorSampleTime);

						// Only store annotations on frames where they're explicitly keyframed, or if this is the first keyframe 
						if (priorKeyIndex != keyIndex)
						{
							const int currentEnumValueIndex = keyIndex < 0 ? (int) lAnimCurve->Evaluate(priorSampleTime) : (int) lAnimCurve->Evaluate(time);
							HK_ASSERT(0x0, currentEnumValueIndex < prop.GetEnumCount());
							const char* enumValue = prop.GetEnumValue(currentEnumValueIndex);
							hkxNode::AnnotationData& annotation = newChildNode->m_annotations.expandOne();
							annotation.m_time = (hkReal) (time - startTime).GetSecondDouble();
							annotation.m_description = (name + hkStringOld(enumValue, hkString::strLen(enumValue))).cString();
						}
					}
					prop = fbxChildNode->GetNextProperty(prop);
				}
			}
		}
	}

	// Replace animation key data for static nodes with just 1 or 2 frames of bind pose data
	if (staticNode)
	{
		// Static nodes in animated scene data are exported with two keys
		const bool exportTwoFramesForStaticNodes = (numFrames > 1);

		// replace transform
		newChildNode->m_keyFrames.setSize(exportTwoFramesForStaticNodes ? 2: 1);
		newChildNode->m_keyFrames.optimizeCapacity(0, true);

		// convert the bind pose transform to Havok format
		convertFbxXMatrixToMatrix4(bindPoseMatrix, newChildNode->m_keyFrames[0]);

		if (exportTwoFramesForStaticNodes)
		{
			newChildNode->m_keyFrames[1] = newChildNode->m_keyFrames[0];
		}
	}

	// Extract all times of actual keyframes for the current node... this can be used by Vision
	if ( m_options.m_storeKeyframeSamplePoints &&
		 newChildNode->m_keyFrames.getSize() > 2 &&
		 numAnimLayers > 0 )
	{
		FbxAnimLayer* lAnimLayer = lAnimStack->GetMember<FbxAnimLayer>(0);

		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_TRANSLATION, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_ROTATION, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_SCALING, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, newChildNode, startTimeSeconds, endTimeSeconds);

		if (newChildNode->m_linearKeyFrameHints.getSize() > 1)
		{
			hkSort(newChildNode->m_linearKeyFrameHints.begin(), newChildNode->m_linearKeyFrameHints.getSize());
		}
	}
}