Exemplo n.º 1
0
// 三角形化
void CFBXLoader::TriangulateRecursive(FbxNode* pNode)
{
	FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();

    if (lNodeAttribute)
    {
        if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh ||
            lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbs ||
            lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbsSurface ||
            lNodeAttribute->GetAttributeType() == FbxNodeAttribute::ePatch)
        {
			FbxGeometryConverter lConverter(pNode->GetFbxManager());
			// これでどんな形状も三角形化
#if 0
            lConverter.TriangulateInPlace(pNode);	// 古い手法
#endif // 0
			lConverter.Triangulate( mScene, true );
        }
    }

	const int lChildCount = pNode->GetChildCount();
    for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
    {
		// 子ノードを探索
        TriangulateRecursive(pNode->GetChild(lChildIndex));
    }
}
void FBXTriangulateRecursive( FbxNode* pNode )
{
	FbxNodeAttribute* pNodeAttr = pNode->GetNodeAttribute();

	if( pNodeAttr )
	{
		if( pNodeAttr->GetAttributeType() == FbxNodeAttribute::eMesh || 
			pNodeAttr->GetAttributeType() == FbxNodeAttribute::eNurbs ||
			pNodeAttr->GetAttributeType() == FbxNodeAttribute::eNurbsSurface ||
			pNodeAttr->GetAttributeType() == FbxNodeAttribute::ePatch )
		{
			FbxGeometryConverter lConverter( pNode->GetFbxManager() );
			lConverter.TriangulateInPlace( pNode );
		}
	}

	const int nChildCount = pNode->GetChildCount();
	for( int i = 0; i < nChildCount; i++ )
	{
		FBXTriangulateRecursive( pNode->GetChild( i ) );
	}
}
Exemplo n.º 3
0
    // Triangulate all NURBS, patch and mesh under this node recursively.
    void TriangulateRecursive(FbxNode* pNode)
    {
      FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();

      if (lNodeAttribute)
      {
        FbxNodeAttribute::EType eAttrType = lNodeAttribute->GetAttributeType();
        if (eAttrType == FbxNodeAttribute::eMesh ||
          eAttrType == FbxNodeAttribute::eNurbs ||
          eAttrType == FbxNodeAttribute::eNurbsSurface ||
          eAttrType == FbxNodeAttribute::ePatch)
        {              
          FbxGeometryConverter lConverter(pNode->GetFbxManager());
          lConverter.TriangulateInPlace(pNode);
        }
      }

      const int lChildCount = pNode->GetChildCount();
      for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
      {
        TriangulateRecursive(pNode->GetChild(lChildIndex));
      }
    }
Exemplo n.º 4
0
osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxNode(
    FbxNode* pNode,
    bool& bIsBone, int& nLightCount)
{
    if (FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute())
    {
        FbxNodeAttribute::EType attrType = lNodeAttribute->GetAttributeType();
        switch (attrType)
        {
        case FbxNodeAttribute::eNurbs:
        case FbxNodeAttribute::ePatch:
        case FbxNodeAttribute::eNurbsCurve:
        case FbxNodeAttribute::eNurbsSurface:
        {
            FbxGeometryConverter lConverter(&pSdkManager);
#if FBXSDK_VERSION_MAJOR < 2014
            if (!lConverter.TriangulateInPlace(pNode))
#else
            if (!lConverter.Triangulate(lNodeAttribute,true,false))
#endif
            {
                OSG_WARN << "Unable to triangulate FBX NURBS " << pNode->GetName() << std::endl;
            }
        }
        break;
        default:
            break;
        }
    }

    bIsBone = false;
    bool bCreateSkeleton = false;

    FbxNodeAttribute::EType lAttributeType = FbxNodeAttribute::eUnknown;
    if (pNode->GetNodeAttribute())
    {
        lAttributeType = pNode->GetNodeAttribute()->GetAttributeType();
        if (lAttributeType == FbxNodeAttribute::eSkeleton)
        {
            bIsBone = true;
        }
    }

    if (!bIsBone && fbxSkeletons.find(pNode) != fbxSkeletons.end())
    {
        bIsBone = true;
    }

    unsigned nMaterials = pNode->GetMaterialCount();
    std::vector<StateSetContent > stateSetList;

    for (unsigned i = 0; i < nMaterials; ++i)
    {
        FbxSurfaceMaterial* fbxMaterial = pNode->GetMaterial(i);
        assert(fbxMaterial);
        stateSetList.push_back(fbxMaterialToOsgStateSet.convert(fbxMaterial));
    }

    osg::NodeList skeletal, children;

    int nChildCount = pNode->GetChildCount();
    for (int i = 0; i < nChildCount; ++i)
    {
        FbxNode* pChildNode = pNode->GetChild(i);

        if (pChildNode->GetParent() != pNode)
        {
            //workaround for bug that occurs in some files exported from Blender
            continue;
        }

        bool bChildIsBone = false;
        osgDB::ReaderWriter::ReadResult childResult = readFbxNode(
                    pChildNode, bChildIsBone, nLightCount);
        if (childResult.error())
        {
            return childResult;
        }
        else if (osg::Node* osgChild = childResult.getNode())
        {
            if (bChildIsBone)
            {
                if (!bIsBone) bCreateSkeleton = true;
                skeletal.push_back(osgChild);
            }
            else
            {
                children.push_back(osgChild);
            }
        }
    }

    std::string animName = readFbxAnimation(pNode, pNode->GetName());

    osg::Matrix localMatrix;
    makeLocalMatrix(pNode, localMatrix);
    bool bLocalMatrixIdentity = localMatrix.isIdentity();

    osg::ref_ptr<osg::Group> osgGroup;

    bool bEmpty = children.empty() && !bIsBone;

    switch (lAttributeType)
    {
    case FbxNodeAttribute::eMesh:
    {
        size_t bindMatrixCount = boneBindMatrices.size();
        osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pNode, stateSetList);
        if (meshRes.error())
        {
            return meshRes;
        }
        else if (osg::Node* node = meshRes.getNode())
        {
            bEmpty = false;

            if (bindMatrixCount != boneBindMatrices.size())
            {
                //The mesh is skinned therefore the bind matrix will handle all transformations.
                localMatrix.makeIdentity();
                bLocalMatrixIdentity = true;
            }

            if (animName.empty() &&
                    children.empty() &&
                    skeletal.empty() &&
                    bLocalMatrixIdentity)
            {
                return osgDB::ReaderWriter::ReadResult(node);
            }

            children.insert(children.begin(), node);
        }
    }
    break;
    case FbxNodeAttribute::eCamera:
    case FbxNodeAttribute::eLight:
    {
        osgDB::ReaderWriter::ReadResult res =
            lAttributeType == FbxNodeAttribute::eCamera ?
            readFbxCamera(pNode) : readFbxLight(pNode, nLightCount);
        if (res.error())
        {
            return res;
        }
        else if (osg::Group* resGroup = dynamic_cast<osg::Group*>(res.getObject()))
        {
            bEmpty = false;
            if (animName.empty() &&
                    bLocalMatrixIdentity)
            {
                osgGroup = resGroup;
            }
            else
            {
                children.insert(children.begin(), resGroup);
            }
        }
    }
    break;
    default:
        break;
    }

    if (bEmpty)
    {
        osgDB::ReaderWriter::ReadResult(0);
    }

    if (!osgGroup) osgGroup = createGroupNode(pSdkManager, pNode, animName, localMatrix, bIsBone, nodeMap, fbxScene);

    osg::Group* pAddChildrenTo = osgGroup.get();
    if (bCreateSkeleton)
    {
        osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, fbxSkeletons, skeletonMap);
        osgSkeleton->setDefaultUpdateCallback();
        pAddChildrenTo->addChild(osgSkeleton);
        pAddChildrenTo = osgSkeleton;
    }

    for (osg::NodeList::iterator it = skeletal.begin(); it != skeletal.end(); ++it)
    {
        pAddChildrenTo->addChild(it->get());
    }
    for (osg::NodeList::iterator it = children.begin(); it != children.end(); ++it)
    {
        pAddChildrenTo->addChild(it->get());
    }


    return osgDB::ReaderWriter::ReadResult(osgGroup.get());
}