/* * wings_fbx.cxx -- * * Erlang driver for FBX file import/export. * * Copyright (c) 2003-2005 Bjorn Gustavsson * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * $Id: wings_fbx.cxx,v 1.9 2005/03/16 20:26:15 bjorng Exp $ */ #define K_NODLL #include #include #include #include #include #include //using namespace FBXSDK_NAMESPACE; #include "fbx_ops.h" extern "C" void send_response(char** res, char* s, int len); // Forward declarations. static bool SaveScene(KFbxSdkManager* pSdkManager, KFbxScene* pScene, char* pFilename); static void LoadScene(char** res, char* pFilename); // Internal functions. static double get_float(char* buff); static KFbxVector4 get_vector(char*& buff); static KFbxColor get_color(char*& buff); static void send_error(char** res, KFbxImporter* importer); static void send_floats(char** res, double* floats, int num_floats); static void send_float(char** res, double f); static void send_integer(char** res, int integer, int resp=RespInteger); static void send_string(char** res, char* s); static void send_color(char** res, KFbxColor& color); static void send_mapping_mode(char** res, kInt mapping_mode); static void send_reference_mode(char** res, kInt ref_mode); static void send_bool(char** res, int b); // Global variables. static KFbxSdkManager* SdkManager = NULL; static KFbxScene* Scene = NULL; static int num_objects = 0; static KFbxNode** objects = NULL; // Current mesh. static KFbxMesh* Mesh; // Mesh itself. static KFbxLayer* Layer; // Layer 0. static KFbxLayerElement* layerElem; // Current layer element. static KFbxLayerElementMaterial* matLayer; // In layer 0 for current mesh. static KFbxLayerElementVertexColor* colorLayer; // In layer 0 for current mesh. static KFbxLayerElementTexture* texLayer; // In layer 0 for current mesh. static KFbxLayerElementUV* uvLayer; // In layer 0 for current mesh. static KFbxVector4* Points; // Control points or normals. static KFbxVector2* UVs; // UV coordinates. static kInt* MaterialIndices; // Material indices (for import). static kInt* TextureIndices; // Texture indices (for import). // Current material and texture. static KFbxMaterial* Material; static KFbxTexture* Texture; // Current node. static KFbxNode* Node; // Current light. static KFbxLight* Light; // Version of file static int Major, Minor, Revision; // File format; static KFbxExporter::EFileFormat FileFormat; struct StackNode { KFbxNode* node; StackNode* next; }; static StackNode* Stack = 0; extern "C" int fbx_control(unsigned int command, char* buff, int count, char** res, int res_size) { switch (command) { case ExpInitialize: SdkManager = KFbxSdkManager::CreateKFbxSdkManager(); Scene = SdkManager->CreateKFbxScene(); objects = 0; num_objects = 0; break; case ExpDestroy: delete [] objects; if (SdkManager) { SdkManager->DestroyKFbxSdkManager(); SdkManager = NULL; } objects = 0; num_objects = 0; break; case ExpNumObjects: num_objects = *(unsigned *) buff; objects = new KFbxNode*[num_objects]; num_objects = 0; break; case ExpCreateMesh: { Mesh = SdkManager->CreateKFbxMesh(); if (Mesh->GetLayer(0) == NULL) { Mesh->CreateLayer(); } Layer = Mesh->GetLayer(0); matLayer = new KFbxLayerElementMaterial; matLayer->SetMappingMode(KFbxLayerElement::eBY_POLYGON); matLayer->SetReferenceMode(KFbxLayerElement::eINDEX_TO_DIRECT); Layer->SetMaterials(matLayer); } break; case ExpInitControlPoints: { unsigned n = *(unsigned *) buff; Mesh->InitControlPoints(n); Points = Mesh->GetControlPoints(); } break; case ExpInitNormals: { Mesh->InitNormals(); Points = Mesh->GetNormals(); } break; case ExpPoint: { KFbxVector4 lPoint = get_vector(buff); *Points++ = lPoint; } break; case ExpInitUVs: { unsigned n = *(unsigned *) buff; Mesh->InitTextureUVIndices(KFbxLayerElement::eBY_POLYGON_VERTEX); Mesh->InitTextureUV(n); UVs = Mesh->GetTextureUV(); } break; case ExpUV: { double u, v; u = *(double *) buff; buff += sizeof(double); v = *(double *) buff; buff += sizeof(double); UVs->Set(u, v); UVs++; } break; case ExpBeginPolygon: { kInt material = *(unsigned *) buff; buff += sizeof(unsigned); kInt texture = *(unsigned *) buff; buff += sizeof(unsigned); Mesh->BeginPolygon(material, texture); } break; case ExpAddPolygon: { kInt vindex = *(unsigned *) buff; buff += sizeof(unsigned); kInt tindex = *(unsigned *) buff; buff += sizeof(unsigned); Mesh->AddPolygon(vindex, tindex); } break; case ExpEndPolygon: Mesh->EndPolygon(); break; case ExpCreateNode: { Node = SdkManager->CreateKFbxNode(buff); objects[num_objects++] = Node; } break; case ExpAssignMesh: // Assign mesh to current node. Node->SetNodeAttribute(Mesh); break; case ExpSetShadingMode: { unsigned shading = *(unsigned *) buff; KFbxNode::EShadingMode sh; switch (shading) { case EnumHardShading: sh = KFbxNode::eHARD_SHADING; break; case EnumWireFrame: sh = KFbxNode::eWIRE_FRAME; break; case EnumFlatShading: sh = KFbxNode::eFLAT_SHADING; break; case EnumLightShading: sh = KFbxNode::eLIGHT_SHADING; break; case EnumTextureShading: sh = KFbxNode::eTEXTURE_SHADING; break; case EnumLightTextureShading: sh = KFbxNode::eLIGHT_TEXTURE_SHADING; break; } Node->SetShadingMode(sh); } break; case ExpSetDefaultT: { KFbxVector4 DefT = get_vector(buff); Node->SetDefaultT(DefT); } break; case ExpSetDefaultR: { KFbxVector4 DefR = get_vector(buff); Node->SetDefaultR(DefR); } break; case ExpMaterial: { Material = SdkManager->CreateKFbxMaterial(buff); Material->SetShadingModel("phong"); int m = matLayer->GetDirectArray().Add(Material); matLayer->GetIndexArray().Add(m); } break; case ExpAmbient: Material->SetAmbient(get_color(buff)); break; case ExpDiffuse: Material->SetDiffuse(get_color(buff)); break; case ExpSpecular: Material->SetSpecular(get_color(buff)); break; case ExpEmissive: Material->SetEmissive(get_color(buff)); break; case ExpOpacity: Material->SetOpacity(get_float(buff)); break; case ExpShininess: Material->SetShininess(get_float(buff)); break; case ExpInitTextures: Mesh->InitTextureIndices(KFbxLayerElement::eBY_POLYGON); break; case ExpCreateTexture: { Texture = SdkManager->CreateKFbxTexture(buff); Texture->SetTextureUse(KFbxTexture::eSTANDARD); Texture->SetMappingType(KFbxTexture::eUV); Texture->SetMaterialUse(KFbxTexture::eMODEL_MATERIAL); Texture->SetSwapUV(false); Texture->SetTranslation(0.0, 0.0); Texture->SetScale(1.0, 1.0); Texture->SetRotation(0.0, 0.0); KFbxLayerElementTexture* texLayer = Layer->GetTextures(); int m = texLayer->GetDirectArray().Add(Texture); texLayer->GetIndexArray().Add(m); } break; case ExpTextureFilename: Texture->SetFileName(buff); break; case ExpInitVertexColorTable: colorLayer = new KFbxLayerElementVertexColor; colorLayer->SetMappingMode(KFbxLayerElement::eBY_POLYGON_VERTEX); colorLayer->SetReferenceMode(KFbxLayerElement::eINDEX_TO_DIRECT); Layer->SetVertexColors(colorLayer); break; case ExpVertexColor: { KFbxColor col = get_color(buff); colorLayer->GetDirectArray().Add(col); } break; case ExpVertexColorIndex: { unsigned index = *(unsigned *) buff; colorLayer->GetIndexArray().Add(index); } break; // // Lights. // case ExpCreateLight: Light = SdkManager->CreateKFbxLight(); break; case ExpLightType: { unsigned light_type = *(unsigned *) buff; KFbxLight::ELightType lt; switch (light_type) { case LightPoint: lt = KFbxLight::ePOINT; break; case LightDirectional: lt = KFbxLight::eDIRECTIONAL; break; case LightSpot: lt = KFbxLight::eSPOT; break; } Light->SetLightType(lt); } break; case ExpLightColor: { KFbxColor col = get_color(buff); Light->SetDefaultColor(col); } break; case ExpLightConeAngle: { double angle = *(double *) buff; Light->SetDefaultConeAngle(angle); } break; case ExpAssignLight: // Assign light to current node. Node->SetNodeAttribute(Light); break; case ExpAmbientColor: Scene->GetGlobalLightSettings().SetAmbientColor(get_color(buff)); break; case ExpAxisAlignmentInEulerAngle: { KFbxVector4 pAB; KFbxVector4 pA; KFbxVector4 pB; KFbxVector4 pAngles; pAB = get_vector(buff); pA = get_vector(buff); pB = get_vector(buff); KFbxVector4::AxisAlignmentInEulerAngle(pAB, pA, pB, pAngles); send_floats(res, (kDouble *) pAngles, 3); break; } case ExpLinkObjects: { KFbxNode* lRootNode = Scene->GetRootNode(); for (int i = 0; i < num_objects; i++) { KFbxNode* node = objects[i]; lRootNode->AddChild(objects[i]); } } break; case ExpSetFileFormat: switch (*buff) { case ExpFileFormatFbx5: FileFormat = KFbxExporter::eFBX_50_BINARY; break; case ExpFileFormatFbx6: FileFormat = KFbxExporter::eFBX_BINARY; break; case ExpFileFormatFbx5Ascii: FileFormat = KFbxExporter::eFBX_50_ASCII; break; case ExpFileFormatFbx6Ascii: FileFormat = KFbxExporter::eFBX_ASCII; break; } break; case ExpSaveScene: SaveScene(SdkManager, Scene, buff); break; // // Import functions start here. // case ImpLoadScene: LoadScene(res, buff); Node = Scene->GetRootNode(); break; case ImpVersion: { char sbuf[64]; sprintf(sbuf, "%d.%d.%d", Major, Minor, Revision); send_string(res, sbuf); break; } case ImpGlobalAmbient: { double rgb[3]; KFbxColor amb = Scene->GetGlobalLightSettings().GetAmbientColor(); rgb[0] = amb.mRed; rgb[1] = amb.mGreen; rgb[2] = amb.mBlue; send_floats(res, rgb, 3); } break; case ImpNumChildren: { int children = Node->GetChildCount(); send_integer(res, children); } break; case ImpEnterChildNode: { kInt child = *(kInt *) buff; StackNode* stk_node = new StackNode; stk_node->node = Node; stk_node->next = Stack; Stack = stk_node; Node = Node->GetChild(child); } break; case ImpPopNode: { StackNode* stk_node = Stack; Node = Stack->node; Stack = stk_node->next; delete stk_node; } break; case ImpNodeType: { KFbxNodeAttribute* lNodeAttribute = Node->GetNodeAttribute(); if (lNodeAttribute == 0) { send_integer(res, NodeEmpty); } else { int type = 0; switch (lNodeAttribute->GetAttributeType()) { case KFbxNodeAttribute::eNULL: type = NodeNull; break; case KFbxNodeAttribute::eMARKER: type = NodeMarker; break; case KFbxNodeAttribute::eSKELETON: type = NodeSkeleton; break; case KFbxNodeAttribute::eMESH: type = NodeMesh; break; case KFbxNodeAttribute::eNURB: type = NodeNurb; break; case KFbxNodeAttribute::ePATCH: type = NodePatch; break; case KFbxNodeAttribute::eCAMERA: type = NodeCamera; break; case KFbxNodeAttribute::eCAMERA_SWITCHER: type = NodeCameraSwitcher; break; case KFbxNodeAttribute::eLIGHT: type = NodeLight; break; case KFbxNodeAttribute::eOPTICAL_REFERENCE: type = NodeOpticalReference; break; case KFbxNodeAttribute::eOPTICAL_MARKER: type = NodeOpticalMarker; break; default: type = NodeUnknown; break; } send_integer(res, type); } } break; case ImpNodeName: send_string(res, Node->GetName()); break; case ImpIsVisible: send_bool(res, Node->GetVisibility()); break; case ImpDefaultT: { KFbxVector4 vec; Node->GetDefaultT(vec); send_floats(res, vec.mData, 3); } break; case ImpDefaultR: { KFbxVector4 vec; Node->GetDefaultR(vec); send_floats(res, vec.mData, 3); } break; case ImpDefaultS: { KFbxVector4 vec; Node->GetDefaultS(vec); send_floats(res, vec.mData, 3); } break; case ImpMesh: Mesh = (KFbxMesh*) Node->GetNodeAttribute(); Layer = Mesh->GetLayer(0); break; case ImpConvertToMesh: { KFbxGeometryConverter* lConverter = SdkManager->CreateKFbxGeometryConverter(); lConverter->TriangulateInPlace(Node); SdkManager->DestroyKFbxGeometryConverter(lConverter); } break; case ImpNumVertices: send_integer(res, Mesh->GetControlPointsCount()); break; case ImpVertices: Points = Mesh->GetControlPoints(); break; case ImpNormals: Points = Mesh->GetNormals(); break; case ImpUVs: UVs = Mesh->GetTextureUV(); break; case ImpPoint: send_floats(res, Points->mData, 3); Points++; break; case ImpUV: send_floats(res, UVs->mData, 2); UVs++; break; case ImpNumPolygons: send_integer(res, Mesh->GetPolygonCount()); break; case ImpPolygonSize: { int i = *(int *) buff; send_integer(res, Mesh->GetPolygonSize(i)); } break; case ImpPolygonVertex: { int i = *(int *) buff; buff += sizeof(int); int j = *(int *) buff; buff += sizeof(int); send_integer(res, Mesh->GetPolygonVertex(i, j)); } break; case ImpPolygonUV: { int i = *(int *) buff; buff += sizeof(int); int j = *(int *) buff; buff += sizeof(int); send_integer(res, Mesh->GetTextureUVIndex(i, j)); } break; case ImpLocalTransformation: { KFbxVector4 T, R, S, Tmp; KFbxXMatrix LocalPosition; double matrix[16]; KFbxTakeNode* lCurrentTakeNode = Node->GetCurrentTakeNode(); KFbxTakeInfo* lCurrentTakeInfo = Scene->GetTakeInfo(lCurrentTakeNode->GetName()); KTime pTime; if (lCurrentTakeInfo) { pTime = lCurrentTakeInfo->mLocalTimeSpan.GetStart(); } else { pTime = KTIME_ZERO; } T[0] = lCurrentTakeNode->GetTranslationX()->Evaluate(pTime); T[1] = lCurrentTakeNode->GetTranslationY()->Evaluate(pTime); T[2] = lCurrentTakeNode->GetTranslationZ()->Evaluate(pTime); LocalPosition.SetT(T); R[0] = lCurrentTakeNode->GetEulerRotationX()->Evaluate(pTime); R[1] = lCurrentTakeNode->GetEulerRotationY()->Evaluate(pTime); R[2] = lCurrentTakeNode->GetEulerRotationZ()->Evaluate(pTime); LocalPosition.SetR(R); S[0] = lCurrentTakeNode->GetScaleX()->Evaluate(pTime); S[1] = lCurrentTakeNode->GetScaleY()->Evaluate(pTime); S[2] = lCurrentTakeNode->GetScaleZ()->Evaluate(pTime); LocalPosition.SetS(S); #if 0 Node->GetDefaultT(T); Node->GetDefaultR(R); Node->GetDefaultS(S); LocalPosition.SetT(T); LocalPosition.SetR(R); LocalPosition.SetS(S); #endif send_floats(res, (double*) LocalPosition, 16); } break; case ImpNumLinks: send_integer(res, Mesh->GetLinkCount()); break; case ImpNumShapes: send_integer(res, Mesh->GetShapeCount()); break; // // General layer element support. // case ImpMappingMode: send_mapping_mode(res, layerElem->GetMappingMode()); break; case ImpReferenceMode: send_reference_mode(res, layerElem->GetReferenceMode()); break; // // Material import. // case ImpInitMaterials: { unsigned b = 0; if (Layer) { layerElem = matLayer = Layer->GetMaterials(); b = (layerElem != NULL); } send_bool(res, b); } break; case ImpMaterialIndices: MaterialIndices = Mesh->GetMaterialIndices(); break; case ImpMaterialIndex: send_integer(res, *MaterialIndices++); break; case ImpNumMaterials: switch (layerElem->GetReferenceMode()) { case KFbxLayerElement::eDIRECT: case KFbxLayerElement::eINDEX_TO_DIRECT: send_integer(res, matLayer->GetDirectArray().GetCount()); break; case KFbxLayerElement::eINDEX: send_integer(res, matLayer->GetIndexArray().GetCount()); break; default: send_integer(res, 0); break; } break; case ImpMaterial: { kInt index = *(kInt *) buff; Material = matLayer->GetDirectArray().GetAt(index); } break; case ImpMaterialName: send_string(res, Material->GetName()); break; case ImpAmbient: { KFbxColor col = Material->GetAmbient(); send_color(res, col); } break; case ImpDiffuse: { KFbxColor col = Material->GetDiffuse(); send_color(res, col); } break; case ImpSpecular: { KFbxColor col = Material->GetSpecular(); send_color(res, col); } break; case ImpEmissive: { KFbxColor col = Material->GetEmissive(); send_color(res, col); } break; case ImpShininess: send_float(res, Material->GetShininess()); break; case ImpOpacity: send_float(res, Material->GetOpacity()); break; // // Importing of UVs. // case ImpInitUVs: { unsigned b = 0; if (Layer) { layerElem = uvLayer = Layer->GetUVs(); if (uvLayer != NULL) { // There is a UV layer element. Unfortunately, careless // exporters (such as previous releases of this plug-in) // could create the layer element without filling it in. // Therefore, check that the needed arrays are really there. switch (layerElem->GetReferenceMode()) { case KFbxLayerElement::eDIRECT: b = uvLayer->GetDirectArray() != NULL; break; case KFbxLayerElement::eINDEX: b = uvLayer->GetIndexArray() != NULL; break; case KFbxLayerElement::eINDEX_TO_DIRECT: b = uvLayer->GetDirectArray() != NULL && uvLayer->GetIndexArray() != NULL; break; } } } send_bool(res, b); } break; case ImpNumUVs: send_integer(res, Mesh->GetTextureUVCount()); break; // // Importing of textures. // case ImpInitTextures: { unsigned b = 0; if (Layer) { layerElem = texLayer = Layer->GetTextures(); if (texLayer != NULL) { // There is a texture layer element. Unfortunately, careless // exporters (such as previous releases of this plug-in) // could create the layer element without filling it in. // Therefore, check that the needed arrays really are there. switch (layerElem->GetReferenceMode()) { case KFbxLayerElement::eDIRECT: b = texLayer->GetDirectArray() != NULL; break; case KFbxLayerElement::eINDEX: b = texLayer->GetIndexArray() != NULL; break; case KFbxLayerElement::eINDEX_TO_DIRECT: b = texLayer->GetDirectArray() != NULL && texLayer->GetIndexArray() != NULL; break; } } send_bool(res, b); } } break; case ImpNumTextures: send_integer(res, texLayer->GetDirectArray().GetCount()); break; case ImpTexture: { kInt index = *(kInt *) buff; Texture = texLayer->GetDirectArray().GetAt(index); } break; case ImpTextureFileName: send_string(res, Texture->GetFileName()); break; case ImpTxMappingType: { int type; switch (Texture->GetMappingType()) { case KFbxTexture::eNULL: type = TxMapNull; break; case KFbxTexture::ePLANAR: type = TxMapPlanar; break; case KFbxTexture::eSPHERICAL: type = TxMapSpherical; break; case KFbxTexture::eCYLINDRICAL: type = TxMapCylindrical; break; case KFbxTexture::eBOX: type = TxMapBox; break; case KFbxTexture::eFACE: type = TxMapFace; break; case KFbxTexture::eUV: type = TxMapUV; break; case KFbxTexture::eENVIRONMENT: type = TxMapEnvironment; break; } send_integer(res, type); } break; case ImpTextureIndices: TextureIndices = Mesh->GetTextureIndices(); break; case ImpTextureIndex: send_integer(res, *TextureIndices++); break; case ImpLight: Light = (KFbxLight*) Node->GetNodeAttribute(); break; case ImpLightType: { unsigned light_type; switch (Light->GetLightType()) { case KFbxLight::ePOINT: light_type = LightPoint; break; case KFbxLight::eDIRECTIONAL: light_type = LightDirectional; break; case KFbxLight::eSPOT: light_type = LightSpot; break; } send_integer(res, light_type); break; } case ImpLightColor: { KFbxColor color; Light->GetDefaultColor(color); send_color(res, color); } break; case ImpConeAngle: send_float(res, Light->GetDefaultConeAngle()); break; // Vertex colors. case ImpInitVertexColors: { unsigned b = 0; if (Layer) { layerElem = colorLayer = Layer->GetVertexColors(); b = (layerElem != NULL); } send_bool(res, b); } break; default: return -1; } return 0; } static double get_float(char* buff) { return *(double *) buff; } static KFbxVector4 get_vector(char*& buff) { double x, y, z; x = *(double *) buff; buff += sizeof(double); y = *(double *) buff; buff += sizeof(double); z = *(double *) buff; buff += sizeof(double); return KFbxVector4(x, y, z); } static KFbxColor get_color(char*& buff) { double r, g, b; r = *(double *) buff; buff += sizeof(double); g = *(double *) buff; buff += sizeof(double); b = *(double *) buff; buff += sizeof(double); return KFbxColor(r, g, b); } static void send_error(char** res, KFbxImporter* importer) { if (importer->GetLastErrorID() == KFbxIO::ePASSWORD_ERROR) { char sbuf[1] = {RespPasswordProtected}; send_response(res, sbuf, 1); } else { char* error = importer->GetLastErrorString(); char* sbuf = new char[strlen(error)+2]; sbuf[0] = RespError; sprintf(sbuf+1, error); send_response(res, sbuf, 1+strlen(sbuf+1)); delete sbuf; } } static void send_color(char** res, KFbxColor& color) { double f[3]; f[0] = color.mRed; f[1] = color.mGreen; f[2] = color.mBlue; send_floats(res, f, 3); } static void send_floats(char** res, double* floats, int num_floats) { int size = 1+num_floats*sizeof(double); char* sbuf = new char[size]; sbuf[0] = RespFloat; memcpy(sbuf+1, floats, num_floats*sizeof(double)); send_response(res, sbuf, size); delete sbuf; } static void send_float(char** res, double f) { char sbuf[1+sizeof(double)]; sbuf[0] = RespFloat; memcpy(sbuf+1, &f, sizeof(double)); send_response(res, sbuf, 1+sizeof(double)); } static void send_integer(char** res, int integer, int resp) { char sbuf[1+sizeof(int)]; sbuf[0] = resp; memcpy(sbuf+1, &integer, sizeof(int)); send_response(res, sbuf, 1+sizeof(int)); } static void send_string(char** res, char* s) { int size = strlen(s); char* sbuf = new char[1+size]; sbuf[0] = RespString; memcpy(sbuf+1, s, size); send_response(res, sbuf, 1+size); delete sbuf; } static void send_mapping_mode(char** res, kInt mapping_mode) { int type = MappingByControlPoint; switch (mapping_mode) { case KFbxLayerElement::eBY_CONTROL_POINT: type = MappingByControlPoint; break; case KFbxLayerElement::eBY_POLYGON_VERTEX: type = MappingByPolygonVertex; break; case KFbxLayerElement::eBY_POLYGON: type = MappingByPolygon; break; case KFbxLayerElement::eALL_SAME: type = MappingAllSame; break; } send_integer(res, type, RespMappingMode); } static void send_reference_mode(char** res, kInt ref_mode) { int type = RefModeDirect; switch (ref_mode) { case KFbxLayerElement::eDIRECT: type = RefModeDirect; break; case KFbxLayerElement::eINDEX: type = RefModeIndex; break; case KFbxLayerElement::eINDEX_TO_DIRECT: type = RefIndexToDirect; break; } send_integer(res, type, RespReferenceMode); } static void send_bool(char** res, int b) { char sbuf[2]; sbuf[0] = RespBoolean; sbuf[1] = b; send_response(res, sbuf, sizeof(sbuf)); } static bool SaveScene(KFbxSdkManager* pSdkManager, KFbxScene* pScene, char* pFilename) { int lMajor, lMinor, lRevision; // Create an exporter. KFbxExporter* lExporter = pSdkManager->CreateKFbxExporter(); char* password = pFilename + strlen(pFilename) + 1; lExporter->SetFileFormat(FileFormat); // Initialize the exporter by providing a filename. if (lExporter->Initialize(pFilename) == false) { printf("Call to KFbxExporter::Initialize() failed.\n"); printf("Error returned: %s\n\n", lExporter->GetLastErrorString()); return false; } lExporter->SetPassword(password); KFbxIO::GetCurrentVersion(lMajor, lMinor, lRevision); // Set the export states. By default, the export states are always set to // true except for the option eEXPORT_TEXTURE_AS_EMBEDDED. The code below // shows how to change these states. lExporter->SetState(KFbxExporter::eEXPORT_MATERIAL, true); lExporter->SetState(KFbxExporter::eEXPORT_TEXTURE, true); lExporter->SetState(KFbxExporter::eEXPORT_TEXTURE_AS_EMBEDDED, false); lExporter->SetState(KFbxExporter::eEXPORT_LINK, true); lExporter->SetState(KFbxExporter::eEXPORT_SHAPE, true); lExporter->SetState(KFbxExporter::eEXPORT_GOBO, true); lExporter->SetState(KFbxExporter::eEXPORT_ANIMATION, true); lExporter->SetState(KFbxExporter::eEXPORT_GLOBAL_SETTINGS, true); // Export the scene. bool lStatus = lExporter->Export(*pScene); // Destroy the exporter. pSdkManager->DestroyKFbxExporter(lExporter); return lStatus; } static void LoadScene(char **res, char* pFilename) { KFbxImporter* lImporter = SdkManager->CreateKFbxImporter(); char* password = pFilename + strlen(pFilename) + 1; // Initialize the importer by providing a filename. if (lImporter->Initialize(pFilename) == false) { send_error(res, lImporter); SdkManager->DestroyKFbxImporter(lImporter); } else { lImporter->GetFileVersion(Major, Minor, Revision); lImporter->SetPassword(password); // Set the import states. To possibly save some time, // we don't import things such as animations which are not // supported in Wings anyway. lImporter->SetState(KFbxImporter::eIMPORT_MATERIAL, true); lImporter->SetState(KFbxImporter::eIMPORT_TEXTURE, true); lImporter->SetState(KFbxImporter::eIMPORT_LINK, true); lImporter->SetState(KFbxImporter::eIMPORT_SHAPE, true); lImporter->SetState(KFbxImporter::eIMPORT_GOBO, false); lImporter->SetState(KFbxImporter::eIMPORT_ANIMATION, true); lImporter->SetState(KFbxImporter::eIMPORT_GLOBAL_SETTINGS, true); // Import the scene. if (!lImporter->Import(*Scene)) { send_error(res, lImporter); } // Destroy the importer. SdkManager->DestroyKFbxImporter(lImporter); } }