/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* * Copyright (C) 2006-2010 - Frictional Games * * This file is part of HPL1 Engine. */ #include "hpl1/engine/impl/MeshLoaderCollada.h" #include "hpl1/engine/graphics/LowLevelGraphics.h" #include "hpl1/engine/graphics/VertexBuffer.h" #include "hpl1/engine/system/String.h" #include "hpl1/engine/system/System.h" #include "hpl1/engine/system/low_level_system.h" #include "hpl1/engine/graphics/Material.h" #include "hpl1/engine/graphics/Mesh.h" #include "hpl1/engine/graphics/SubMesh.h" #include "hpl1/engine/resources/MaterialManager.h" #include "hpl1/engine/graphics/Animation.h" #include "hpl1/engine/graphics/AnimationTrack.h" #include "hpl1/engine/graphics/Bone.h" #include "hpl1/engine/graphics/Skeleton.h" #include "hpl1/engine/impl/tinyXML/tinyxml.h" #include "hpl1/engine/math/Math.h" namespace hpl { //------------------------------------------------------------------------ ////////////////////////////////////////////////////////////////////////// // FILL STRUCTURES ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- bool cMeshLoaderCollada::FillStructures(const tString &asFile, tColladaImageVec *apColladaImageVec, tColladaTextureVec *apColladaTextureVec, tColladaMaterialVec *apColladaMaterialVec, tColladaLightVec *apColladaLightVec, tColladaGeometryVec *apColladaGeometryVec, tColladaControllerVec *apColladaControllerVec, tColladaAnimationVec *apColladaAnimVec, cColladaScene *apColladaScene, bool abCache) { abCache = false; // FIXME: find a way to enable the use of cache files bool bLoadCache = false; // abCache = false; // Log("Loading %s\n",asFile.c_str()); tString sCacheFile = cString::GetFileName(cString::SetFileExt(asFile, "collcach")); sCacheFile = "core/cache/" + sCacheFile; if (abCache && FileExists(cString::To16Char(sCacheFile)) && FileExists(cString::To16Char(asFile))) { cDate colladaDate = FileModifiedDate(cString::To16Char(asFile)); cDate cacheDate = FileModifiedDate(cString::To16Char(sCacheFile)); // Check if cache is newer if (cacheDate > colladaDate) bLoadCache = true; } ///////////////////////////////////////////////// // LOAD CACHE if (bLoadCache) { return LoadStructures(sCacheFile, apColladaImageVec, apColladaTextureVec, apColladaMaterialVec, apColladaLightVec, apColladaGeometryVec, apColladaControllerVec, apColladaAnimVec, apColladaScene); } else if (abCache) { Log("Cache out of date! Reloading collada file '%s'\n and generating cache files", asFile.c_str()); } ///////////////////////////////////////////////// // LOAD THE DOCUMENT // unsigned long lStartTime = mpSystem->GetLowLevel()->GetTime(); TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (asFile.c_str())); if (pXmlDoc->LoadFile() == false) { Error("Couldn't load Collada XML file '%s'!\n", asFile.c_str()); hplDelete(pXmlDoc); return false; } // unsigned long lTime = mpSystem->GetLowLevel()->GetTime() - lStartTime; // Log("Loading collada XML file for '%s' took: %d ms\n",asFile.c_str(),lTime); // Get the root. TiXmlElement *pRootElem = pXmlDoc->RootElement(); ///////////////////////////////////////////////// // FIRST SETUP // Set up axis as Y. mbZToY = false; // Load assets element. TiXmlElement *pAssetElem = pRootElem->FirstChildElement("asset"); if (pAssetElem) { TiXmlElement *pUpAxisElem = pAssetElem->FirstChildElement("up_axis"); if (pUpAxisElem) { TiXmlText *pAxisText = pUpAxisElem->FirstChild()->ToText(); if (tString(pAxisText->Value()) == "Z_UP") { mbZToY = true; // Log("!!!!!!!Z IS UP!!!!!!"); } } } else { Error("Couldn't find asset element!\n"); } ///////////////////////////////////////////////// // ITERATE THE LIBRARIES BEFORE SCENE LIBRARIES TiXmlElement *pLibraryElem = pRootElem->FirstChildElement(); while (pLibraryElem) { tString sType = cString::ToString(pLibraryElem->Attribute("type"), ""); tString sValue = cString::ToString(pLibraryElem->Value(), ""); // Lights if ((sType == "LIGHT" || sValue == "library_lights") && apColladaLightVec) { /// Log("Loading type: %s\n",sType.c_str()); LoadLights(pLibraryElem, *apColladaLightVec); // Log(" --- \n"); } pLibraryElem = pLibraryElem->NextSiblingElement(); } ////////////////////////////////////////////// // LOAD SCENE if (apColladaScene) { TiXmlElement *pSceneElem = pRootElem->FirstChildElement("library_visual_scenes"); if (pSceneElem) { pSceneElem = pSceneElem->FirstChildElement("visual_scene"); if (pSceneElem == NULL) Warning("No visual scene element found!\n"); } if (pSceneElem == NULL) pSceneElem = pRootElem->FirstChildElement("scene"); if (pSceneElem == NULL) { Warning("No scene element found!\n"); } else { // Get start and end time (MAYA ONLY!) TiXmlElement *pExtraElem = pSceneElem->FirstChildElement("extra"); if (pExtraElem) { // Get techniques TiXmlElement *pExtraTechElem = pExtraElem->FirstChildElement("technique"); for (; pExtraTechElem; pExtraTechElem = pExtraTechElem->NextSiblingElement("technique")) { // Check for maya profile tString sProfile = cString::ToString(pExtraTechElem->Attribute("profile"), ""); if (sProfile == "MAYA") { // Iterate params TiXmlElement *pParam = pExtraTechElem->FirstChildElement(); for (; pParam; pParam = pParam->NextSiblingElement()) { tString sName = cString::ToString(pParam->Attribute("name"), ""); if (sName == "") { sName = cString::ToString(pParam->Value(), ""); } sName = cString::ToLowerCase(sName); TiXmlText *pText = pParam->FirstChild()->ToText(); float fValue = cString::ToFloat(pText->Value(), 0); if (sName == "start_time") apColladaScene->mfStartTime = fValue; else if (sName == "end_time") apColladaScene->mfEndTime = fValue; } } apColladaScene->mfDeltaTime = apColladaScene->mfEndTime - apColladaScene->mfStartTime; } // Log("Anim Start: %f End: %f\n",apColladaScene->mfStartTime, apColladaScene->mfEndTime); } else { Warning("No 'extra scene' element found!\n"); } // Load all nodes in the scene. TiXmlElement *pNodeElem = pSceneElem->FirstChildElement("node"); while (pNodeElem) { LoadColladaScene(pNodeElem, &apColladaScene->mRoot, apColladaScene, apColladaLightVec); pNodeElem = pNodeElem->NextSiblingElement("node"); } } } ///////////////////////////////////////////////// // ITERATE THE AFTER SCENE LIBRARIES pLibraryElem = pRootElem->FirstChildElement(); while (pLibraryElem) { tString sType = cString::ToString(pLibraryElem->Attribute("type"), ""); tString sValue = cString::ToString(pLibraryElem->Value(), ""); // Image if ((sType == "IMAGE" || sValue == "library_images") && apColladaImageVec) { // Loads all images files available LoadImages(pLibraryElem, *apColladaImageVec); } // Texture else if ((sType == "TEXTURE" || sValue == "library_effects") && apColladaTextureVec) { // Loads all texture and their settings LoadTextures(pLibraryElem, *apColladaTextureVec); } // Material else if ((sType == "MATERIAL" || sValue == "library_materials") && apColladaMaterialVec) { // All materials used are loaded LoadMaterials(pLibraryElem, *apColladaMaterialVec); } // Geometry else if ((sType == "GEOMETRY" || sValue == "library_geometries") && apColladaGeometryVec) { // geometry for all objects in the scene are loaded. LoadGeometry(pLibraryElem, *apColladaGeometryVec, apColladaScene); } // Animation else if ((sType == "ANIMATION" || sValue == "library_animations") && apColladaScene && apColladaAnimVec) { LoadAnimations(pLibraryElem, *apColladaAnimVec, apColladaScene); } // Controller else if ((sType == "CONTROLLER" || sValue == "library_controllers") && apColladaGeometryVec && apColladaControllerVec) { LoadControllers(pLibraryElem, *apColladaControllerVec, apColladaGeometryVec); } // Log(" ---- \n",sType.c_str()); pLibraryElem = pLibraryElem->NextSiblingElement(); } if (abCache) { SaveStructures(sCacheFile, apColladaImageVec, apColladaTextureVec, apColladaMaterialVec, apColladaLightVec, apColladaGeometryVec, apColladaControllerVec, apColladaAnimVec, apColladaScene); } hplDelete(pXmlDoc); return true; } //-------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // SAVE COLLADA DATA ////////////////////////////////////////////////////////////////////////// #define CreateXMLChild(parent, name) static_cast(parent->InsertEndChild(TiXmlElement(name))); #define CreateXMLTextChild(parent, name) static_cast(parent->InsertEndChild(TiXmlText(name))); //----------------------------------------------------------------------- static void SaveImageVec(TiXmlElement *apRootElem, tColladaImageVec *apColladaImageVec); static void SaveTextureVec(TiXmlElement *apRootElem, tColladaTextureVec *apColladaTextureVec); static void SaveMaterialVec(TiXmlElement *apRootElem, tColladaMaterialVec *apColladaMaterialVec); static void SaveLightVec(TiXmlElement *apRootElem, tColladaLightVec *apColladaLightVec); static void SaveAnimationVec(TiXmlElement *apRootElem, tColladaAnimationVec *apColladaAnimationVec); static void SaveControllerVec(TiXmlElement *apRootElem, tColladaControllerVec *apColladaControllerVec); static void SaveGeometryVec(TiXmlElement *apRootElem, tColladaGeometryVec *apColladaGeometryVec); static void SaveScene(TiXmlElement *apRootElem, cColladaScene *apColladaScene); bool cMeshLoaderCollada::SaveStructures(const tString &asFile, tColladaImageVec *apColladaImageVec, tColladaTextureVec *apColladaTextureVec, tColladaMaterialVec *apColladaMaterialVec, tColladaLightVec *apColladaLightVec, tColladaGeometryVec *apColladaGeometryVec, tColladaControllerVec *apColladaControllerVec, tColladaAnimationVec *apColladaAnimVec, cColladaScene *apColladaScene) { TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (asFile.c_str())); TiXmlElement *pRootElem = CreateXMLChild(pXmlDoc, "ColladaCache"); if (apColladaImageVec) SaveImageVec(pRootElem, apColladaImageVec); if (apColladaTextureVec) SaveTextureVec(pRootElem, apColladaTextureVec); if (apColladaMaterialVec) SaveMaterialVec(pRootElem, apColladaMaterialVec); if (apColladaLightVec) SaveLightVec(pRootElem, apColladaLightVec); if (apColladaAnimVec) SaveAnimationVec(pRootElem, apColladaAnimVec); if (apColladaControllerVec) SaveControllerVec(pRootElem, apColladaControllerVec); if (apColladaGeometryVec) SaveGeometryVec(pRootElem, apColladaGeometryVec); if (apColladaScene) SaveScene(pRootElem, apColladaScene); if (pXmlDoc->SaveFile() == false) { Error("Couldn't save XML file %s\n", asFile.c_str()); hplDelete(pXmlDoc); return false; } hplDelete(pXmlDoc); return true; } //----------------------------------------------------------------------- static void SaveImageVec(TiXmlElement *apRootElem, tColladaImageVec *apColladaImageVec) { TiXmlElement *pImageRootElem = CreateXMLChild(apRootElem, "ImageRoot"); pImageRootElem->SetAttribute("Size", (int)apColladaImageVec->size()); for (size_t i = 0; i < apColladaImageVec->size(); ++i) { cColladaImage *pImage = &(*apColladaImageVec)[i]; TiXmlElement *pImageElem = CreateXMLChild(pImageRootElem, "Image"); pImageElem->SetAttribute("Id", pImage->msId.c_str()); pImageElem->SetAttribute("Name", pImage->msName.c_str()); pImageElem->SetAttribute("Source", cString::GetFileName(pImage->msSource.c_str()).c_str()); } } //----------------------------------------------------------------------- static void SaveTextureVec(TiXmlElement *apRootElem, tColladaTextureVec *apColladaTextureVec) { TiXmlElement *pTextureRootElem = CreateXMLChild(apRootElem, "TextureRoot"); pTextureRootElem->SetAttribute("Size", (int)apColladaTextureVec->size()); for (size_t i = 0; i < apColladaTextureVec->size(); ++i) { cColladaTexture *pTexture = &(*apColladaTextureVec)[i]; TiXmlElement *pTextureElem = CreateXMLChild(pTextureRootElem, "Texture"); pTextureElem->SetAttribute("Id", pTexture->msId.c_str()); pTextureElem->SetAttribute("Name", pTexture->msName.c_str()); pTextureElem->SetAttribute("Image", pTexture->msImage.c_str()); } } //----------------------------------------------------------------------- static void SaveMaterialVec(TiXmlElement *apRootElem, tColladaMaterialVec *apColladaMaterialVec) { TiXmlElement *pMaterialRootElem = CreateXMLChild(apRootElem, "MaterialRoot"); pMaterialRootElem->SetAttribute("Size", (int)apColladaMaterialVec->size()); for (size_t i = 0; i < apColladaMaterialVec->size(); ++i) { cColladaMaterial *pMaterial = &(*apColladaMaterialVec)[i]; TiXmlElement *pMaterialElem = CreateXMLChild(pMaterialRootElem, "Material"); pMaterialElem->SetAttribute("Id", pMaterial->msId.c_str()); pMaterialElem->SetAttribute("Name", pMaterial->msName.c_str()); pMaterialElem->SetAttribute("Texture", pMaterial->msTexture.c_str()); pMaterialElem->SetAttribute("Color", pMaterial->mDiffuseColor.ToFileString().c_str()); } } //----------------------------------------------------------------------- static void SaveLightVec(TiXmlElement *apRootElem, tColladaLightVec *apColladaLightVec) { TiXmlElement *pLightRootElem = CreateXMLChild(apRootElem, "LightRoot"); pLightRootElem->SetAttribute("Size", (int)apColladaLightVec->size()); for (size_t i = 0; i < apColladaLightVec->size(); ++i) { cColladaLight *pLight = &(*apColladaLightVec)[i]; TiXmlElement *pLightElem = CreateXMLChild(pLightRootElem, "Light"); // Log("Light %s\n",pLight->msName.c_str()); pLightElem->SetAttribute("Id", pLight->msId.c_str()); pLightElem->SetAttribute("Name", pLight->msName.c_str()); pLightElem->SetAttribute("Type", pLight->msType.c_str()); pLightElem->SetAttribute("Angle", cString::ToString(pLight->mfAngle).c_str()); pLightElem->SetAttribute("Color", pLight->mDiffuseColor.ToFileString().c_str()); } } //----------------------------------------------------------------------- static void SaveAnimationVec(TiXmlElement *apRootElem, tColladaAnimationVec *apColladaAnimationVec) { TiXmlElement *pAnimationRootElem = CreateXMLChild(apRootElem, "AnimationRoot"); pAnimationRootElem->SetAttribute("Size", (int)apColladaAnimationVec->size()); for (size_t i = 0; i < apColladaAnimationVec->size(); ++i) { cColladaAnimation *pAnimation = &(*apColladaAnimationVec)[i]; TiXmlElement *pAnimationElem = CreateXMLChild(pAnimationRootElem, "Animation"); pAnimationElem->SetAttribute("Id", pAnimation->msId.c_str()); pAnimationElem->SetAttribute("TargetNode", pAnimation->msTargetNode.c_str()); ///////////////////////////////////// // Channels { TiXmlElement *pChannelVecElem = CreateXMLChild(pAnimationElem, "ChannelVec"); pChannelVecElem->SetAttribute("Size", (int)pAnimation->mvChannels.size()); for (size_t idx = 0; idx < pAnimation->mvChannels.size(); ++idx) { cColladaChannel *pChannel = &pAnimation->mvChannels[idx]; TiXmlElement *pChannelElem = CreateXMLChild(pChannelVecElem, "Channel"); pChannelElem->SetAttribute("Id", pChannel->msId.c_str()); pChannelElem->SetAttribute("Target", pChannel->msTarget.c_str()); pChannelElem->SetAttribute("Source", pChannel->msSource.c_str()); } } ///////////////////////////////////// // Samplers { TiXmlElement *pSamplerVecElem = CreateXMLChild(pAnimationElem, "SamplerVec"); pSamplerVecElem->SetAttribute("Size", (int)pAnimation->mvSamplers.size()); for (size_t idx = 0; idx < pAnimation->mvSamplers.size(); ++idx) { cColladaSampler *pSampler = &pAnimation->mvSamplers[idx]; TiXmlElement *pSamplerElem = CreateXMLChild(pSamplerVecElem, "Sampler"); pSamplerElem->SetAttribute("Id", pSampler->msId.c_str()); pSamplerElem->SetAttribute("TimeArray", pSampler->msTimeArray.c_str()); pSamplerElem->SetAttribute("ValueArray", pSampler->msValueArray.c_str()); pSamplerElem->SetAttribute("Target", pSampler->msTarget.c_str()); } } ///////////////////////////////////// // Sources { TiXmlElement *pSourceVecElem = CreateXMLChild(pAnimationElem, "SourceVec"); pSourceVecElem->SetAttribute("Size", (int)pAnimation->mvSources.size()); for (size_t idx = 0; idx < pAnimation->mvSources.size(); ++idx) { cColladaAnimSource *pSource = &pAnimation->mvSources[idx]; TiXmlElement *pSourceElem = CreateXMLChild(pSourceVecElem, "Source"); pSourceElem->SetAttribute("Id", pSource->msId.c_str()); tString sData = ""; for (size_t j = 0; j < pSource->mvValues.size(); ++j) sData += cString::ToString(pSource->mvValues[j]) + " "; pSourceElem->SetAttribute("Values", sData.c_str()); } } } } //----------------------------------------------------------------------- static void SaveControllerVec(TiXmlElement *apRootElem, tColladaControllerVec *apColladaControllerVec) { TiXmlElement *pControllerRootElem = CreateXMLChild(apRootElem, "ControllerRoot"); pControllerRootElem->SetAttribute("Size", (int)apColladaControllerVec->size()); for (size_t i = 0; i < apColladaControllerVec->size(); ++i) { cColladaController *pController = &(*apColladaControllerVec)[i]; TiXmlElement *pControllerElem = CreateXMLChild(pControllerRootElem, "Controller"); pControllerElem->SetAttribute("Id", pController->msId.c_str()); pControllerElem->SetAttribute("Target", pController->msTarget.c_str()); pControllerElem->SetAttribute("BindShapeMatrix", pController->m_mtxBindShapeMatrix.ToFileString().c_str()); pControllerElem->SetAttribute("JointPairIdx", pController->mlJointPairIdx); pControllerElem->SetAttribute("WeightPairIdx", pController->mlWeightPairIdx); /////////////////////// // Joints { TiXmlElement *pJointsElem = CreateXMLChild(pControllerElem, "Joints"); pJointsElem->SetAttribute("Size", (int)pController->mvJoints.size()); tString sData; for (size_t idx = 0; idx < pController->mvJoints.size(); ++idx) { sData += pController->mvJoints[idx] + " "; } CreateXMLTextChild(pJointsElem, sData.c_str()); } /////////////////////// // Weights { TiXmlElement *pWeightsElem = CreateXMLChild(pControllerElem, "Weights"); pWeightsElem->SetAttribute("Size", (int)pController->mvWeights.size()); tString sData = ""; for (size_t idx = 0; idx < pController->mvWeights.size(); ++idx) { sData += cString::ToString(pController->mvWeights[idx]) + " "; } CreateXMLTextChild(pWeightsElem, sData.c_str()); } /////////////////////// // Matrices { TiXmlElement *pMatricesElem = CreateXMLChild(pControllerElem, "Matrices"); pMatricesElem->SetAttribute("Size", (int)pController->mvMatrices.size()); tString sData = ""; for (size_t idx = 0; idx < pController->mvMatrices.size(); ++idx) { sData += pController->mvMatrices[idx].ToFileString() + " "; } CreateXMLTextChild(pMatricesElem, sData.c_str()); } /////////////////////// // Pairs { TiXmlElement *pPairVecElem = CreateXMLChild(pControllerElem, "PairVec"); pPairVecElem->SetAttribute("Size", (int)pController->mvPairs.size()); tIntVec vPairNumVec; Hpl1::resizeAndFill(vPairNumVec, pController->mvPairs.size(), 0); //////////////////////////////// // The pair connections int lCount = 0; TiXmlElement *pPairsElem = CreateXMLChild(pPairVecElem, "Pairs"); tString sData = ""; for (size_t idx = 0; idx < pController->mvPairs.size(); ++idx) { tColladaJointPairList *pList = &pController->mvPairs[idx]; for (tColladaJointPairListIt it = pList->begin(); it != pList->end(); ++it) { cColladaJointPair &Pair = *it; sData += cString::ToString(Pair.mlJoint) + " " + cString::ToString(Pair.mlWeight) + " "; ++lCount; ++vPairNumVec[idx]; } } CreateXMLTextChild(pPairsElem, sData.c_str()); pPairsElem->SetAttribute("Size", lCount); //////////////////////////////// // The pair numbers TiXmlElement *pPairNumElem = CreateXMLChild(pPairVecElem, "PairNum"); sData = ""; for (size_t idx = 0; idx < pController->mvPairs.size(); ++idx) { sData += cString::ToString(vPairNumVec[idx]) + " "; } CreateXMLTextChild(pPairNumElem, sData.c_str()); } } } //----------------------------------------------------------------------- static void SaveGeometryVec(TiXmlElement *apRootElem, tColladaGeometryVec *apColladaGeometryVec) { TiXmlElement *pGeometryRootElem = CreateXMLChild(apRootElem, "GeometryRoot"); pGeometryRootElem->SetAttribute("Size", (int)apColladaGeometryVec->size()); for (size_t i = 0; i < apColladaGeometryVec->size(); ++i) { cColladaGeometry *pGeometry = &(*apColladaGeometryVec)[i]; TiXmlElement *pGeometryElem = CreateXMLChild(pGeometryRootElem, "Geometry"); /////////////////////////////////7 // Main properties pGeometryElem->SetAttribute("Id", pGeometry->msId.c_str()); pGeometryElem->SetAttribute("Name", pGeometry->msName.c_str()); pGeometryElem->SetAttribute("Material", pGeometry->msMaterial.c_str()); ///////////////////////////////// // Vertex properties // Should not be needed. /*pGeometryElem->SetAttribute("PosIdxNum",pGeometry->mlPosIdxNum); pGeometryElem->SetAttribute("NormIdxNum",pGeometry->mlNormIdxNum); pGeometryElem->SetAttribute("TexIdxNum",pGeometry->mlTexIdxNum); pGeometryElem->SetAttribute("PosArrayIdx",pGeometry->mlPosArrayIdx); pGeometryElem->SetAttribute("NormArrayIdx",pGeometry->mlNormArrayIdx); pGeometryElem->SetAttribute("TexArrayIdx",pGeometry->mlTexArrayIdx); */ ///////////////////////////////// // Index Vec TiXmlElement *pIndexVecElem = CreateXMLChild(pGeometryElem, "IndexVec"); pIndexVecElem->SetAttribute("Size", (int)pGeometry->mvIndexVec.size()); TiXmlElement *pIndicesDataElem = CreateXMLChild(pIndexVecElem, "Indices"); tString sIndexVec = ""; for (size_t j = 0; j < pGeometry->mvIndexVec.size(); ++j) { sIndexVec += cString::ToString((int)pGeometry->mvIndexVec[j]) + " "; } TiXmlText *pIndecVecText = CreateXMLTextChild(pIndicesDataElem, "Data"); pIndecVecText->SetValue(sIndexVec.c_str()); ///////////////////////////////// // Vertex vec TiXmlElement *pVertexVecElem = CreateXMLChild(pGeometryElem, "VertexVec"); pVertexVecElem->SetAttribute("Size", (int)pGeometry->mvVertexVec.size()); { ///////////////////////////////// // Positions tString sData = ""; for (size_t j = 0; j < pGeometry->mvVertexVec.size(); ++j) { sData += pGeometry->mvVertexVec[j].pos.ToFileString() + " "; } TiXmlElement *pDataElem = CreateXMLChild(pVertexVecElem, "Positions"); TiXmlText *pVecText = CreateXMLTextChild(pDataElem, "Data"); pVecText->SetValue(sData.c_str()); ///////////////////////////////// // Normals sData = ""; for (size_t j = 0; j < pGeometry->mvVertexVec.size(); ++j) { sData += pGeometry->mvVertexVec[j].norm.ToFileString() + " "; } pDataElem = CreateXMLChild(pVertexVecElem, "Normals"); pVecText = CreateXMLTextChild(pDataElem, "Data"); pVecText->SetValue(sData.c_str()); ///////////////////////////////// // UVs sData = ""; for (size_t j = 0; j < pGeometry->mvVertexVec.size(); ++j) { sData += pGeometry->mvVertexVec[j].tex.ToFileString() + " "; } pDataElem = CreateXMLChild(pVertexVecElem, "UV"); pVecText = CreateXMLTextChild(pDataElem, "Data"); pVecText->SetValue(sData.c_str()); ///////////////////////////////// // Tangents sData = ""; char sTemp[20]; for (size_t j = 0; j < pGeometry->mvTangents.size(); ++j) { snprintf(sTemp, 20, "%g ", pGeometry->mvTangents[j]); sData += sTemp; } pDataElem = CreateXMLChild(pVertexVecElem, "Tangents"); CreateXMLTextChild(pDataElem, sData.c_str()); } ///////////////////////////////// // Extra vertex vec // if(false) { TiXmlElement *pExtraVertexVecElem = CreateXMLChild(pGeometryElem, "ExtraVertexVec"); pExtraVertexVecElem->SetAttribute("Size", (int)pGeometry->mvExtraVtxVec.size()); tUIntVec vExtraNum; Hpl1::resizeAndFill(vExtraNum, pGeometry->mvExtraVtxVec.size(), 0); //////////////////////////// // Extra vertices tString sData = ""; int lExtraCount = 0; TiXmlElement *pExtraElem = CreateXMLChild(pExtraVertexVecElem, "ExtraVertex"); for (size_t idx = 0; idx < pGeometry->mvExtraVtxVec.size(); ++idx) { tColladaExtraVtxList *pList = &pGeometry->mvExtraVtxVec[idx]; tColladaExtraVtxListIt it = pList->begin(); for (; it != pList->end(); ++it) { cColladaExtraVtx &extra = *it; sData += cString::ToString(extra.mlVtx) + " " + cString::ToString(extra.mlNorm) + " " + cString::ToString(extra.mlTex) + " " + cString::ToString(extra.mlNewVtx) + " "; ++lExtraCount; ++vExtraNum[idx]; } } CreateXMLTextChild(pExtraElem, sData.c_str()); pExtraElem->SetAttribute("Size", (int)lExtraCount); //////////////////////////// // Extra num sData = ""; TiXmlElement *pExtraNumElem = CreateXMLChild(pExtraVertexVecElem, "ExtraNum"); for (size_t idx = 0; idx < pGeometry->mvExtraVtxVec.size(); ++idx) { sData += cString::ToString((int)vExtraNum[idx]) + " "; } CreateXMLTextChild(pExtraNumElem, sData.c_str()); } } } //----------------------------------------------------------------------- static void SaveIterativeNode(TiXmlElement *apParentElem, cColladaNode *apParentNode) { tColladaNodeListIt it = apParentNode->mlstChildren.begin(); for (; it != apParentNode->mlstChildren.end(); ++it) { cColladaNode *pNode = *it; TiXmlElement *pNodeElem = CreateXMLChild(apParentElem, "Node"); pNodeElem->SetAttribute("Id", pNode->msId.c_str()); pNodeElem->SetAttribute("Name", pNode->msName.c_str()); pNodeElem->SetAttribute("Type", pNode->msType.c_str()); pNodeElem->SetAttribute("Source", pNode->msSource.c_str()); pNodeElem->SetAttribute("SourceIsFile", pNode->mbSourceIsFile ? "true" : "false"); pNodeElem->SetAttribute("Transform", pNode->m_mtxTransform.ToFileString().c_str()); pNodeElem->SetAttribute("WorldTransform", pNode->m_mtxWorldTransform.ToFileString().c_str()); pNodeElem->SetAttribute("Scale", pNode->mvScale.ToFileString().c_str()); pNodeElem->SetAttribute("Count", pNode->mlCount); TiXmlElement *pTransformRootElem = CreateXMLChild(pNodeElem, "TransformRoot"); // tColladaTransformList mlstTransforms; tColladaTransformListIt transIt = pNode->mlstTransforms.begin(); for (; transIt != pNode->mlstTransforms.end(); ++transIt) { cColladaTransform &transform = *transIt; TiXmlElement *pTransformElem = CreateXMLChild(pTransformRootElem, "Transform"); pTransformElem->SetAttribute("Sid", transform.msSid.c_str()); pTransformElem->SetAttribute("Type", transform.msType.c_str()); tString sValues = ""; for (size_t i = 0; i < transform.mvValues.size(); ++i) sValues += cString::ToString(transform.mvValues[i]) + " "; pTransformElem->SetAttribute("Values", sValues.c_str()); } SaveIterativeNode(pNodeElem, pNode); } } static void SaveScene(TiXmlElement *apRootElem, cColladaScene *apColladaScene) { TiXmlElement *pSceneElem = CreateXMLChild(apRootElem, "Scene"); pSceneElem->SetAttribute("StartTime", cString::ToString(apColladaScene->mfStartTime).c_str()); pSceneElem->SetAttribute("EndTime", cString::ToString(apColladaScene->mfEndTime).c_str()); pSceneElem->SetAttribute("DeltaTime", cString::ToString(apColladaScene->mfDeltaTime).c_str()); TiXmlElement *pSceneRootElem = CreateXMLChild(pSceneElem, "Root"); SaveIterativeNode(pSceneRootElem, &apColladaScene->mRoot); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // LOAD COLLADA DATA ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- static void LoadImageVec(TiXmlElement *apRootElem, tColladaImageVec *apColladaImageVec); static void LoadTextureVec(TiXmlElement *apRootElem, tColladaTextureVec *apColladaTextureVec); static void LoadMaterialVec(TiXmlElement *apRootElem, tColladaMaterialVec *apColladaMaterialVec); static void LoadLightVec(TiXmlElement *apRootElem, tColladaLightVec *apColladaLightVec); static void LoadAnimationVec(TiXmlElement *apRootElem, tColladaAnimationVec *apColladaAnimVec); static void LoadControllerVec(TiXmlElement *apRootElem, tColladaControllerVec *apColladaControllerVec); static void LoadGeometryVec(TiXmlElement *apRootElem, tColladaGeometryVec *apColladaGeometryVec); static void LoadScene(TiXmlElement *apRootElem, cColladaScene *apColladaScene); bool cMeshLoaderCollada::LoadStructures(const tString &asFile, tColladaImageVec *apColladaImageVec, tColladaTextureVec *apColladaTextureVec, tColladaMaterialVec *apColladaMaterialVec, tColladaLightVec *apColladaLightVec, tColladaGeometryVec *apColladaGeometryVec, tColladaControllerVec *apColladaControllerVec, tColladaAnimationVec *apColladaAnimVec, cColladaScene *apColladaScene) { // unsigned long lStartTime = mpSystem->GetLowLevel()->GetTime(); TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (asFile.c_str())); if (pXmlDoc->LoadFile() == false) { Warning("Couldn't open XML file %s\n", asFile.c_str()); hplDelete(pXmlDoc); return false; } // unsigned long lTime = mpSystem->GetLowLevel()->GetTime() - lStartTime; // Log("Loading cached collada XML file '%s' took: %d ms\n",asFile.c_str(),lTime); TiXmlElement *pRootElem = pXmlDoc->RootElement(); if (apColladaImageVec) LoadImageVec(pRootElem, apColladaImageVec); if (apColladaTextureVec) LoadTextureVec(pRootElem, apColladaTextureVec); if (apColladaMaterialVec) LoadMaterialVec(pRootElem, apColladaMaterialVec); if (apColladaLightVec) LoadLightVec(pRootElem, apColladaLightVec); if (apColladaAnimVec) LoadAnimationVec(pRootElem, apColladaAnimVec); if (apColladaControllerVec) LoadControllerVec(pRootElem, apColladaControllerVec); if (apColladaGeometryVec) LoadGeometryVec(pRootElem, apColladaGeometryVec); if (apColladaScene) LoadScene(pRootElem, apColladaScene); hplDelete(pXmlDoc); return true; } //----------------------------------------------------------------------- static void LoadImageVec(TiXmlElement *apRootElem, tColladaImageVec *apColladaImageVec) { TiXmlElement *pImageRootElem = apRootElem->FirstChildElement("ImageRoot"); int lSize = cString::ToInt(pImageRootElem->Attribute("Size"), 0); apColladaImageVec->clear(); apColladaImageVec->resize(lSize); int lCount = 0; TiXmlElement *pImageElem = pImageRootElem->FirstChildElement(); for (; pImageElem != NULL; pImageElem = pImageElem->NextSiblingElement(), ++lCount) { cColladaImage *pImage = &(*apColladaImageVec)[lCount]; pImage->msId = pImageElem->Attribute("Id"); pImage->msName = pImageElem->Attribute("Name"); pImage->msSource = pImageElem->Attribute("Source"); } } //----------------------------------------------------------------------- static void LoadTextureVec(TiXmlElement *apRootElem, tColladaTextureVec *apColladaTextureVec) { TiXmlElement *pTextureRootElem = apRootElem->FirstChildElement("TextureRoot"); int lSize = cString::ToInt(pTextureRootElem->Attribute("Size"), 0); apColladaTextureVec->clear(); apColladaTextureVec->resize(lSize); int lCount = 0; TiXmlElement *pTextureElem = pTextureRootElem->FirstChildElement(); for (; pTextureElem != NULL; pTextureElem = pTextureElem->NextSiblingElement(), ++lCount) { cColladaTexture *pTexture = &(*apColladaTextureVec)[lCount]; pTexture->msId = pTextureElem->Attribute("Id"); pTexture->msName = pTextureElem->Attribute("Name"); pTexture->msImage = pTextureElem->Attribute("Image"); } } //----------------------------------------------------------------------- static void LoadMaterialVec(TiXmlElement *apRootElem, tColladaMaterialVec *apColladaMaterialVec) { TiXmlElement *pMaterialRootElem = apRootElem->FirstChildElement("MaterialRoot"); int lSize = cString::ToInt(pMaterialRootElem->Attribute("Size"), 0); apColladaMaterialVec->clear(); apColladaMaterialVec->resize(lSize); int lCount = 0; TiXmlElement *pMaterialElem = pMaterialRootElem->FirstChildElement(); for (; pMaterialElem != NULL; pMaterialElem = pMaterialElem->NextSiblingElement(), ++lCount) { cColladaMaterial *pMaterial = &(*apColladaMaterialVec)[lCount]; pMaterial->msId = pMaterialElem->Attribute("Id"); pMaterial->msName = pMaterialElem->Attribute("Name"); pMaterial->msTexture = pMaterialElem->Attribute("Texture"); pMaterial->mDiffuseColor = cString::ToColor(pMaterialElem->Attribute("Color"), cColor(0, 0)); } } //----------------------------------------------------------------------- static void LoadControllerVec(TiXmlElement *apRootElem, tColladaControllerVec *apColladaControllerVec) { TiXmlElement *pControllerRootElem = apRootElem->FirstChildElement("ControllerRoot"); if (pControllerRootElem == NULL) { Warning("Could not find root element 'ControllerRoot' for controller!\n"); return; } int lSize1 = cString::ToInt(pControllerRootElem->Attribute("Size"), 0); apColladaControllerVec->clear(); apColladaControllerVec->resize(lSize1); int lCount = 0; TiXmlElement *pControllerElem = pControllerRootElem->FirstChildElement(); for (; pControllerElem != NULL; pControllerElem = pControllerElem->NextSiblingElement(), ++lCount) { cColladaController *pController = &(*apColladaControllerVec)[lCount]; pController->msId = pControllerElem->Attribute("Id"); pController->msTarget = pControllerElem->Attribute("Target"); pController->m_mtxBindShapeMatrix = cString::ToMatrixf(pControllerElem->Attribute("BindShapeMatrix"), cMatrixf::Identity); pController->mlJointPairIdx = cString::ToInt(pControllerElem->Attribute("JointPairIdx"), 0); pController->mlWeightPairIdx = cString::ToInt(pControllerElem->Attribute("WeightPairIdx"), 0); //////////////////////////// // Joints { TiXmlElement *pJointsElem = pControllerElem->FirstChildElement("Joints"); int lSize = cString::ToInt(pJointsElem->Attribute("Size"), 0); TiXmlText *pJointsText = pJointsElem->FirstChild()->ToText(); tString sData = pJointsText->Value(); tString sSepp = " "; pController->mvJoints.reserve(lSize); cString::GetStringVec(sData, pController->mvJoints, &sSepp); } //////////////////////////// // Weights { TiXmlElement *pWeightsElem = pControllerElem->FirstChildElement("Weights"); int lSize = cString::ToInt(pWeightsElem->Attribute("Size"), 0); TiXmlText *pWeightsText = pWeightsElem->FirstChild()->ToText(); // tString sData = pWeightsText->Value(); // tString sSepp = " "; pController->mvWeights.reserve(lSize); // cString::GetFloatVec(sData,pController->mvWeights,&sSepp); pController->mvWeights.resize(lSize); cString::FloatStringToArray(&pController->mvWeights[0], pWeightsText->Value(), lSize); } //////////////////////////// // Matrices { TiXmlElement *pMatricesElem = pControllerElem->FirstChildElement("Matrices"); int lSize = cString::ToInt(pMatricesElem->Attribute("Size"), 0); TiXmlText *pMatricesText = pMatricesElem->FirstChild()->ToText(); // tString sData = pMatricesText->Value(); // tString sSepp = " "; // cString::GetFloatVec(sData,vRawData,&sSepp); tFloatVec vRawData; vRawData.resize(lSize * 16); cString::FloatStringToArray(&vRawData[0], pMatricesText->Value(), lSize * 16); float *pData = &vRawData[0]; pController->mvMatrices.reserve(lSize); for (int i = 0; i < lSize; ++i) { pController->mvMatrices.push_back( cMatrixf(pData[0], pData[1], pData[2], pData[3], pData[4], pData[5], pData[6], pData[7], pData[8], pData[9], pData[10], pData[11], pData[12], pData[13], pData[14], pData[15])); pData += 16; } } //////////////////////////// // Pairs { TiXmlElement *pPairVecElem = pControllerElem->FirstChildElement("PairVec"); int lSize = cString::ToInt(pPairVecElem->Attribute("Size"), 0); ///////////////////////////////////////// // Get number of connections per pair TiXmlElement *pPairNumElem = pPairVecElem->FirstChildElement("PairNum"); TiXmlText *pPairNumText = pPairNumElem->FirstChild()->ToText(); tUIntVec vPairNum; vPairNum.resize(lSize); // tString sData = pPairNumText->Value(); // tString sSepp = " "; // cString::GetIntVec(sData,vPairNum,&sSepp); cString::UIntStringToArray(&vPairNum[0], pPairNumText->Value(), lSize); ///////////////////////////////////////// // Get pairs TiXmlElement *pPairsElem = pPairVecElem->FirstChildElement("Pairs"); int lPairSize = cString::ToInt(pPairsElem->Attribute("Size"), 0); TiXmlText *pPairsText = pPairsElem->FirstChild()->ToText(); tUIntVec vPairs; vPairs.resize(lPairSize * 2); // sData = pPairsText->Value(); // cString::GetIntVec(sData,vPairs,&sSepp); cString::UIntStringToArray(&vPairs[0], pPairsText->Value(), lPairSize * 2); pController->mvPairs.resize(lSize); int lPairCount = 0; for (int i = 0; i < lSize; ++i) { for (unsigned int j = 0; j < vPairNum[i]; ++j) { pController->mvPairs[i].push_back( cColladaJointPair(vPairs[lPairCount], vPairs[lPairCount + 1])); lPairCount += 2; } } } } } //----------------------------------------------------------------------- static void LoadLightVec(TiXmlElement *apRootElem, tColladaLightVec *apColladaLightVec) { TiXmlElement *pLightRootElem = apRootElem->FirstChildElement("LightRoot"); int lSize = cString::ToInt(pLightRootElem->Attribute("Size"), 0); apColladaLightVec->clear(); apColladaLightVec->resize(lSize); int lCount = 0; TiXmlElement *pLightElem = pLightRootElem->FirstChildElement(); for (; pLightElem != NULL; pLightElem = pLightElem->NextSiblingElement(), ++lCount) { cColladaLight *pLight = &(*apColladaLightVec)[lCount]; pLight->msId = pLightElem->Attribute("Id"); pLight->msName = pLightElem->Attribute("Name"); pLight->msType = pLightElem->Attribute("Type"); pLight->mfAngle = cString::ToFloat(pLightElem->Attribute("Angle"), 0); pLight->mDiffuseColor = cString::ToColor(pLightElem->Attribute("Color"), cColor(0, 0)); } } //----------------------------------------------------------------------- static void LoadAnimationVec(TiXmlElement *apRootElem, tColladaAnimationVec *apColladaAnimationVec) { TiXmlElement *pAnimationRootElem = apRootElem->FirstChildElement("AnimationRoot"); if (pAnimationRootElem == NULL) { Warning("Could not find root element 'AnimationRoot' for animation!\n"); return; } int lSize1 = cString::ToInt(pAnimationRootElem->Attribute("Size"), 0); apColladaAnimationVec->clear(); apColladaAnimationVec->resize(lSize1); int lCount = 0; TiXmlElement *pAnimationElem = pAnimationRootElem->FirstChildElement(); for (; pAnimationElem != NULL; pAnimationElem = pAnimationElem->NextSiblingElement(), ++lCount) { cColladaAnimation *pAnimation = &(*apColladaAnimationVec)[lCount]; pAnimation->msId = pAnimationElem->Attribute("Id"); pAnimation->msTargetNode = pAnimationElem->Attribute("TargetNode"); ///////////////////////////////////// // Channels { TiXmlElement *pChannelVecElem = pAnimationElem->FirstChildElement("ChannelVec"); int lSize = cString::ToInt(pChannelVecElem->Attribute("Size"), 0); pAnimation->mvChannels.resize(lSize); int idx = 0; TiXmlElement *pChannelElem = pChannelVecElem->FirstChildElement("Channel"); for (; pChannelElem != NULL; pChannelElem = pChannelElem->NextSiblingElement("Channel"), ++idx) { cColladaChannel *pChannel = &pAnimation->mvChannels[idx]; pChannel->msId = pChannelElem->Attribute("Id"); pChannel->msTarget = pChannelElem->Attribute("Target"); pChannel->msSource = pChannelElem->Attribute("Source"); } } ///////////////////////////////////// // Samplers { TiXmlElement *pSamplerVecElem = pAnimationElem->FirstChildElement("SamplerVec"); int lSize = cString::ToInt(pSamplerVecElem->Attribute("Size"), 0); pAnimation->mvSamplers.resize(lSize); int idx = 0; TiXmlElement *pSamplerElem = pSamplerVecElem->FirstChildElement("Sampler"); for (; pSamplerElem != NULL; pSamplerElem = pSamplerElem->NextSiblingElement("Sampler"), ++idx) { cColladaSampler *pSampler = &pAnimation->mvSamplers[idx]; pSampler->msId = pSamplerElem->Attribute("Id"); pSampler->msTarget = pSamplerElem->Attribute("Target"); pSampler->msTimeArray = pSamplerElem->Attribute("TimeArray"); pSampler->msValueArray = pSamplerElem->Attribute("ValueArray"); } } ///////////////////////////////////// // Sources { TiXmlElement *pSourceVecElem = pAnimationElem->FirstChildElement("SourceVec"); int lSize = cString::ToInt(pSourceVecElem->Attribute("Size"), 0); pAnimation->mvSources.resize(lSize); int idx = 0; TiXmlElement *pSourceElem = pSourceVecElem->FirstChildElement("Source"); for (; pSourceElem != NULL; pSourceElem = pSourceElem->NextSiblingElement("Source"), ++idx) { cColladaAnimSource *pSource = &pAnimation->mvSources[idx]; pSource->msId = pSourceElem->Attribute("Id"); tString sData = pSourceElem->Attribute("Values"); tString sSepp = " "; pSource->mvValues.reserve(3); cString::GetFloatVec(sData, pSource->mvValues, &sSepp); } } } } //----------------------------------------------------------------------- static void LoadGeometryVec(TiXmlElement *apRootElem, tColladaGeometryVec *apColladaGeometryVec) { TiXmlElement *pGeometryRootElem = apRootElem->FirstChildElement("GeometryRoot"); int lSize1 = cString::ToInt(pGeometryRootElem->Attribute("Size"), 0); apColladaGeometryVec->clear(); apColladaGeometryVec->resize(lSize1); int lCount = 0; TiXmlElement *pGeometryElem = pGeometryRootElem->FirstChildElement(); for (; pGeometryElem != NULL; pGeometryElem = pGeometryElem->NextSiblingElement(), ++lCount) { cColladaGeometry *pGeometry = &(*apColladaGeometryVec)[lCount]; pGeometry->msId = pGeometryElem->Attribute("Id"); pGeometry->msName = pGeometryElem->Attribute("Name"); pGeometry->msMaterial = pGeometryElem->Attribute("Material"); ///////////////////////////////// // Index Vec { TiXmlElement *pIndexVecElem = pGeometryElem->FirstChildElement("IndexVec"); int lSize = cString::ToInt(pIndexVecElem->Attribute("Size"), 0); if (lSize > 0) { TiXmlElement *pIndicesDataElem = pIndexVecElem->FirstChildElement("Indices"); TiXmlText *pVecText = pIndicesDataElem->FirstChild()->ToText(); pGeometry->mvIndexVec.resize(lSize); cString::UIntStringToArray(&pGeometry->mvIndexVec[0], pVecText->Value(), lSize); // tString sData = pVecText->Value(); // tString sSepp = " "; // cString::GetUIntVec(sData,pGeometry->mvIndexVec,&sSepp); } } ///////////////////////////////// // Vertex vec { TiXmlElement *pVertexVecElem = pGeometryElem->FirstChildElement("VertexVec"); int lSize = cString::ToInt(pVertexVecElem->Attribute("Size"), 0); if (lSize > 0) { pGeometry->mvVertexVec.resize(lSize); tFloatVec vRawData; vRawData.resize(lSize * 3); ///////////////////////////////// // Positions { TiXmlElement *pDataElem = pVertexVecElem->FirstChildElement("Positions"); TiXmlText *pVecText = pDataElem->FirstChild()->ToText(); // tString sData = pVecText->Value(); // tString sSepp = " "; // tFloatVec vRawData; vRawData.reserve(lSize * 3); // cString::GetFloatVec(sData,vRawData,&sSepp); cString::FloatStringToArray(&vRawData[0], pVecText->Value(), lSize * 3); float *pData = &vRawData[0]; for (int i = 0; i < lSize; ++i) { cVector3f &vPos = pGeometry->mvVertexVec[i].pos; vPos.x = pData[0]; vPos.y = pData[1]; vPos.z = pData[2]; pData += 3; } } ///////////////////////////////// // Normals { TiXmlElement *pDataElem = pVertexVecElem->FirstChildElement("Normals"); TiXmlText *pVecText = pDataElem->FirstChild()->ToText(); // tString sData = pVecText->Value(); // tString sSepp = " "; // tFloatVec vRawData; vRawData.reserve(lSize * 3); // cString::GetFloatVec(sData,vRawData,&sSepp); cString::FloatStringToArray(&vRawData[0], pVecText->Value(), lSize * 3); float *pData = &vRawData[0]; for (int i = 0; i < lSize; ++i) { cVector3f &vPos = pGeometry->mvVertexVec[i].norm; vPos.x = pData[0]; vPos.y = pData[1]; vPos.z = pData[2]; pData += 3; } } ///////////////////////////////// // UVs { TiXmlElement *pDataElem = pVertexVecElem->FirstChildElement("UV"); TiXmlText *pVecText = pDataElem->FirstChild()->ToText(); // tString sData = pVecText->Value(); // tString sSepp = " "; // tFloatVec vRawData; vRawData.reserve(lSize * 3); // cString::GetFloatVec(sData,vRawData,&sSepp); cString::FloatStringToArray(&vRawData[0], pVecText->Value(), lSize * 3); float *pData = &vRawData[0]; for (int i = 0; i < lSize; ++i) { cVector3f &vPos = pGeometry->mvVertexVec[i].tex; vPos.x = pData[0]; vPos.y = pData[1]; vPos.z = pData[2]; pData += 3; } } ///////////////////////////////// // Tangents { TiXmlElement *pDataElem = pVertexVecElem->FirstChildElement("Tangents"); TiXmlText *pVecText = pDataElem->FirstChild()->ToText(); // tString sData = pVecText->Value(); // tString sSepp = " "; // tFloatVec vRawData; vRawData.reserve(lSize * 3); // cString::GetFloatVec(sData,vRawData,&sSepp); pGeometry->mvTangents.resize(lSize * 4); cString::FloatStringToArray(&pGeometry->mvTangents[0], pVecText->Value(), lSize * 4); } } } ///////////////////////////////// // Extra vertex vec { TiXmlElement *pVertexVecElem = pGeometryElem->FirstChildElement("ExtraVertexVec"); int lSize = cString::ToInt(pVertexVecElem->Attribute("Size"), 0); if (lSize > 0) { pGeometry->mvExtraVtxVec.resize(lSize); tUIntVec mvExtraNum; mvExtraNum.resize(lSize); tUIntVec mvExtraVtx; ////////////////////////////////////////////// // Extra num { TiXmlElement *pExtraNumElem = pVertexVecElem->FirstChildElement("ExtraNum"); TiXmlText *pExtraNumText = pExtraNumElem->FirstChild()->ToText(); cString::UIntStringToArray(&mvExtraNum[0], pExtraNumText->Value(), lSize); } ////////////////////////////////////////////// // Extra vertex { TiXmlElement *pExtraVertexElem = pVertexVecElem->FirstChildElement("ExtraVertex"); TiXmlText *pExtraVertexText = pExtraVertexElem->FirstChild()->ToText(); int lExtraVtxSize = cString::ToInt(pExtraVertexElem->Attribute("Size"), 0); mvExtraVtx.resize(lExtraVtxSize * 4); cString::UIntStringToArray(&mvExtraVtx[0], pExtraVertexText->Value(), lExtraVtxSize * 4); } unsigned int *pData = &mvExtraVtx[0]; for (int idx = 0; idx < lSize; ++idx) { tColladaExtraVtxList *pList = &pGeometry->mvExtraVtxVec[idx]; for (unsigned int j = 0; j < mvExtraNum[idx]; ++j) { pList->push_back(cColladaExtraVtx(pData[0], pData[1], pData[2], pData[3])); pData += 4; } } } } } } //----------------------------------------------------------------------- static void LoadIterativeNode(TiXmlElement *apNodeElem, cColladaNode *apParentNode, cColladaScene *apColladaScene) { cColladaNode *pNode = apParentNode->CreateChild(); apColladaScene->mlstNodes.push_back(pNode); pNode->msId = apNodeElem->Attribute("Id"); pNode->msName = apNodeElem->Attribute("Name"); pNode->msType = apNodeElem->Attribute("Type"); pNode->msSource = apNodeElem->Attribute("Source"); pNode->mbSourceIsFile = cString::ToBool(apNodeElem->Attribute("SourceIsFile"), false); pNode->m_mtxTransform = cString::ToMatrixf(apNodeElem->Attribute("Transform"), cMatrixf::Identity); pNode->m_mtxWorldTransform = cString::ToMatrixf(apNodeElem->Attribute("WorldTransform"), cMatrixf::Identity); pNode->mvScale = cString::ToVector3f(apNodeElem->Attribute("Scale"), 1); pNode->mlCount = cString::ToInt(apNodeElem->Attribute("Count"), 1); TiXmlElement *pTransformRootElem = apNodeElem->FirstChildElement("TransformRoot"); TiXmlElement *pTransformElem = pTransformRootElem->FirstChildElement("Transform"); for (; pTransformElem != NULL; pTransformElem = pTransformElem->NextSiblingElement("Transform")) { pNode->mlstTransforms.push_back(cColladaTransform()); cColladaTransform &transform = pNode->mlstTransforms.back(); transform.msSid = pTransformElem->Attribute("Sid"); transform.msType = pTransformElem->Attribute("Type"); tString sData = pTransformElem->Attribute("Values"); tString sSepp = " "; cString::GetFloatVec(sData, transform.mvValues, &sSepp); } TiXmlElement *pChildElem = apNodeElem->FirstChildElement("Node"); for (; pChildElem != NULL; pChildElem = pChildElem->NextSiblingElement("Node")) { LoadIterativeNode(pChildElem, pNode, apColladaScene); } } //----------------------------------------------------------------------- static void LoadScene(TiXmlElement *apRootElem, cColladaScene *apColladaScene) { TiXmlElement *pSceneElem = apRootElem->FirstChildElement("Scene"); // Delete all nodes. apColladaScene->ResetNodes(); apColladaScene->mfStartTime = cString::ToFloat(pSceneElem->Attribute("StartTime"), 0); apColladaScene->mfEndTime = cString::ToFloat(pSceneElem->Attribute("EndTime"), 0); apColladaScene->mfDeltaTime = cString::ToFloat(pSceneElem->Attribute("DeltaTime"), 0); TiXmlElement *pSceneRootElem = pSceneElem->FirstChildElement("Root"); TiXmlElement *pNodeElem = pSceneRootElem->FirstChildElement("Node"); for (; pNodeElem != NULL; pNodeElem = pNodeElem->NextSiblingElement("Node")) { LoadIterativeNode(pNodeElem, &apColladaScene->mRoot, apColladaScene); } } //----------------------------------------------------------------------- } // namespace hpl