void SMDImporter::DetectModel() { XSI::Application app; m_pModel = app.GetActiveSceneRoot(); for (int c=0;c<m_pNodes.GetUsed();c++) { if ( !m_pNodes[c]->m_pChildren.GetUsed() ) continue; char name[MAX_PATH]; memset ( name,0,MAX_PATH); strcpy ( name, m_pNodes[c]->m_szName ); char * subname = strchr ( name, '.' ); if ( subname ) { subname[0] =0; subname++; LPWSTR l_wszModelName; DSA2W(&l_wszModelName,name); XSI::CRefArray models = m_pModel.GetModels(false); for (int m=0;m<models.GetCount();m++) { XSI::Model mm = models[m]; XSI::CString l_szName =l_wszModelName; if ( l_szName == mm.GetName() ) { m_pModel = mm; return; } } // // Create the model // XSI::Model rootModel; XSI::CRefArray nullList; m_pModel.AddModel(nullList, l_wszModelName, rootModel); m_pModel = rootModel; m_pModel.AddMixer(); break; } } }
void getAnimations(XSI::Model& root, Ogre::AnimationList& animList) { animList.clear(); findAnimations(root, animList); // Find all children (recursively) XSI::CRefArray children = root.FindChildren(L"", siModelType, XSI::CStringArray()); for (int c = 0; c < children.GetCount(); ++c) { XSI::Model child(children[c]); findAnimations(child, animList); } // Now iterate over the list and eliminate overlapping elements for (Ogre::AnimationList::iterator i = animList.begin(); i != animList.end(); ++i) { Ogre::AnimationList::iterator j = i; ++j; for (; j != animList.end();) { bool remove = false; if (j->startFrame <= i->endFrame && j->endFrame >= i->startFrame) { // Merge this one into i, extend boundaries remove = true; i->startFrame = std::min(j->startFrame, i->startFrame); i->endFrame = std::max(j->endFrame, i->endFrame); } if (remove) { j = animList.erase(j); } else { ++j; } } } }
XSI::Null DoesObjectExist ( XSI::X3DObject in_pModel, XSI::CString in_szName ) { XSI::Null theNull; XSI::CStringArray emptyArray; XSI::CRefArray cRefArray = in_pModel.FindChildren( L"", L"", emptyArray, true ); XSI::CStringArray nameArray(cRefArray.GetCount()); for ( long i=0; i < cRefArray.GetCount(); i++ ) { if ( in_szName == XSI::SIObject(cRefArray[i]).GetName() ) { theNull = cRefArray[i]; break; } } return theNull; }
SI_Error SMDEnvelope::Write ( FILE* l_fptr, int rigid, SMDNodeList* in_pNodeList ) { CSIBCVector3D* l_pPosition = NULL; CSIBCVector3D* l_pNormal = NULL; CSIBCVector2D* l_pUV = NULL; XSI::Primitive l_pPrim = m_pModel.GetActivePrimitive(); if ( !l_pPrim.IsValid() ) return SI_ERR_ERROR_MSG; XSI::Application app; XSI::UIToolkit kit = app.GetUIToolkit(); XSI::ProgressBar m_pBar = kit.GetProgressBar(); m_pBar.PutMaximum( 100 ); m_pBar.PutMinimum( 1 ); m_pBar.PutStep( 1 ); m_pBar.PutValue( 1 ); m_pBar.PutCaption( L"Writing vertex data..." ); m_pBar.PutStatusText( L"" ); m_pBar.PutVisible( true ); // // Get default texture name // char l_szDefaultTextureName[MAX_PATH]; XSI::OGLTexture l_pDefaultTexture = m_pModel.GetMaterial().GetOGLTexture(); if ( !l_pDefaultTexture.IsValid() ) { XSILogMessage ( "Material on enveloped mesh has no texture!", XSI::siErrorMsg ); sprintf ( l_szDefaultTextureName, "default.tga" ); } else { W2AHelper2 ( l_szDefaultTextureName, l_pDefaultTexture.GetFullName().GetWideString() ); char l_szTextureFile[MAX_PATH]; char l_szTextureExt[MAX_PATH]; _splitpath ( l_szDefaultTextureName, NULL, NULL, l_szTextureFile, l_szTextureExt ); sprintf ( l_szDefaultTextureName, "%s%s", l_szTextureFile, l_szTextureExt ); } XSI::Geometry l_pGeo = l_pPrim.GetGeometry(); XSI::CPointRefArray l_pPoints = l_pGeo.GetPoints(); XSI::PolygonMesh l_pPolyMesh = l_pGeo; XSI::CPointRefArray pointRefArray(l_pPolyMesh.GetPoints()); XSI::MATH::CVector3Array positionArray(pointRefArray.GetPositionArray()); XSI::CPolygonNodeRefArray nodeRefArray(l_pPolyMesh.GetNodes()); XSI::MATH::CVector3Array normalArray(nodeRefArray.GetNormalArray()); //Take care of the UV's XSI::CRefArray clusterRefArray; l_pPolyMesh.GetClusters().Filter(XSI::siSampledPointCluster,XSI::CStringArray(),L"",clusterRefArray); XSI::Cluster samplePointClusterUV; XSI::CRefArray uvClusterPropertiesRefArray; int i; for(i=0;i < clusterRefArray.GetCount(); i++) { XSI::Cluster cluster(clusterRefArray[i]); if(cluster.GetProperties().Filter(XSI::siClsUVSpaceTxtType,XSI::CStringArray(), L"",uvClusterPropertiesRefArray) == XSI::CStatus::OK) { samplePointClusterUV = cluster; break; } } XSI::ClusterProperty uvProp(uvClusterPropertiesRefArray[0]); XSI::CClusterPropertyElementArray uvElementArray = uvProp.GetElements(); XSI::CDoubleArray uvValueArray = uvElementArray.GetArray(); long lnbUV= (long)(uvValueArray.GetCount() / 3); // // Make sure that UVs are present // if ( !samplePointClusterUV.IsValid() ) { XSILogMessage ( "Invalid .SMD: Enveloped mesh doesn't have any UVs.", XSI::siErrorMsg ); return SI_ERR_ERROR_MSG; } m_pBar.PutCaption( L"Analyzing clusters..." ); m_pBar.PutStatusText( L"" ); m_pBar.PutVisible( true ); SMDNode* in_pNode = in_pNodeList->GetByName ( m_pModel.GetFullName() ); CSIBCArray < CSIBCVector3D > l_pVertexNormals; ComputeVertexNormals ( l_pVertexNormals, l_pGeo ); XSI::CRefArray allClusters; l_pPolyMesh.GetClusters().Filter(L"poly",XSI::CStringArray(),L"",allClusters); CSIBCArray<MateriaList> matList; for (int c=0;c<allClusters.GetCount();c++) { XSI::Cluster Thecluster = allClusters[c]; XSI::Material l_pMat = Thecluster.GetMaterial(); XSI::OGLTexture l_pTexture = l_pMat.GetOGLTexture(); matList.Extend(1); if ( !l_pTexture.IsValid() ) { char mess[1024]; sprintf ( mess, "Cluster #%d has no texture! Bypassing.", c); XSILogMessage ( mess, XSI::siErrorMsg ); continue; } W2AHelper2 ( matList[matList.GetUsed()-1].texture, l_pTexture.GetFullName().GetWideString() ); char l_szTextureFile[MAX_PATH]; char l_szTextureExt[MAX_PATH]; _splitpath ( matList[matList.GetUsed()-1].texture, NULL, NULL, l_szTextureFile, l_szTextureExt ); sprintf ( matList[matList.GetUsed()-1].texture, "%s%s", l_szTextureFile, l_szTextureExt ); XSI::CClusterElementArray clusterElementArray = Thecluster.GetElements(); XSI::CLongArray values(clusterElementArray.GetArray()); long countPolyIndices = values.GetCount(); matList[matList.GetUsed()-1].polyIndices.Extend(countPolyIndices); for (int v=0;v<countPolyIndices;v++) { matList[matList.GetUsed()-1].polyIndices[v] = values[v]; } } XSI::CTriangleRefArray tris = l_pPolyMesh.GetTriangles(); m_pBar.PutCaption( L"Processing geometry..." ); m_pBar.PutStatusText( L"" ); m_pBar.PutVisible( true ); long progress_value = 0; long last_progress_value = 0; int vindex = 0; int vii = 0; for (int v=0;v<tris.GetCount();v++) { progress_value = (long)(((float)v / (float)tris.GetCount()) * 100.0f); if ( progress_value != last_progress_value ) { last_progress_value = progress_value; m_pBar.PutValue ( progress_value ); if ( m_pBar.IsCancelPressed() ) { if ( MessageBox ( NULL, "Cancelling the export will create a corrupted SMD file.\n\n Are you sure?", "Cancel Export", MB_YESNO|MB_ICONWARNING ) == IDYES ) { break; } else { m_pBar.PutVisible( true ); } } } XSI::Triangle tri = tris[v]; char* textureName = l_szDefaultTextureName; long polyI = tri.GetPolygonIndex(); for (int p=0;p<matList.GetUsed();p++) { bool found = false; for (int h=0;h<matList[p].polyIndices.GetUsed();h++) { if ( matList[p].polyIndices[h] == polyI ) { textureName = matList[p].texture; found = true; break; } } if ( found ) break; } for (int i=0;i<3;i++) { // // Build a vertex // CSIBCVector3D l_vPosition = CSIBCVector3D( (float)tri.GetPositionArray()[i].GetX(), (float)tri.GetPositionArray()[i].GetY(), (float)tri.GetPositionArray()[i].GetZ() ); XSI::CTriangleVertexRefArray vRef = tri.GetPoints(); XSI::TriangleVertex l_vTriangleVertex = vRef[i]; CSIBCVector3D l_vNormal = CSIBCVector3D ( (float)l_vTriangleVertex.GetNormal().GetX(), (float)l_vTriangleVertex.GetNormal().GetY(), (float)l_vTriangleVertex.GetNormal().GetZ() ); //if ( SMDType == 1 ) //{ // l_vNormal = l_pVertexNormals [ l_pVertexList[vii] ]; //} if (( SMDType == 0 ) || ( SMDType == 1 )) { CSIBCMatrix4x4 l_pResult = in_pNode->GetMatrix(); l_pResult.Multiply ( l_vPosition, l_vPosition ); l_pResult.Multiply ( l_vNormal, l_vNormal ); l_vNormal = l_vNormal.Normalize(); } XSI::CTriangleVertexRefArray l_TriRef = tri.GetPoints(); XSI::CUVArray l_vuvArray = l_TriRef.GetUVArray(); XSI::CUV l_uv = l_vuvArray[i]; int c = l_vuvArray.GetCount(); long vertexIndex = tri.GetIndexArray()[i]; CSIBCVector2D l_vUV; l_vUV.m_fX = (float)l_uv.u; l_vUV.m_fY = (float)l_uv.v; // // Build weight list // SMDVertex* l_pWeights = m_pVertexList[vertexIndex]; // not sure the line above works correclty, if not, uncomment // the code below //for (int w=0;w<m_pVertexList.GetUsed();w++) //{ // if ( m_pVertexList[w]->GetIndex() == vertexIndex ) // { // l_pWeights = m_pVertexList[w]; // break; // // } //} vii++; // // Now output // // XSI::OGLTexture l_pTexture = useMat.GetOGLTexture(); if ( vindex == 0 ) { fprintf ( l_fptr, "%s\n", textureName ); } if ( !rigid ) { CSIBCString l_szWeight; l_szWeight.Concat ( l_pWeights->GetNumWeights() ); l_szWeight.Concat (" "); for (int f=0;f<l_pWeights->GetNumWeights();f++) { l_szWeight.Concat ( l_pWeights->GetWeight(f)->m_iBoneID ); l_szWeight.Concat (" "); l_szWeight.Concat ( l_pWeights->GetWeight(f)->m_fWeight ); l_szWeight.Concat (" "); } fprintf ( l_fptr, "0 %f %f %f %f %f %f %f %f %s\n", l_vPosition.m_fX, l_vPosition.m_fY, l_vPosition.m_fZ, l_vNormal.m_fX, l_vNormal.m_fY, l_vNormal.m_fZ, l_vUV.m_fX, l_vUV.m_fY, l_szWeight.GetText()); } else { fprintf ( l_fptr, "%d %f %f %f %f %f %f %f %f \n", l_pWeights->GetWeight(0)->m_iBoneID, l_vPosition.m_fX, l_vPosition.m_fY, l_vPosition.m_fZ, l_vNormal.m_fX, l_vNormal.m_fY, l_vNormal.m_fZ, l_vUV.m_fX, l_vUV.m_fY ); } vindex++; if ( vindex == 3 ) vindex = 0; } } return SI_SUCCESS; }