private void ParseNode(FBXNode n, bool traverse) { CreateCMPData(n); if (!traverse) { return; } for (int i = 0; i < n.GetChildCount(); i++) { var child = n.GetChild(i); ParseNode(child, false); } }
/// <summary> /// /// </summary> /// <param name="nodeInstance">The node that we are recursing into.</param> /// <param name="depth">The depth of the hierarchy we are displaying</param> private static void DisplayHierarchyRecursive(FBXNode nodeInstance, int depth) { string output = string.Empty; for (int index = 0; index < depth; index++) { output += " "; } // Write the information out Logger.LogMessage("{0}{1}", output, nodeInstance.GetName()); for (int index = 0; index < nodeInstance.GetChildCount(); index++) { DisplayHierarchyRecursive(nodeInstance.GetChild(index), depth + 1); } }
/// <summary> /// The display content method /// </summary> /// <param name="sceneInstance">The scene that we are running on.</param> private static void DisplayContent(FBXScene sceneInstance) { FBXNode rootNode = sceneInstance.GetRootNode(); if (rootNode != null) { // Iterate over the children in this node. for (int index = 0; index < rootNode.GetChildCount(); index++) { var attributeType = rootNode.GetChild(index).GetNodeAttribute().GetAttributeType(); FBXNode nodeInstance = rootNode.GetChild(index); FBXNodeAttribute attributeInstance = nodeInstance.GetNodeAttribute(); // Cast out the node object based on the type of the attribute. switch (attributeType) { case EAttributeType.eMesh: DisplayMesh((FBXMesh)attributeInstance); break; case EAttributeType.eCamera: DisplayCamera((FBXCamera)attributeInstance); break; case EAttributeType.eLight: DisplayLight((FBXLight)attributeInstance); break; case EAttributeType.eSkeleton: DisplaySkeleton((FBXSkeleton)attributeInstance); break; } } } }
private void CreateCMPData(FBXNode n) { Vector3 vOffset = Vector3.Zero; CmpndData cmpnd = new CmpndData(); cmpnd.index = 0; cmpnd.object_name = n.GetName(); if (cmpnd.object_name == "Root") { cmpnd.name = "Root"; } else { cmpnd.name = "Part_" + cmpnd.object_name; if (Relocate) { vOffset = T(n.EvaluateLocalTranslation(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false)); } } cmpnd.object_data = new ThreeDBData(); cmpnd.object_data.data = new LodData[8]; cmpnd.object_data.wireframe_lod = 0; int lods = 0; for (int i = 0; i < n.GetChildCount(); i++) { var cur_lodnode = n.GetChild(i); var match = Regex.Match(cur_lodnode.GetName(), @"^.+_lod(?<lod>[0-9])(?<wireframe>_vwd)?"); if (match.Success) { uint lod = uint.Parse(match.Groups["lod"].Value); if (match.Groups["wireframe"].Success) { cmpnd.object_data.wireframe_lod = lod; } cmpnd.object_data.data[lod].meshes = new List <SMesh>(); lods++; int numVerts = 0; int numFaces = 0; Vector3 bbmin = new Vector3(float.MaxValue); Vector3 bbmax = new Vector3(float.MinValue); for (int j = 0; j < cur_lodnode.GetChildCount(); j++) { var cur_node = cur_lodnode.GetChild(j); var attr = cur_node.GetNodeAttribute(); if (attr == null) { continue; } if (attr.GetAttributeType() != ArcManagedFBX.Types.EAttributeType.eMesh) { continue; } var pmesh = attr as FBXMesh; var cur_node_trans = T(cur_node.EvaluateGlobalTransform(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false)); var cur_node_geo = T(cur_node.GetGeometricMatrix(ArcManagedFBX.Types.EPivotSet.eSourcePivot)); cur_node_trans = cur_node_geo * cur_node_trans; SMesh mesh = new SMesh(); int nTris = pmesh.GetPolygonCount(); if (nTris <= 0) { continue; } if (cur_node.GetMaterialCount() <= 0) { mesh.material_name = "default"; } else { var material = cur_node.GetMaterial(0); mesh.material_name = material.GetName(); } mesh.name = cur_node.GetName(); mesh.t = new VMSTri[nTris]; int nVerts = nTris * 3; mesh.v = new VMSVert[nVerts]; var vertices = pmesh.GetControlPoints(); int tangentLayerCount = pmesh.GetElementTangentCount(); var tangentLayer = tangentLayerCount > 0 ? pmesh.GetElementTangent().GetDirectArray() : null; int binormalLayerCount = pmesh.GetElementBinormalCount(); var binormalLayer = binormalLayerCount > 0 ? pmesh.GetElementBinormal().GetDirectArray() : null; for (int nTri = 0; nTri < nTris; nTri++) { mesh.t[nTri].vertices = new ushort[3]; for (int k = 0; k < 3; k++) { int nVert = (nTri * 3 + k); Vector3 vertice, normal; Vector2 uv; bool unmapped = false; FBXVector fbxuv = new FBXVector(); FBXVector fbxnormal = new FBXVector(); vertice = Vector3.TransformCoordinate(T(vertices[pmesh.GetPolygonVertex(nTri, k)]), cur_node_trans); // offset vertice vertice -= vOffset; pmesh.GetPolygonVertexUV(nTri, k, "map1", ref fbxuv, ref unmapped); uv = T2(fbxuv); pmesh.GetPolygonVertexNormal(nTri, k, ref fbxnormal); normal = Vector3.TransformNormal(T(fbxnormal), cur_node_trans); mesh.t[nTri].vertices[k] = (ushort)nVert; mesh.v[nVert].vert = vertice; mesh.v[nVert].normal = normal; mesh.v[nVert].uv = uv; mesh.v[nVert].tangent = tangentLayer != null?T(tangentLayer.GetAt(nVert)) : Vector3.Zero; mesh.v[nVert].binormal = binormalLayer != null?T(binormalLayer.GetAt(nVert)) : Vector3.Zero; /* * * float alpha = 1.0f; * int iVCindex = mesh->pMesh->GetFaceVertex(pTriangle->meshFaceIndex, i); * if (iVCindex != -1) * { * alpha = mesh->pMesh->GetAlphaVertex(pTriangle->alpha[i]); * color = mesh->pMesh->GetColorVertex(pTriangle->color[i]); * mesh->v[nVert].diffuse = (DWORD)(alpha * 255) << 24 | (DWORD)(color.x * 255) << 16 | (DWORD)(color.y * 255) << 8 | (DWORD)(color.z * 255); * mesh->v[nVert].uv = uv; * } * else * { * mesh->v[nVert].tangent = Point3(0, 0, 0); * mesh->v[nVert].binormal = Point3(0, 0, 0); * }*/ bbmin = Vector3.Min(bbmin, vertice); bbmax = Vector3.Max(bbmin, vertice); } } mesh.nVerts = nVerts; numVerts += mesh.nVerts; mesh.nTris = nTris; numFaces += mesh.nTris; cmpnd.object_data.data[lod].meshes.Add(mesh); } cmpnd.object_data.data[lod].vmeshref = new VMeshRef(); cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxX = bbmax.X; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxY = bbmax.Y; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxZ = bbmax.Z; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinX = bbmin.X; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinY = bbmin.Y; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinZ = bbmin.Z; var vCenter = (bbmax + bbmin) / 2; cmpnd.object_data.data[lod].vmeshref.CenterX = vCenter.X; cmpnd.object_data.data[lod].vmeshref.CenterY = vCenter.Y; cmpnd.object_data.data[lod].vmeshref.CenterZ = vCenter.Z; cmpnd.object_data.data[lod].vmeshref.Radius = (bbmax - vCenter).Length() * 1.25f; cmpnd.object_data.data[lod].vmeshref.HeaderSize = 60; cmpnd.object_data.data[lod].vmeshref.NumMeshes = (ushort)cmpnd.object_data.data[lod].meshes.Count; cmpnd.object_data.data[lod].vmeshref.NumVert = (ushort)numVerts; cmpnd.object_data.data[lod].vmeshref.NumIndex = (ushort)(numFaces * 3); if (numFaces * 3 > 0xFFFF) { throw new ArgumentException($"{cmpnd.object_name} references more than 65535 vertices. Split the group into smaller groups!"); } } } cmpnd.object_data.lods = (uint)lods; cmpnd.index = cmpndData.Count; cmpndData.Add(cmpnd); if (cmpnd.object_name != "Root") { if (cmpnd.object_name.EndsWith("_rev")) { CmpRevData.Part revdata = new CmpRevData.Part(); revdata.ParentName = "Root"; revdata.ChildName = cmpnd.object_name; revdata.OriginX = vOffset.X; revdata.OriginY = vOffset.Y; revdata.OriginZ = vOffset.Z; var mat = n.EvaluateLocalTransform(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false); revdata.RotMatXX = (float)mat.mData[0].x; revdata.RotMatXY = (float)mat.mData[1].x; revdata.RotMatXZ = (float)mat.mData[2].x; revdata.RotMatYX = (float)mat.mData[0].y; revdata.RotMatYY = (float)mat.mData[1].y; revdata.RotMatYZ = (float)mat.mData[2].y; revdata.RotMatZX = (float)mat.mData[0].z; revdata.RotMatZY = (float)mat.mData[1].z; revdata.RotMatZZ = (float)mat.mData[2].z; revdata.AxisRotX = (float)mat.mData[0].x; revdata.AxisRotY = (float)mat.mData[1].x; revdata.AxisRotZ = (float)mat.mData[2].x; revdata.Max = 1; rev.Parts.Add(revdata); } else if (cmpnd.object_name.EndsWith("_pris")) { CmpRevData.Part revdata = new CmpRevData.Part(); revdata.ParentName = "Root"; revdata.ChildName = cmpnd.object_name; revdata.OriginX = vOffset.X; revdata.OriginY = vOffset.Y; revdata.OriginZ = vOffset.Z; revdata.RotMatXX = revdata.RotMatYY = revdata.RotMatZZ = 1; revdata.AxisRotZ = 1; revdata.Max = 360; pris.Parts.Add(revdata); } else { CmpFixData.Part fixdata = new CmpFixData.Part(); fixdata.ParentName = "Root"; fixdata.ChildName = cmpnd.object_name; fixdata.OriginX = vOffset.X; fixdata.OriginY = vOffset.Y; fixdata.OriginZ = vOffset.Z; fixdata.RotMatXX = fixdata.RotMatYY = fixdata.RotMatZZ = 1; fix.Parts.Add(fixdata); } } }
void FbxsdkFindAllAnimatedNodes(FBXScene scene, FBXNode node, List<FBXNode> outputCollection) { if(scene.HasCurve(node)) outputCollection.Add(node); for(int i=0;i<node.GetChildCount();++i) { FbxsdkFindAllAnimatedNodes(scene, node.GetChild(i), outputCollection); } }
void FbxsdkBuildHierachy(FBXNode fbxNode, SkeletonNode parentNode, Dictionary<SkeletonNode, FBXMesh> outputMeshDict) { var node = new SkeletonNode(); node.Name = fbxNode.GetName(); node.PoseMatrix = FbxsdkConvertMatrix(fbxNode.GetLocalTransform()); node.Parent = parentNode; if (parentNode == null) skeleton = node; else parentNode.Children.Add(node); var mesh = fbxNode.GetMesh() ; if(mesh != null) { outputMeshDict[node] = mesh; } if (skeletonNodeDict.ContainsKey(node.Name)) { Debug.Log("Found duplicated skeleton node name: " + node.Name); } else { skeletonNodeDict.Add(node.Name, node); } for (int i = 0; i < fbxNode.GetChildCount(); ++i) { FbxsdkBuildHierachy(fbxNode.GetChild(i), node, outputMeshDict); } }