private FBXNode CreateFbxMesh(MeshLodSection section, FBXScene pScene) { FBXMesh fbxMesh = FBXMesh.Create(pScene, section.matName); FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal(); lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal(); lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent(); lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); fbxMesh.InitControlPoints(section.vertices.Count); FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial(); lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon); lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); FBXGeometryElementUV lUVDiffuseElement = fbxMesh.CreateElementUV(section.matName); lUVDiffuseElement.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); lUVDiffuseElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); lUVDiffuseElement.SetIndexArrayCount(section.vertices.Count); for (int j = 0; j < section.vertices.Count; j++) { FBXVector4 position = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0); FBXVector4 normal = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]); FBXVector4 textCoords = new FBXVector4(section.vertices[j].texCoords.members[0], (-section.vertices[j].texCoords.members[1] + 1), 0, 0); FBXVector4 bitangent = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]); FBXVector4 tangent = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]); fbxMesh.SetControlPoint(j, position); lGeometryElementNormal.Add(normal); lGeometryElementBiNormal.Add(bitangent); lGeometryElementTangent.Add(tangent); lUVDiffuseElement.Add(textCoords); } for (int j = 0; j < section.indicies.Count; j++) { if (j % 3 == 0) { fbxMesh.EndPolygon(); fbxMesh.BeginPolygon(); } fbxMesh.AddPolygon(section.indicies[j]); } fbxMesh.EndPolygon(); FBXNode lMeshNode = FBXNode.Create(pScene, section.matName); lMeshNode.SetNodeAttribute(fbxMesh); lMeshNode.AddMaterial(pScene, section.matName); return(lMeshNode); }
private FBXNode CreateFbxSkeleton(List <MESkeletalMesh.BoneStruct> Bones, FBXScene pScene) { FBXSkeleton lSkeletonRootAttribute = FBXSkeleton.Create(pScene, "Skeleton"); lSkeletonRootAttribute.SetSkeletonType(FBXWrapper.SkelType.eRoot); FBXNode lSkeletonRoot = FBXNode.Create(pScene, "Skeleton"); lSkeletonRoot.SetNodeAttribute(lSkeletonRootAttribute); lSkeletonRoot.LclTranslation = new FBXVector4().ToList(); FBXNode FbxSkeletonRootNode = CreateFbxBone(0, Bones, pScene, lSkeletonRoot); lSkeletonRoot.AddChild(FbxSkeletonRootNode); return(lSkeletonRoot); }
private FBXNode CreateFbxSkeleton(SkeletonAsset Skeleton, FBXScene pScene) { FBXSkeleton lSkeletonRootAttribute = FBXSkeleton.Create(pScene, "Skeleton"); lSkeletonRootAttribute.SetSkeletonType(FBXWrapper.SkelType.eRoot); FBXNode lSkeletonRoot = FBXNode.Create(pScene, "Skeleton"); lSkeletonRoot.SetNodeAttribute(lSkeletonRootAttribute); lSkeletonRoot.LclTranslation = new FBXVector4().ToList(); FBXNode FbxSkeletonRootNode = CreateFbxBone(Skeleton.RootBone, pScene, lSkeletonRoot); lSkeletonRoot.AddChild(FbxSkeletonRootNode); SetBoneTransform(Skeleton, lSkeletonRoot); return(lSkeletonRoot); }
private FBXNode CreateFbxBone(FBBone bone, FBXScene pScene, FBXNode parent) { FBXSkeleton lSkeletonLimbNodeAttribute1 = FBXSkeleton.Create(pScene, bone.Name); lSkeletonLimbNodeAttribute1.SetSkeletonType(FBXWrapper.SkelType.eLimbNode); lSkeletonLimbNodeAttribute1.SetSize(1.0); FBXNode lSkeletonLimbNode1 = FBXNode.Create(pScene, bone.Name); lSkeletonLimbNode1.SetNodeAttribute(lSkeletonLimbNodeAttribute1); for (int i = 0; i < bone.Children.Count; i++) { FBBone childBone = bone.Children[i]; FBXNode fbxChildBone = CreateFbxBone(childBone, pScene, lSkeletonLimbNode1); lSkeletonLimbNode1.AddChild(fbxChildBone); } return(lSkeletonLimbNode1); }
private FBXNode CreateFbxBone(int boneIndex, List <MESkeletalMesh.BoneStruct> Skeleton, FBXScene pScene, FBXNode parent) { MESkeletalMesh.BoneStruct bone = Skeleton[boneIndex]; string boneName = bone.BoneName; FBXSkeleton lSkeletonLimbNodeAttribute1 = FBXSkeleton.Create(pScene, boneName); lSkeletonLimbNodeAttribute1.SetSkeletonType(FBXWrapper.SkelType.eLimbNode); lSkeletonLimbNodeAttribute1.SetSize(1.0); FBXNode lSkeletonLimbNode1 = FBXNode.Create(pScene, boneName); lSkeletonLimbNode1.SetNodeAttribute(lSkeletonLimbNodeAttribute1); lSkeletonLimbNode1.LclTranslation = new List <double> { bone.Position.X, -bone.Position.Y, bone.Position.Z }; ME3Explorer.Unreal.Classes.SkeletalMeshOld.Quad boneQuad; boneQuad.x = -bone.Orientation.X; boneQuad.y = bone.Orientation.Y; boneQuad.z = bone.Orientation.Z; boneQuad.w = -bone.Orientation.W; if (boneIndex == 0) { boneQuad.w = boneQuad.w * -1; } Rotator rot = QuatToRotator(boneQuad); lSkeletonLimbNode1.LclRotation = new List <double> { rot.Roll, rot.Pitch, rot.Yaw }; var children = Skeleton.Where(b => b.Parent == boneIndex).ToList(); foreach (var childBone in children) { int childIndexInSkeleton = Skeleton.FindIndex(b => b.Name == childBone.Name); if (childIndexInSkeleton != boneIndex) { FBXNode fbxChildBone = CreateFbxBone(childIndexInSkeleton, Skeleton, pScene, lSkeletonLimbNode1); lSkeletonLimbNode1.AddChild(fbxChildBone); } } return(lSkeletonLimbNode1); }
private void ExportGroupShapes(CSGGroup group, FBXScene fbxScene, FBXNode sceneNode, string groupName, FBXNode node) { CSGShapeArray childShapeList = group.GetShapes(); for (int shapeIndex = 0; shapeIndex < childShapeList.GetSize(); shapeIndex++) { // this little bit of weirdness is due to View3D and Paint3D not being able to have multiple shapes on the same node // there may need to be an export option for this at some point var subnode = node; if (shapeIndex > 0) { string subGroupName = this.GetUniqueName(groupName + "_" + shapeIndex.ToString(), "group"); subnode = FBXNode.Create(sceneNode, subGroupName); node.AddChild(subnode); } this.ExportShape(fbxScene, subnode, childShapeList.GetElement(shapeIndex)); subnode.SetShadingMode(ArcManagedFBX.Types.EShadingMode.eTextureShading); } }
private void ExportGroupRecursively(CSGGroup group, FBXScene fbxScene, FBXNode parentNode, FBXAnimLayer animationLayer, float keyFramesPerSecond) { string groupName = this.GetUniqueName(group.Name, "group"); var node = FBXNode.Create(parentNode, groupName); parentNode.AddChild(node); this.SetTransform(group, node); this.ExportGroupAnimation(group, animationLayer, keyFramesPerSecond, node); this.ExportGroupShapes(group, fbxScene, parentNode, groupName, node); CSGGroupArray childGroupList = group.GetChildren(); for (int groupIndex = 0; groupIndex < childGroupList.GetSize(); groupIndex++) { this.ExportGroupRecursively(childGroupList.GetElement(groupIndex), fbxScene, node, animationLayer, keyFramesPerSecond); } }
private FBXNode CreateFbxMesh(MESkeletalMesh mesh, string mname, FBXScene pScene, float exportScale = 1.0f) { MESkeletalMesh.LODModelStruct lod = mesh.LODModels[0]; FBXMesh fbxMesh = FBXMesh.Create(pScene, mname); FBXNode lMeshNode = FBXNode.Create(pScene, mname); lMeshNode.SetNodeAttribute(fbxMesh); FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent(); lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial(); lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon); lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); fbxMesh.InitControlPoints(lod.NumVertices); // init UV maps FBXGeometryElementUV[] UVs = new FBXGeometryElementUV[lod.Sections.Count]; for (int s = 0; s < lod.Sections.Count; s++) { string matName = GetMatName(mesh, lod, s); UVs[s] = fbxMesh.CreateElementUV(matName); UVs[s].SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); } // vertices for (int j = 0; j < lod.VertexBufferGPUSkin.Vertices.Count; j++) { var vertex = lod.VertexBufferGPUSkin.Vertices[j]; FBXVector4 position = new FBXVector4(vertex.Position.X * exportScale, -vertex.Position.Y * exportScale, vertex.Position.Z * exportScale, 0); FBXVector4 normal = new FBXVector4(vertex.TangentX, 0, vertex.TangentZ, 0); fbxMesh.SetControlPoint(j, position); lGeometryElementTangent.Add(normal); // uvs for (int s = 0; s < lod.Sections.Count; s++) { var sectionVerts = GetSectionVertices(mesh, 0, s); if (sectionVerts.Contains(j)) { FBXVector4 texCoords = new FBXVector4(vertex.U, 1 - vertex.V, 0, 0); UVs[s].Add(texCoords); } else { UVs[s].Add(new FBXVector4(0, 0, 0, 0)); } } } // faces & mats for (int s = 0; s < lod.Sections.Count; s++) { int chunkId = lod.Sections[s].ChunkIndex; var chunk = lod.Chunks[chunkId]; // mat string matName = GetMatName(mesh, lod, s); lMeshNode.AddMaterial(pScene, matName); // faces for (int j = 0; j < lod.Sections[s].NumTriangles; j++) { int baseI = lod.Sections[s].BaseIndex; fbxMesh.BeginPolygon(s); fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3]); fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3 + 1]); fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3 + 2]); fbxMesh.EndPolygon(); } } return(lMeshNode); }
private FBXNode CreateFbxMesh(MeshLOD lod, FBXScene pScene) { FBXMesh fbxMesh = FBXMesh.Create(pScene, lod.shortName); FBXNode lMeshNode = FBXNode.Create(pScene, lod.shortName); lMeshNode.SetNodeAttribute(fbxMesh); FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal(); lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal(); lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent(); lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial(); lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon); lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); int verticesCount = lod.GetLODTotalVertCount(); fbxMesh.InitControlPoints(verticesCount); List <FBXGeometryElementUV[]> UVs = new List <FBXGeometryElementUV[]>(); for (int i = 0; i < lod.sections.Count; i++) { UVs.Add(new FBXGeometryElementUV[Vertex.UV_SLOTS]); } int VertexOffset = 0; for (int i = 0; i < lod.sections.Count; i++) { MeshLodSection section = lod.sections[i]; for (int j = 0; j < section.vertices.Count; j++) { FBXVector4 position = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0); FBXVector4 normal = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]); fbxMesh.SetControlPoint(VertexOffset + j, position); lGeometryElementNormal.Add(normal); // adding a check on bitangent and tangent as some meshes don't have them... if (section.vertices[j].biTangents.members.Length == 4) { FBXVector4 bitangent = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]); lGeometryElementBiNormal.Add(bitangent); } if (section.vertices[j].tangents.members.Length == 4) { FBXVector4 tangent = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]); lGeometryElementTangent.Add(tangent); } // multiple UVs management for (int uvInd = 0; uvInd < Vertex.UV_SLOTS; uvInd++) { if (section.vertices[j].texCoords[uvInd] != null) { FBXVector4 texCoords = new FBXVector4(section.vertices[j].texCoords[uvInd].members[0], (-section.vertices[j].texCoords[uvInd].members[1] + 1), 0, 0); if (UVs[i][uvInd] == null) { // if the UV layer does not already exist, we create it... UVs[i][uvInd] = fbxMesh.CreateElementUV(section.matName + "_" + uvInd); UVs[i][uvInd].SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); UVs[i][uvInd].SetReferenceMode(FBXWrapper.ReferenceMode.eDirect); // ... and fill it with empty vectors for all previous sections vertices. for (int p = 0; p < VertexOffset + j; p++) { UVs[i][uvInd].Add(new FBXVector4(0, 0, 0, 0)); } } // and now we can add the tex coord of the current vertex we're treating. UVs[i][uvInd].Add(texCoords); } } // since we use direct reference mode for UV, every vertices in the mesh must be present in every UV layer // so for every UV layer created for previous section, we had an empty vector for this vertex. UVs.Where((o, oi) => oi != i).ToList().ForEach(suv => { for (int subuv = 0; subuv < Vertex.UV_SLOTS; subuv++) { if (suv[subuv] != null) { suv[subuv].Add(new FBXVector4(0, 0, 0, 0)); } } } ); } for (int j = 0; j < section.indicies.Count; j++) { if (j % 3 == 0) { fbxMesh.EndPolygon(); fbxMesh.BeginPolygon(i); } fbxMesh.AddPolygon(VertexOffset + section.indicies[j]); } fbxMesh.EndPolygon(); VertexOffset = VertexOffset + section.vertices.Count; lMeshNode.AddMaterial(pScene, section.matName); } return(lMeshNode); }
private FBXNode CreateFbxMesh(MeshLOD lod, FBXScene pScene) { FBXMesh fbxMesh = FBXMesh.Create(pScene, lod.shortName); FBXNode lMeshNode = FBXNode.Create(pScene, lod.shortName); lMeshNode.SetNodeAttribute(fbxMesh); FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal(); lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal(); lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent(); lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial(); lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon); lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); int verticesCount = lod.GetLODTotalVertCount(); fbxMesh.InitControlPoints(verticesCount); List <FBXGeometryElementUV> UVs = new List <FBXGeometryElementUV>(); for (int i = 0; i < lod.sections.Count; i++) { MeshLodSection section = lod.sections[i]; FBXGeometryElementUV lUVDiffuseElement = fbxMesh.CreateElementUV(section.matName); lUVDiffuseElement.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); lUVDiffuseElement.SetReferenceMode(FBXWrapper.ReferenceMode.eDirect); UVs.Add(lUVDiffuseElement); } int VertexOffset = 0; for (int i = 0; i < lod.sections.Count; i++) { MeshLodSection section = lod.sections[i]; for (int j = 0; j < section.vertices.Count; j++) { FBXVector4 position = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0); FBXVector4 normal = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]); FBXVector4 textCoords = new FBXVector4(section.vertices[j].texCoords.members[0], (-section.vertices[j].texCoords.members[1] + 1), 0, 0); FBXVector4 bitangent = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]); FBXVector4 tangent = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]); fbxMesh.SetControlPoint(VertexOffset + j, position); lGeometryElementNormal.Add(normal); lGeometryElementBiNormal.Add(bitangent); lGeometryElementTangent.Add(tangent); int uvI = 0; foreach (FBXGeometryElementUV uv in UVs) { if (uvI == i) { uv.Add(textCoords); } else { uv.Add(new FBXVector4(0, 0, 0, 0)); } uvI++; } } for (int j = 0; j < section.indicies.Count; j++) { if (j % 3 == 0) { fbxMesh.EndPolygon(); fbxMesh.BeginPolygon(i); } fbxMesh.AddPolygon(VertexOffset + section.indicies[j]); } fbxMesh.EndPolygon(); VertexOffset = VertexOffset + section.vertices.Count; lMeshNode.AddMaterial(pScene, section.matName); } return(lMeshNode); }