Beispiel #1
0
// Deform the vertex array with the shapes contained in the mesh.
void compute_shape_deformation(FbxMesh* pMesh, FbxTime& pTime, FbxAnimLayer * pAnimLayer, FbxVector4* pVertexArray)
{
  int lVertexCount = pMesh->GetControlPointsCount();

  FbxVector4* lSrcVertexArray = pVertexArray;
  FbxVector4* lDstVertexArray = new FbxVector4[lVertexCount];
  memcpy(lDstVertexArray, pVertexArray, lVertexCount * sizeof(FbxVector4));

  int lBlendShapeDeformerCount = pMesh->GetDeformerCount(FbxDeformer::eBlendShape);

  for(int lBlendShapeIndex = 0; lBlendShapeIndex<lBlendShapeDeformerCount; ++lBlendShapeIndex) {
    FbxBlendShape* lBlendShape = (FbxBlendShape*)pMesh->GetDeformer(lBlendShapeIndex, FbxDeformer::eBlendShape);

    int lBlendShapeChannelCount = lBlendShape->GetBlendShapeChannelCount();

    for(int lChannelIndex = 0; lChannelIndex<lBlendShapeChannelCount; ++lChannelIndex) {
      FbxBlendShapeChannel* lChannel = lBlendShape->GetBlendShapeChannel(lChannelIndex);

      if(lChannel) {
        // Get the percentage of influence of the shape.
        FbxAnimCurve* lFCurve = pMesh->GetShapeChannel(lBlendShapeIndex, lChannelIndex, pAnimLayer);

        if(!lFCurve) {
          continue;
        }

        double lWeight = lFCurve->Evaluate(pTime);

        //Find which shape should we use according to the weight.
        int lShapeCount = lChannel->GetTargetShapeCount();
        double* lFullWeights = lChannel->GetTargetShapeFullWeights();

        for(int lShapeIndex = 0; lShapeIndex<lShapeCount; ++lShapeIndex) {
          FbxShape* lShape = NULL;

          if(lWeight > 0 && lWeight <= lFullWeights[0]) {
            lShape = lChannel->GetTargetShape(0);
          }

          if(lWeight > lFullWeights[lShapeIndex] && lWeight < lFullWeights[lShapeIndex+1]) {
            lShape = lChannel->GetTargetShape(lShapeIndex+1);
          }

          if(lShape) {
            for(int j = 0; j < lVertexCount; j++) {
              // Add the influence of the shape vertex to the mesh vertex.
              FbxVector4 lInfluence = (lShape->GetControlPoints()[j] - lSrcVertexArray[j]) * lWeight * 0.01;
              lDstVertexArray[j] += lInfluence;
            }
          }
        }//For each target shape
      }//If lChannel is valid
    }//For each blend shape channel
  }//For each blend shape deformer

  memcpy(pVertexArray, lDstVertexArray, lVertexCount * sizeof(FbxVector4));

  delete [] lDstVertexArray;
}
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());
		}
	}
}
// Get the animated parameters of a camera contained in the scene
// and store them in the associated member variables contained in 
// the camera.
void GetCameraAnimatedParameters(FbxNode* pNode, FbxTime& pTime, FbxAnimLayer* pAnimLayer)
{
    FbxCamera* lCamera = (FbxCamera*) pNode->GetNodeAttribute();
    lCamera->Position.Set(GetGlobalPosition(pNode, pTime).GetT());

    FbxAnimCurve* fc = lCamera->Roll.GetCurve(pAnimLayer);
    if (fc)
        lCamera->Roll.Set(fc->Evaluate(pTime));

    FbxCamera::EApertureMode lCameraApertureMode = lCamera->GetApertureMode();
    if (lCameraApertureMode == FbxCamera::eHorizontal || 
        lCameraApertureMode == FbxCamera::eVertical) 
    {
        double lFieldOfView = lCamera->FieldOfView.Get();
        fc = lCamera->FieldOfView.GetCurve(pAnimLayer);
        if (fc)
            lFieldOfView = fc->Evaluate(pTime);

        //update FOV and focal length
        lCamera->FieldOfView.Set( lFieldOfView);
        lCamera->FocalLength.Set( lCamera->ComputeFocalLength( lFieldOfView));
        
    }
    else if ( lCameraApertureMode == FbxCamera::eHorizAndVert)
    {
        double lOldFieldOfViewX = lCamera->FieldOfViewX.Get();
        double lOldFieldOfViewY = lCamera->FieldOfViewY.Get();

        //update FOV
        double lNewFieldOfViewX = lOldFieldOfViewX;
        double lNewFieldOfViewY = lOldFieldOfViewY;
        fc = lCamera->FieldOfViewX.GetCurve(pAnimLayer);
        if (fc)
            lNewFieldOfViewX = fc->Evaluate(pTime);

        fc = lCamera->FieldOfViewY.GetCurve(pAnimLayer);
        if (fc)
            lNewFieldOfViewY = fc->Evaluate(pTime);

        lCamera->FieldOfViewX.Set(lNewFieldOfViewX);
        lCamera->FieldOfViewY.Set(lNewFieldOfViewY);

        //update aspect
        double lUpdatedApertureX = lCamera->GetApertureWidth();
        double lUpdatedApertureY = lCamera->GetApertureHeight();
        lUpdatedApertureX *= tan( lNewFieldOfViewX * 0.5 * FBXSDK_PI_DIV_180) / tan( lOldFieldOfViewX * 0.5 * FBXSDK_PI_DIV_180);
        lUpdatedApertureY *= tan( lNewFieldOfViewY * 0.5 * FBXSDK_PI_DIV_180) / tan( lOldFieldOfViewY * 0.5 * FBXSDK_PI_DIV_180);
        
        lCamera->FilmWidth.Set( lUpdatedApertureX);
        lCamera->FilmHeight.Set( lUpdatedApertureY);
        lCamera->FilmAspectRatio.Set( lUpdatedApertureX / lUpdatedApertureY);


    }
    else if ( lCameraApertureMode == FbxCamera::eFocalLength)
    {
        double lFocalLength = lCamera->FocalLength.Get();
        fc = lCamera->FocalLength.GetCurve(pAnimLayer);
        if (fc && fc ->Evaluate(pTime))
            lFocalLength = fc->Evaluate( pTime);
            

        //update FOV and focal length
        lCamera->FocalLength.Set( lFocalLength);
        lCamera->FieldOfView.Set( lCamera->ComputeFieldOfView( lFocalLength));
    }
}
Beispiel #4
0
//--------------------------------------------------------------
void ofxFBXMesh::computeBlendShapes( ofMesh* aMesh, FbxTime& pTime, FbxAnimLayer * pAnimLayer ) {
    int lBlendShapeDeformerCount = fbxMesh->GetDeformerCount(FbxDeformer::eBlendShape);
//    cout << "Computing blendshapes for " << getName() << endl;
    for(int lBlendShapeIndex = 0; lBlendShapeIndex<lBlendShapeDeformerCount; ++lBlendShapeIndex) {
        FbxBlendShape* lBlendShape = (FbxBlendShape*)fbxMesh->GetDeformer(lBlendShapeIndex, FbxDeformer::eBlendShape);
        
        int lBlendShapeChannelCount = lBlendShape->GetBlendShapeChannelCount();
		for(int lChannelIndex = 0; lChannelIndex<lBlendShapeChannelCount; ++lChannelIndex) {
			FbxBlendShapeChannel* lChannel = lBlendShape->GetBlendShapeChannel(lChannelIndex);
			if(lChannel) {
				// Get the percentage of influence on this channel.
				FbxAnimCurve* lFCurve = fbxMesh->GetShapeChannel(lBlendShapeIndex, lChannelIndex, pAnimLayer);
				if (!lFCurve) continue;
                
				double lWeight          = lFCurve->Evaluate(pTime);
//                cout << "updateMesh lWeight = " << lWeight << " time = " << pTime.GetMilliSeconds() << endl;
                
                int lShapeCount         = lChannel->GetTargetShapeCount();
				double* lFullWeights    = lChannel->GetTargetShapeFullWeights();
                
                // Find out which scope the lWeight falls in.
				int lStartIndex = -1;
				int lEndIndex = -1;
				for(int lShapeIndex = 0; lShapeIndex<lShapeCount; ++lShapeIndex) {
					if(lWeight > 0 && lWeight <= lFullWeights[0]) {
						lEndIndex = 0;
						break;
					}
					if(lWeight > lFullWeights[lShapeIndex] && lWeight < lFullWeights[lShapeIndex+1]) {
						lStartIndex = lShapeIndex;
						lEndIndex = lShapeIndex + 1;
						break;
					}
				}
                
                FbxShape* lStartShape = NULL;
				FbxShape* lEndShape = NULL;
				if(lStartIndex > -1) {
					lStartShape = lChannel->GetTargetShape(lStartIndex);
				}
				if(lEndIndex > -1) {
					lEndShape = lChannel->GetTargetShape(lEndIndex);
				}
                
                //The weight percentage falls between base geometry and the first target shape.
				if(lStartIndex == -1 && lEndShape) {
                    float lEndWeight    = lFullWeights[0];
                    lWeight = (lWeight/lEndWeight);
                    
                    cout << "updateMesh : weight = " << lWeight << endl;
                    for (int j = 0; j < aMesh->getNumVertices(); j++) {
                        // Add the influence of the shape vertex to the mesh vertex.
                        ofVec3f influence = (toOf(lEndShape->GetControlPoints()[j]) - original.getVertices()[j]) * lWeight;
                        aMesh->getVertices()[j] += influence;
                    }
                    
                } else if(lStartShape && lEndShape) {
                    float lStartWeight  = lFullWeights[lStartIndex];
					float lEndWeight    = lFullWeights[lEndIndex];
                    // Calculate the real weight.
                    lWeight = ofMap(lWeight, lStartWeight, lEndWeight, 0, 1, true);
                    cout << "updateMesh : weight = " << lWeight << " lStartWeight " << lStartWeight << " lEndWeight " << lEndWeight << endl;
                    //					lWeight = ((lWeight-lStartWeight)/(lEndWeight-lStartWeight)) * 100;
                    for (int j = 0; j < aMesh->getNumVertices(); j++) {
                        // Add the influence of the shape vertex to the mesh vertex.
                        ofVec3f influence = (toOf(lEndShape->GetControlPoints()[j] - lStartShape->GetControlPoints()[j] )) * lWeight;
                        aMesh->getVertices()[j] += influence;
                    }
                }
                
            }
        }
    }
}
// Find the current camera at the given time.
FbxCamera* GetCurrentCamera(FbxScene* pScene, 
                             FbxTime& pTime, 
                             FbxAnimLayer* pAnimLayer,
                             const FbxArray<FbxNode*>& pCameraArray)
{
    FbxGlobalSettings& lGlobalSettings = pScene->GetGlobalSettings();
    FbxGlobalCameraSettings& lGlobalCameraSettings = pScene->GlobalCameraSettings();
    FbxString lCurrentCameraName = lGlobalSettings.GetDefaultCamera();

	

    // check if we need to create the Producer cameras!
    if (lGlobalCameraSettings.GetCameraProducerPerspective() == NULL &&
        lGlobalCameraSettings.GetCameraProducerBottom() == NULL &&
        lGlobalCameraSettings.GetCameraProducerTop() == NULL &&
        lGlobalCameraSettings.GetCameraProducerFront() == NULL &&
        lGlobalCameraSettings.GetCameraProducerBack() == NULL &&
        lGlobalCameraSettings.GetCameraProducerRight() == NULL &&
        lGlobalCameraSettings.GetCameraProducerLeft() == NULL)
    {
        lGlobalCameraSettings.CreateProducerCameras();
    }

    if (lCurrentCameraName.Compare(FBXSDK_CAMERA_PERSPECTIVE) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerPerspective();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_BOTTOM) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerBottom();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_TOP) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerTop();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_FRONT) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerFront();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_BACK) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerBack();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_RIGHT) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerRight();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_LEFT) == 0)
    {
        return lGlobalCameraSettings.GetCameraProducerLeft();
    }
    else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_SWITCHER) == 0)
    {
        FbxCameraSwitcher* lCameraSwitcher = pScene->GlobalCameraSettings().GetCameraSwitcher();
		FbxAnimCurve* lCurve = NULL;
		if (lCameraSwitcher)
		{
			lCurve = lCameraSwitcher->CameraIndex.GetCurve(pAnimLayer);
			int lCameraIndex = lCurve ? int(lCurve->Evaluate(pTime)) - 1 : 0;
			if (lCameraIndex >= 0 && lCameraIndex < pCameraArray.GetCount())
			{
				FbxNode* lNode = pCameraArray[lCameraIndex];

				// Get the animated parameters of the camera.
				GetCameraAnimatedParameters(lNode, pTime, pAnimLayer);

				return (FbxCamera*) lNode->GetNodeAttribute();
			}
		}
    }
    else
    {
        int i;
        FbxNode* lNode = NULL;

        // Find the camera in the camera array.
        for (i = 0; i < pCameraArray.GetCount(); i++)
        {
            if (lCurrentCameraName.Compare(pCameraArray[i]->GetName()) == 0)
            {
                lNode = pCameraArray[i];
                break;
            }
        }

        if (lNode)
        {
            // Get the animated parameters of the camera.
            GetCameraAnimatedParameters(lNode, pTime, pAnimLayer);

            return (FbxCamera*) lNode->GetNodeAttribute();
        }
    }

    return lGlobalCameraSettings.GetCameraProducerPerspective();
}