void bgExporterMax::ExpScene() { struct tm *newtime; time_t aclock; time(&aclock); newtime = localtime(&aclock); TSTR today = _tasctime(newtime); today.remove(today.length() - 1); _ftprintf(m_pStream, _T("%s\t%s\n"), _T("#BG3D_MODEL"), FixupName(today)); // 날짜 _ftprintf(m_pStream, _T("%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n"), _T("#SCENE_INFO"), m_Scene.iVersion, // 버전 m_Scene.iFirstFrame, // 시작 프레임 m_Scene.iLastFrame, // 마지막 프레임 m_Scene.iFrameSpeed, // 프레임 스피드 m_Scene.iTickPerFrame, // 프레임당 틱 m_Scene.iNumMesh, // 메시 갯수 m_Scene.iMaxWeight, // 가중치 m_Scene.iBindPose); // 바인드포즈 }
const MCHAR* HLSLShaderMaterialClassDesc::GetEntryCategory() const { static TSTR s_categoryInfo; if( s_categoryInfo.length()==0 ) { s_categoryInfo = GetString( IDS_CATEGORY_MPOOL_PREFIX ); s_categoryInfo += _T("\\"); s_categoryInfo += GetString( IDS_CATEGORY_MPOOL ); } return s_categoryInfo.data(); }
// Dump some global animation information. void HoeMax::ExportGlobalInfo() { struct tm *newtime; time_t aclock; time( &aclock ); newtime = localtime(&aclock); TSTR today = _tasctime(newtime); // The date string has a \n appended. today.remove(today.length()-1); // Remove the \n // Start with a file identifier and format version m_file.Printf( "// %s\t%.2f\n", this->LongDesc(), this->Version()*0.01f); m_file.Printf( "// %s\t%s\n", this->AuthorName(), this->CopyrightMessage()); m_file.Printf( "// \"%s\" - %s\n", Utils::FixupName(ip->GetCurFileName()), (TCHAR*)today); m_file.Printf( "\n"); }
// Dump some global animation information. void Exporter::ExportGlobalInfo() { Interval range = ip->GetAnimRange(); struct tm *newtime; time_t aclock; time( &aclock ); newtime = localtime(&aclock); TSTR today = _tasctime(newtime); // The date string has a \n appended. today.remove(today.length()-1); // Remove the \n strcpy(rsm->MaxFileName,FixupName(ip->GetCurFilePath())); // Texmap* env = ip->GetEnvironmentMap(); }
int TextureMgr::Find(const TSTR &Name, TextureType Type) { int i,Count; if(Name.length()) { Count = m_List.size(); for(i=0; i < Count; i++) { if(Name == m_List[i].m_Name && Type == m_List[i].m_Type) { return(i); } } } return(-1); }
int Unreal3DExport::DoExport( const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options ) { int Result = FALSE; // Set a global prompt display switch bShowPrompts = suppressPrompts ? false : true; bExportSelected = (options & SCENE_EXPORT_SELECTED) ? true : false; // Get file names SplitFilename(TSTR(name), &FilePath, &FileName, &FileExt); if( MatchPattern(FileName,TSTR(_T("*_d")),TRUE) || MatchPattern(FileName,TSTR(_T("*_a")),TRUE) ) { FileName = FileName.Substr(0,FileName.length()-2); } ModelFileName = FilePath + _T("\\") + FileName + TSTR(_T("_d")) + FileExt; AnimFileName = FilePath + _T("\\") + FileName + TSTR(_T("_a")) + FileExt; ScriptFileName = FilePath + _T("\\") + FileName + TSTR(_T("_rc.uc")); // Open Log fLog = _tfopen(FilePath + _T("\\") + FileName + _T(".log") ,_T("wb")); // Init pInt = GetCOREInterface(); pInt->ProgressStart( GetString(IDS_INFO_INIT), TRUE, fn, this); Progress += U3D_PROGRESS_INIT; try { MyErrorProc pErrorProc; SetErrorCallBack(&pErrorProc); ReadConfig(); //if(bShowPrompts) /*DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), Unreal3DExportOptionsDlgProc, (LPARAM)this);*/ //if(showPrompts) { // Prompt the user with our dialogbox, and get all the options. if(!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), Unreal3DExportOptionsDlgProc, (LPARAM)this)) { throw CancelException(); } } // Enumerate interesting nodes Init(); // Fetch data from nodes GetTris(); GetAnim(); // Prepare data for writing Prepare(); // Write to files WriteScript(); WriteModel(); WriteTracking(); // Show optional summary ShowSummary(); WriteConfig(); Result = IMPEXP_SUCCESS; } catch( CancelException& ) { Result = IMPEXP_CANCEL; } catch( MAXException& e ) { if( bShowPrompts && !e.message.isNull() ) { MaxMsgBox(pInt->GetMAXHWnd(),e.message,ShortDesc(),MB_OK|MB_ICONERROR); } Result = IMPEXP_FAIL; } // Release scene if( pScene != NULL ) { pScene->ReleaseIGame(); pScene = NULL; } // Close files fclosen(fMesh); fclosen(fAnim); fclosen(fLog); fclosen(fScript); // Return to MAX pInt->ProgressEnd(); return Result; }
bool CExporter::buildGrpSkinnedMesh(grp::SkinnedMeshExporter* skinnedMesh, INode* node, ISkin* skin, ISkinContextData* data, Mesh* mesh, const std::vector<ExportVertex>& exportVertices, const std::vector< std::vector<grp::LodIndices> >& buffers) { assert(skinnedMesh != NULL); assert(node != NULL); wchar_t unicodeString[256]; mbstowcs(unicodeString, node->GetName(), 255); skinnedMesh->m_name = unicodeString; skinnedMesh->m_vertexFormat = grp::POSITION; if (!generateSkinBone(skinnedMesh, node, skin)) { return false; } skinnedMesh->m_skinVertices.resize(exportVertices.size()); skinnedMesh->m_positions.resize(exportVertices.size()); skinnedMesh->m_type = 0; if ((m_options.exportType & EXP_MESH_NORMAL) != 0) { skinnedMesh->m_vertexFormat |= grp::NORMAL; skinnedMesh->m_normals.resize(exportVertices.size()); } if ((m_options.exportType & EXP_MESH_TANGENT) != 0) { skinnedMesh->m_vertexFormat |= grp::TANGENT; skinnedMesh->m_tangents.resize(exportVertices.size()); skinnedMesh->m_binormals.resize(exportVertices.size()); } if ((m_options.exportType & EXP_MESH_TEXCOORD) != 0) { skinnedMesh->m_vertexFormat |= grp::TEXCOORD; } if ((m_options.exportType & EXP_MESH_TEXCOORD2) != 0) { skinnedMesh->m_vertexFormat |= grp::TEXCOORD2; } if ((m_options.exportType & EXP_MESH_VERTEX_COLOR) != 0) { skinnedMesh->m_vertexFormat |= grp::COLOR; } //纹理坐标层数 int texCoordCount = mesh->getNumMaps() - 1; //0层为顶点颜色,1层为第一层纹理坐标 assert(texCoordCount >= 0); texCoordCount = std::min(2, texCoordCount); if (mesh->tvFace == NULL) { texCoordCount = 0; } if ((m_options.exportType & EXP_MESH_TEXCOORD) == 0) { texCoordCount = 0; } if (texCoordCount == 0) { skinnedMesh->m_vertexFormat &= ~grp::TEXCOORD; skinnedMesh->m_vertexFormat &= ~grp::TEXCOORD2; skinnedMesh->m_vertexFormat &= ~grp::TANGENT; } else if (texCoordCount == 1) { skinnedMesh->m_vertexFormat &= ~grp::TEXCOORD2; } else if ((skinnedMesh->m_vertexFormat & grp::TEXCOORD2) == 0) { texCoordCount = 1; } if (mesh->vcFace == NULL) { skinnedMesh->m_vertexFormat &= ~grp::COLOR; } if (skinnedMesh->checkVertexFormat(grp::TEXCOORD)) { skinnedMesh->m_texCoordsArray.resize(texCoordCount); for (int i = 0; i < texCoordCount; ++i) { skinnedMesh->m_texCoordsArray[i].resize(exportVertices.size()); } } if (skinnedMesh->checkVertexFormat(grp::COLOR)) { skinnedMesh->m_colors.resize(exportVertices.size()); } bool influenceIgnored = false; for (int iVertex = 0; iVertex < exportVertices.size(); ++iVertex) { grp::SkinVertex& skinVertex = skinnedMesh->m_skinVertices[iVertex]; const ExportVertex& vertexExp = exportVertices[iVertex]; //骨骼权重 size_t influenceCount = data->GetNumAssignedBones(vertexExp.maxVertexIndex); if (influenceCount <= 0) { setLastError("Vertex has no bone weight."); return false; } std::vector<grp::VertexInfluence> vecInflu; vecInflu.resize(std::max(influenceCount, grp::MAX_VERTEX_INFLUENCE)); for (int iInfluence = 0; iInfluence < influenceCount; ++iInfluence) { //每个影响顶点的骨骼 grp::VertexInfluence influence; influence.boneIndex = data->GetAssignedBone(vertexExp.maxVertexIndex, iInfluence); influence.weight = data->GetBoneWeight(vertexExp.maxVertexIndex, iInfluence); if (influence.weight < grp::MIN_VERTEX_WEIGHT) { influence.weight = 0.0f; } vecInflu[iInfluence] = influence; } //按权重从大到小排序 sort(vecInflu.begin(), vecInflu.end()); if (vecInflu[grp::MAX_VERTEX_INFLUENCE - 1].weight > 0.0f) { influenceIgnored = true; } memcpy(skinVertex.influences, &(vecInflu[0]), grp::MAX_VERTEX_INFLUENCE * sizeof(grp::VertexInfluence)); //严格保证总权重为1,这个很重要 float fWeightTotal = 0.0f; for (int i = 0; i < grp::MAX_VERTEX_INFLUENCE; ++i) { fWeightTotal += skinVertex.influences[i].weight; } if (fWeightTotal > 0.0f) { for (int i = 0; i < grp::MAX_VERTEX_INFLUENCE; ++i) { skinVertex.influences[i].weight /= fWeightTotal; } } else { setLastError("Vertex has no bone weight."); return false; } ::Vector3FromPoint3(skinnedMesh->m_positions[iVertex], mesh->verts[vertexExp.maxVertexIndex]); if (skinnedMesh->m_normals.size() > iVertex) { skinnedMesh->m_normals[iVertex] = vertexExp.normal; } if (skinnedMesh->m_tangents.size() > iVertex) { skinnedMesh->m_tangents[iVertex] = vertexExp.tangent; } if (skinnedMesh->m_binormals.size() > iVertex) { skinnedMesh->m_binormals[iVertex] = vertexExp.binormal; } float weightError = calcWeightError(*skinnedMesh, skinVertex, skinnedMesh->m_positions[iVertex]); if (weightError > skinnedMesh->m_weightLodError) { skinnedMesh->m_weightLodError = weightError; } //纹理坐标 for (int i = 0; i < texCoordCount; ++i) { grp::Vector2& texcoord = skinnedMesh->m_texCoordsArray[i][iVertex]; if (i == 0) { ::Vector2FromPoint3(texcoord, mesh->tVerts[vertexExp.texcoord[i]]); } else { UVVert* pUV = mesh->mapVerts(i + 1); ::Vector2FromPoint3(texcoord, pUV[vertexExp.texcoord[i]]); } texcoord.Y = 1.0f - texcoord.Y; //纹理坐标超出0,1范围就不压缩 if ((m_options.exportType & EXP_MESH_COMPRESS_TEXCOORD) != 0 && (texcoord.X < 0.0f || texcoord.X > 1.0f || texcoord.Y < 0.0f || texcoord.Y > 1.0f)) { m_options.exportType &= (~EXP_MESH_COMPRESS_TEXCOORD); } } //顶点颜色 if (skinnedMesh->checkVertexFormat(grp::COLOR)) { ::DWORDFromPoint3(skinnedMesh->m_colors[iVertex], mesh->vertCol[vertexExp.color]); } skinVertex.copyPosition = vertexExp.copyPos; skinVertex.copyNormal = vertexExp.copyNormal; }//for (int vertexIndex = 0; vertexIndex < iNumVertexMax; ++vertexIndex) skinnedMesh->m_meshBuffers = buffers; if (influenceIgnored) { ::MessageBox(NULL, "影响顶点的骨骼数超过4,超出的已被忽略。", "提示", MB_OK | MB_ICONINFORMATION); } if ((m_options.exportType & EXP_MESH_PROPERTY) != 0) { TSTR buffer; node->GetUserPropBuffer(buffer); wchar_t* unicodeString = new wchar_t[buffer.length() + 1]; mbstowcs(unicodeString, buffer.data(), buffer.length() + 1); skinnedMesh->m_property = unicodeString; delete[] unicodeString; } return true; }
bool CExporter::buildGrpRigidMesh(grp::RigidMeshExporter* rigidMesh, INode* node, Mesh* mesh, const std::vector<ExportVertex>& exportVertices, const std::vector< std::vector<grp::LodIndices> >& buffers) { assert(rigidMesh != NULL); assert(node != NULL); wchar_t unicodeString[256]; mbstowcs(unicodeString, node->GetName(), 255); rigidMesh->m_name = unicodeString; rigidMesh->m_positions.resize(exportVertices.size()); rigidMesh->m_type = grp::MESH_RIGID; rigidMesh->m_vertexFormat = grp::POSITION; if ((m_options.exportType & EXP_MESH_NORMAL) != 0) { rigidMesh->m_vertexFormat |= grp::NORMAL; } if ((m_options.exportType & EXP_MESH_TANGENT) != 0) { rigidMesh->m_vertexFormat |= grp::TANGENT; } if ((m_options.exportType & EXP_MESH_TEXCOORD) != 0) { rigidMesh->m_vertexFormat |= grp::TEXCOORD; } if ((m_options.exportType & EXP_MESH_TEXCOORD2) != 0) { rigidMesh->m_vertexFormat |= grp::TEXCOORD2; } if ((m_options.exportType & EXP_MESH_VERTEX_COLOR) != 0) { rigidMesh->m_vertexFormat |= grp::COLOR; } //纹理坐标层数 int texCoordCount = mesh->getNumMaps() - 1; //0层为顶点颜色,1层为第一层纹理坐标 assert(texCoordCount >= 0); texCoordCount = std::min(2, texCoordCount); if (mesh->tvFace == NULL) { texCoordCount = 0; } if ((m_options.exportType & EXP_MESH_TEXCOORD) == 0) { texCoordCount = 0; } if (texCoordCount == 0) { rigidMesh->m_vertexFormat &= ~grp::TEXCOORD; rigidMesh->m_vertexFormat &= ~grp::TEXCOORD2; rigidMesh->m_vertexFormat &= ~grp::TANGENT; } else if (texCoordCount == 1) { rigidMesh->m_vertexFormat &= ~grp::TEXCOORD2; } else if ((rigidMesh->m_vertexFormat & grp::TEXCOORD2) == 0) { texCoordCount = 1; } if (mesh->vcFace == NULL) { rigidMesh->m_vertexFormat &= ~grp::COLOR; } if (rigidMesh->checkVertexFormat(grp::NORMAL)) { rigidMesh->m_normals.resize(exportVertices.size()); } if (rigidMesh->checkVertexFormat(grp::TANGENT)) { rigidMesh->m_tangents.resize(exportVertices.size()); rigidMesh->m_binormals.resize(exportVertices.size()); } if (rigidMesh->checkVertexFormat(grp::TEXCOORD)) { rigidMesh->m_texCoordsArray.resize(texCoordCount); for (int i = 0; i < texCoordCount; ++i) { rigidMesh->m_texCoordsArray[i].resize(exportVertices.size()); } } if (rigidMesh->checkVertexFormat(grp::COLOR)) { rigidMesh->m_colors.resize(exportVertices.size()); } for (int iVertex = 0; iVertex < exportVertices.size(); ++iVertex) { const ExportVertex& vertexExp = exportVertices[iVertex]; //pos grp::Vector3& vPos = rigidMesh->m_positions[iVertex]; ::Vector3FromPoint3(vPos, mesh->verts[vertexExp.maxVertexIndex]); //normal if (rigidMesh->checkVertexFormat(grp::NORMAL)) { grp::Vector3& normal = rigidMesh->m_normals[iVertex]; normal = vertexExp.normal; normal.normalize(); } //tangent/binormal if (rigidMesh->checkVertexFormat(grp::TANGENT)) { grp::Vector3& tangent = rigidMesh->m_tangents[iVertex]; grp::Vector3& binormal = rigidMesh->m_binormals[iVertex]; tangent = vertexExp.tangent; binormal = vertexExp.binormal; tangent.normalize(); binormal.normalize(); } //纹理坐标 for (int i = 0; i < texCoordCount; ++i) { grp::Vector2& texcoord = rigidMesh->m_texCoordsArray[i][iVertex]; if (i == 0) { ::Vector2FromPoint3(texcoord, mesh->tVerts[vertexExp.texcoord[i]]); } else { UVVert* pUV = mesh->mapVerts(i + 1); ::Vector2FromPoint3(texcoord, pUV[vertexExp.texcoord[i]]); } texcoord.Y = 1.0f - texcoord.Y; //纹理坐标超出0,1范围就不压缩 if ((m_options.exportType & EXP_MESH_COMPRESS_TEXCOORD) != 0 && (texcoord.X < 0.0f || texcoord.X > 1.0f || texcoord.Y < 0.0f || texcoord.Y > 1.0f)) { m_options.exportType &= (~EXP_MESH_COMPRESS_TEXCOORD); } } //顶点颜色 if (rigidMesh->checkVertexFormat(grp::COLOR)) { ::DWORDFromPoint3(rigidMesh->m_colors[iVertex], mesh->vertCol[vertexExp.color]); } }//for (int iVertex = 0; iVertex < iNumVertexMax; ++iVertex) rigidMesh->m_meshBuffers = buffers; INode* parent = node->GetParentNode(); if (parent != NULL && !parent->IsRootNode()) { mbstowcs(unicodeString, parent->GetName(), 255); rigidMesh->m_attachedBoneName = unicodeString; Matrix3 nodeTM = node->GetObjTMBeforeWSM(0); Matrix3 parentTM = parent->GetNodeTM(0); ::MatrixFromMatrix3(rigidMesh->m_transform, nodeTM * Inverse(parentTM)); } else { ::MatrixFromMatrix3(rigidMesh->m_transform, node->GetObjTMBeforeWSM(0)); } if ((m_options.exportType & EXP_MESH_PROPERTY) != 0) { TSTR buffer; node->GetUserPropBuffer(buffer); wchar_t* unicodeString = new wchar_t[buffer.length() + 1]; mbstowcs(unicodeString, buffer.data(), buffer.length() + 1); rigidMesh->m_property = unicodeString; delete[] unicodeString; } return true; }