bool FillGeometryLibrary(FULogFile& fileOut, FCDGeometryLibrary* library) { FCDGeometry* geometry = library->AddEntity(); PassIf(geometry->GetType() == FCDEntity::GEOMETRY); FailIf(geometry->IsMesh()); FailIf(geometry->IsSpline()); meshId = geometry->GetDaeId(); FailIf(meshId.empty()); // Creates a mesh to export FCDGeometryMesh* mesh = geometry->CreateMesh(); FailIf(geometry->IsSpline()); PassIf(geometry->IsMesh()); PassIf(geometry->GetMesh() == mesh); PassIf(geometry->GetSpline() == NULL); FillGeometryMesh(fileOut, mesh); // Create a spline to export geometry = library->AddEntity(); geometry->CreateMesh(); FCDGeometrySpline* spline = geometry->CreateSpline(); PassIf(geometry->IsSpline()); FailIf(geometry->IsMesh()); PassIf(geometry->GetMesh() == NULL); PassIf(geometry->GetSpline() == spline); FillGeometrySpline(fileOut, spline); splineId = geometry->GetDaeId(); FailIf(splineId.empty()); return true; }
bool FArchiveXML::LoadGeometryInstance(FCDObject* object, xmlNode* instanceNode) { if (!FArchiveXML::LoadEntityInstance(object, instanceNode)) return false; bool status = true; FCDGeometryInstance* geometryInstance = (FCDGeometryInstance*)object; // Look for the <bind_material> element. The others are discarded for now. xmlNode* bindMaterialNode = FindChildByType(instanceNode, DAE_BINDMATERIAL_ELEMENT); if (bindMaterialNode != NULL) { for (xmlNode* child = bindMaterialNode->children; child != NULL; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; if (IsEquivalent(child->name, DAE_PARAMETER_ELEMENT)) { FCDEffectParameter* parameter = geometryInstance->AddEffectParameter(FArchiveXML::GetEffectParameterType(child)); parameter->SetAnimator(); status &= FArchiveXML::LoadSwitch(parameter, ¶meter->GetObjectType(), child); } } // Retrieve the list of the <technique_common><instance_material> elements. xmlNode* techniqueNode = FindChildByType(bindMaterialNode, DAE_TECHNIQUE_COMMON_ELEMENT); xmlNodeList materialNodes; FindChildrenByType(techniqueNode, DAE_INSTANCE_MATERIAL_ELEMENT, materialNodes); for (xmlNodeList::iterator itM = materialNodes.begin(); itM != materialNodes.end(); ++itM) { FCDMaterialInstance* material = geometryInstance->AddMaterialInstance(); status &= (FArchiveXML::LoadMaterialInstance(material, *itM)); } } else { // Blinding attempt to use the material semantic from the polygons as a material id. FCDGeometry* geometry = (FCDGeometry*) geometryInstance->GetEntity(); if (geometry != NULL && geometry->HasType(FCDGeometry::GetClassType()) && geometry->IsMesh()) { FCDGeometryMesh* mesh = geometry->GetMesh(); size_t polyCount = mesh->GetPolygonsCount(); for (size_t i = 0; i < polyCount; ++i) { FCDGeometryPolygons* polys = mesh->GetPolygons(i); const fstring& semantic = polys->GetMaterialSemantic(); fm::string semanticUTF8 = TO_STRING(semantic); semanticUTF8 = FCDObjectWithId::CleanId(semanticUTF8.c_str()); FCDMaterial* material = geometry->GetDocument()->FindMaterial(semanticUTF8); if (material != NULL) { geometryInstance->AddMaterialInstance(material, polys); } } } } geometryInstance->SetDirtyFlag(); return status; }
bool CheckGeometryLibrary(FULogFile& fileOut, FCDGeometryLibrary* library) { PassIf(library->GetEntityCount() == 2); // Find the one mesh and the one spline geometries. FCDGeometryMesh* mesh = NULL; FCDGeometrySpline* spline = NULL; for (size_t i = 0; i < 2; ++i) { FCDGeometry* g = library->GetEntity(i); if (g->IsMesh()) mesh = g->GetMesh(); else if (g->IsSpline()) spline = g->GetSpline(); else Fail; } FailIf(mesh == NULL || spline == NULL); CheckGeometryMesh(fileOut, mesh); CheckGeometrySpline(fileOut, spline); return true; }
float FCDPhysicsShape::CalculateVolume() const { if (IsGeometryInstance()) { FCDGeometry* geom = ((FCDGeometry*)geometry->GetEntity()); if (geom->IsMesh()) { FUBoundingBox boundary; float countingVolume = 0.0f; const FCDGeometryMesh* mesh = geom->GetMesh(); if (!mesh->GetConvexHullOf().empty()) { mesh = mesh->FindConvexHullOfMesh(); } if (mesh == NULL) return 1.0f; // missing convex hull or of spline for (size_t i = 0; i < mesh->GetPolygonsCount(); i++) { const FCDGeometryPolygons* polygons = mesh->GetPolygons(i); const FCDGeometryPolygonsInput* positionInput = polygons->FindInput(FUDaeGeometryInput::POSITION); const FCDGeometrySource* positionSource = positionInput->GetSource(); uint32 positionStride = positionSource->GetStride(); FUAssert(positionStride == 3, continue;); const float* positionData = positionSource->GetData(); size_t positionDataLength = positionSource->GetDataCount(); for (size_t pos = 0; pos < positionDataLength;) { boundary.Include(FMVector3(positionData, (uint32)pos)); pos += positionStride; } FMVector3 min = boundary.GetMin(); FMVector3 max = boundary.GetMax(); countingVolume += (max.x - min.x) * (max.y - min.y) * (max.z - min.z); boundary.Reset(); } return countingVolume; }
bool CModelConverter::ReadDAE(const tstring& sFilename) { if (m_pWorkListener) m_pWorkListener->BeginProgress(); FCollada::Initialize(); FCDocument* pDoc = FCollada::NewTopDocument(); if (m_pWorkListener) m_pWorkListener->SetAction("Reading file", 0); if (FCollada::LoadDocumentFromFile(pDoc, convert_to_fstring(sFilename))) { size_t i; FCDocumentTools::StandardizeUpAxisAndLength(pDoc, FMVector3(0, 1, 0)); FCDMaterialLibrary* pMatLib = pDoc->GetMaterialLibrary(); size_t iEntities = pMatLib->GetEntityCount(); if (m_pWorkListener) m_pWorkListener->SetAction("Reading materials", iEntities); for (i = 0; i < iEntities; ++i) { FCDMaterial* pColladaMaterial = pMatLib->GetEntity(i); FCDEffect* pEffect = pColladaMaterial->GetEffect(); size_t iMaterial = m_pScene->AddMaterial(convert_from_fstring(pColladaMaterial->GetName())); CConversionMaterial* pMaterial = m_pScene->GetMaterial(iMaterial); if (pEffect->GetProfileCount() < 1) continue; FCDEffectProfile* pEffectProfile = pEffect->GetProfile(0); FUDaeProfileType::Type eProfileType = pEffectProfile->GetType(); if (eProfileType == FUDaeProfileType::COMMON) { FCDEffectStandard* pStandardProfile = dynamic_cast<FCDEffectStandard*>(pEffectProfile); if (pStandardProfile) { pMaterial->m_vecAmbient = Vector((float*)pStandardProfile->GetAmbientColor()); pMaterial->m_vecDiffuse = Vector((float*)pStandardProfile->GetDiffuseColor()); pMaterial->m_vecSpecular = Vector((float*)pStandardProfile->GetSpecularColor()); pMaterial->m_vecEmissive = Vector((float*)pStandardProfile->GetEmissionColor()); pMaterial->m_flShininess = pStandardProfile->GetShininess(); } } for (size_t j = 0; j < pEffectProfile->GetEffectParameterCount(); j++) { FCDEffectParameter* pEffectParameter = pEffectProfile->GetEffectParameter(j); FCDEffectParameter::Type eType = pEffectParameter->GetType(); if (eType == FCDEffectParameter::SAMPLER) { FCDEffectParameterSampler* pSampler = dynamic_cast<FCDEffectParameterSampler*>(pEffectParameter); if (pSampler) { FCDEffectParameterSurface* pSurface = pSampler->GetSurface(); if (pSurface) { if (pSurface->GetImageCount()) { // Christ Collada why do you have to make things so damn complicated? FCDImage* pImage = pSurface->GetImage(0); pMaterial->m_sDiffuseTexture = convert_from_fstring(pImage->GetFilename()); // Fix up a bug in the Max Collada exporter if (pMaterial->m_sDiffuseTexture.startswith("\\\\C\\")) pMaterial->m_sDiffuseTexture = "C:\\" + pMaterial->m_sDiffuseTexture.substr(4); else if (pMaterial->m_sDiffuseTexture.startswith("\\\\D\\")) pMaterial->m_sDiffuseTexture = "D:\\" + pMaterial->m_sDiffuseTexture.substr(4); } } } } } if (m_pWorkListener) m_pWorkListener->WorkProgress(i+1); } FCDGeometryLibrary* pGeoLib = pDoc->GetGeometryLibrary(); iEntities = pGeoLib->GetEntityCount(); if (m_pWorkListener) m_pWorkListener->SetAction("Loading entities", iEntities); for (i = 0; i < iEntities; ++i) { FCDGeometry* pGeometry = pGeoLib->GetEntity(i); if (pGeometry->IsMesh()) { size_t j; size_t iMesh = m_pScene->AddMesh(convert_from_fstring(pGeometry->GetName())); CConversionMesh* pMesh = m_pScene->GetMesh(iMesh); pMesh->AddBone(convert_from_fstring(pGeometry->GetName())); FCDGeometryMesh* pGeoMesh = pGeometry->GetMesh(); FCDGeometrySource* pPositionSource = pGeoMesh->GetPositionSource(); size_t iVertexCount = pPositionSource->GetValueCount(); for (j = 0; j < iVertexCount; j++) { const float* pflValues = pPositionSource->GetValue(j); pMesh->AddVertex(pflValues[0], pflValues[1], pflValues[2]); } FCDGeometrySource* pNormalSource = pGeoMesh->FindSourceByType(FUDaeGeometryInput::NORMAL); if (pNormalSource) { iVertexCount = pNormalSource->GetValueCount(); for (j = 0; j < iVertexCount; j++) { const float* pflValues = pNormalSource->GetValue(j); pMesh->AddNormal(pflValues[0], pflValues[1], pflValues[2]); } } FCDGeometrySource* pUVSource = pGeoMesh->FindSourceByType(FUDaeGeometryInput::TEXCOORD); if (pUVSource) { iVertexCount = pUVSource->GetValueCount(); for (j = 0; j < iVertexCount; j++) { const float* pflValues = pUVSource->GetValue(j); pMesh->AddUV(pflValues[0], pflValues[1]); } } for (j = 0; j < pGeoMesh->GetPolygonsCount(); j++) { FCDGeometryPolygons* pPolygons = pGeoMesh->GetPolygons(j); FCDGeometryPolygonsInput* pPositionInput = pPolygons->FindInput(FUDaeGeometryInput::POSITION); FCDGeometryPolygonsInput* pNormalInput = pPolygons->FindInput(FUDaeGeometryInput::NORMAL); FCDGeometryPolygonsInput* pUVInput = pPolygons->FindInput(FUDaeGeometryInput::TEXCOORD); size_t iPositionCount = pPositionInput->GetIndexCount(); uint32* pPositions = pPositionInput->GetIndices(); size_t iNormalCount = 0; uint32* pNormals = NULL; if (pNormalInput) { iNormalCount = pNormalInput->GetIndexCount(); pNormals = pNormalInput->GetIndices(); } size_t iUVCount = 0; uint32* pUVs = NULL; if (pUVInput) { iUVCount = pUVInput->GetIndexCount(); pUVs = pUVInput->GetIndices(); } fm::stringT<fchar> sMaterial = pPolygons->GetMaterialSemantic(); size_t iCurrentMaterial = pMesh->AddMaterialStub(convert_from_fstring(sMaterial)); if (pPolygons->TestPolyType() == 3) { // All triangles! for (size_t k = 0; k < iPositionCount; k+=3) { size_t iFace = pMesh->AddFace(iCurrentMaterial); pMesh->AddVertexToFace(iFace, pPositions[k+0], pUVs?pUVs[k+0]:~0, pNormals?pNormals[k+0]:~0); pMesh->AddVertexToFace(iFace, pPositions[k+1], pUVs?pUVs[k+1]:~0, pNormals?pNormals[k+1]:~0); pMesh->AddVertexToFace(iFace, pPositions[k+2], pUVs?pUVs[k+2]:~0, pNormals?pNormals[k+2]:~0); } } else if (pPolygons->TestPolyType() == 4) { // All quads! for (size_t k = 0; k < iPositionCount; k+=4) { size_t iFace = pMesh->AddFace(iCurrentMaterial); pMesh->AddVertexToFace(iFace, pPositions[k+0], pUVs?pUVs[k+0]:~0, pNormals?pNormals[k+0]:~0); pMesh->AddVertexToFace(iFace, pPositions[k+1], pUVs?pUVs[k+1]:~0, pNormals?pNormals[k+1]:~0); pMesh->AddVertexToFace(iFace, pPositions[k+2], pUVs?pUVs[k+2]:~0, pNormals?pNormals[k+2]:~0); pMesh->AddVertexToFace(iFace, pPositions[k+3], pUVs?pUVs[k+3]:~0, pNormals?pNormals[k+3]:~0); } } else { size_t iFaces = pPolygons->GetFaceCount(); for (size_t k = 0; k < iFaces; k++) { size_t iFace = pMesh->AddFace(iCurrentMaterial); size_t o = pPolygons->GetFaceVertexOffset(k); size_t iFaceVertexCount = pPolygons->GetFaceVertexCount(k); for (size_t v = 0; v < iFaceVertexCount; v++) pMesh->AddVertexToFace(iFace, pPositions[o+v], pUVs?pUVs[o+v]:~0, pNormals?pNormals[o+v]:~0); } } } } if (m_pWorkListener) m_pWorkListener->WorkProgress(i+1); } FCDVisualSceneNodeLibrary* pVisualScenes = pDoc->GetVisualSceneLibrary(); iEntities = pVisualScenes->GetEntityCount(); for (i = 0; i < iEntities; ++i) { FCDSceneNode* pNode = pVisualScenes->GetEntity(i); size_t iScene = m_pScene->AddScene(convert_from_fstring(pNode->GetName())); ReadDAESceneTree(pNode, m_pScene->GetScene(iScene)); } } else { printf("Oops! Some kind of error happened!\n"); return false; } m_pScene->SetWorkListener(m_pWorkListener); m_pScene->CalculateExtends(); for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++) { if (m_bWantEdges) m_pScene->GetMesh(i)->CalculateEdgeData(); if (m_pScene->GetMesh(i)->GetNumNormals() == 0) m_pScene->GetMesh(i)->CalculateVertexNormals(); m_pScene->GetMesh(i)->CalculateVertexTangents(); } pDoc->Release(); FCollada::Release(); if (m_pWorkListener) m_pWorkListener->EndProgress(); return true; }