/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Implementation of the CryEngine Unit Testing framework #include "stdafx.h" #include "AssetFileInfo.h" #include "CryPath.h" #include "ExcelReport.h" #include "IResCompiler.h" #include "StringUtils.h" // for cry_strcat ////////////////////////////////////////////////////////////////////////// struct FilesComparePredicate { bool operator()(const CAssetFileInfo* p1, const CAssetFileInfo* p2) { if (p1->m_bSuccess != p2->m_bSuccess) { return p1->m_bSuccess < p2->m_bSuccess; } return p1->m_DstFileSize > p2->m_DstFileSize; } }; ////////////////////////////////////////////////////////////////////////// static inline int64 ComputeSizeInKB(int64 sz) { return (sz < 0) ? 0 : (sz + 512) / 1024; } ////////////////////////////////////////////////////////////////////////// bool CExcelReport::Export(IResourceCompiler* pRC, const char* filename, std::vector& files) { m_pRC = pRC; XmlNodeRef WorkBook = NewWorkbook(); std::sort(files.begin(), files.end(), FilesComparePredicate()); ExportSummary(files); ExportTextures(files); ExportCGF(files); ExportCHR(files); ExportCAF(files); return SaveToFile(filename); } ////////////////////////////////////////////////////////////////////////// void CExcelReport::ExportSummary(const std::vector& files) { NewWorksheet("Summary"); const SFileVersion& fv = m_pRC->GetFileVersion(); AddColumn("", 150); AddColumn("", 150); AddRow(); AddCell("RC Version", CELL_BOLD); char buffer[1024]; azsnprintf(buffer, sizeof(buffer), "%d.%d.%d", fv.v[2], fv.v[1], fv.v[0]); AddCell(buffer); AddRow(); AddCell("RC Compile Time", CELL_BOLD); azsnprintf(buffer, sizeof(buffer), "%s %s", __DATE__, __TIME__); AddCell(buffer); AddRow(); AddRow(); size_t unusedCount = 0; uint64 unusedSize = 0; for (size_t i = 0; i < files.size(); i++) { const CAssetFileInfo& afi = *files[i]; if (!afi.m_bReferencedInLevels && (afi.m_type == CAssetFileInfo::eTexture || afi.m_type == CAssetFileInfo::eCGF || afi.m_type == CAssetFileInfo::eCHR)) { ++unusedCount; unusedSize += afi.m_DstFileSize; } } azsnprintf(buffer, sizeof(buffer), "%d files processed", (int)files.size()); AddCell(buffer); AddRow(); const unsigned int bytesInMegabyte = 1024 * 1024; azsnprintf(buffer, sizeof(buffer), "%u unused assets found (%u MB)", (unsigned int)unusedCount, (unsigned int)(unusedSize / bytesInMegabyte)); AddCell(buffer); } ////////////////////////////////////////////////////////////////////////// void CExcelReport::ExportTextures(const std::vector& files) { NewWorksheet("Textures"); FreezeFirstRow(); AutoFilter(1, 10); BeginColumns(); AddColumn("Ok", 40); AddColumn("File", 400); AddColumn("In Levels", 60); AddColumn("User", 80); AddColumn("Size (KB)", 80); AddColumn("Width", 50); AddColumn("Height", 50); AddColumn("Mips", 50); AddColumn("Format", 80); AddColumn("Type", 80); AddColumn("Alpha", 50); AddColumn("Sides", 50); AddColumn("Perforce", 100); AddColumn("Error", 100); EndColumns(); for (uint32 i = 0; i < files.size(); i++) { const CAssetFileInfo& afi = *files[i]; if (afi.m_type != CAssetFileInfo::eTexture) { continue; } AddRow(); AddCell(afi.m_bSuccess ? "OK" : "FAIL", (afi.m_bSuccess ? 0 : CELL_HIGHLIGHT)); AddCell(afi.m_sSourceFilename); AddCell(afi.m_bReferencedInLevels ? "USED" : "NOT USED", afi.m_bReferencedInLevels ? CELL_CENTERED : CELL_BOLD | CELL_CENTERED); AddCell(ComputeSizeInKB(afi.m_DstFileSize)); AddCell(afi.m_textureInfo.w); AddCell(afi.m_textureInfo.h); AddCell(afi.m_textureInfo.nNumMips); AddCell(afi.m_textureInfo.format, CELL_CENTERED); const char* type = "2D"; if (afi.m_textureInfo.nDepth > 1) { type = "3D"; } else if (afi.m_textureInfo.nSides > 1) { type = "Cubemap"; } AddCell(type, CELL_CENTERED); AddCell((afi.m_textureInfo.bAlpha) ? "Yes" : "", CELL_CENTERED); AddCell(afi.m_textureInfo.nSides); AddCell(afi.m_sErrorLog); } } ////////////////////////////////////////////////////////////////////////// void CExcelReport::ExportCGF(const std::vector& files) { NewWorksheet("Geometry"); FreezeFirstRow(); AutoFilter(1, 15); BeginColumns(); AddColumn("Ok", 40); AddColumn("File", 400); AddColumn("In Levels", 60); AddColumn("User", 80); AddColumn("File Size", 80); AddColumn("Mesh Size (KB)", 80); AddColumn("Mesh Size Lod0 (KB)", 80); AddColumn("LODs", 50); AddColumn("Sub Meshes", 50); AddColumn("Vertices", 50); AddColumn("Tris", 50); AddColumn("Joints", 50); AddColumn("Phys Tris", 80); AddColumn("Phys Size (KB)", 80); AddColumn("Phys Proxies", 80); AddColumn("LODs Tris", 80); AddColumn("Split LODs", 80); AddColumn("Perforce", 100); AddColumn("Error", 100); EndColumns(); for (uint32 i = 0; i < files.size(); i++) { const CAssetFileInfo& afi = *files[i]; if (afi.m_type != CAssetFileInfo::eCGF) { continue; } int nMeshSizeTotal = 0; for (int lod = 0; lod < CAssetFileInfo::kMaxCgfLods; lod++) { nMeshSizeTotal += afi.m_geomInfo.nMeshSizePerLod[lod]; } AddRow(); AddCell(afi.m_bSuccess ? "OK" : "FAIL", (afi.m_bSuccess ? 0 : CELL_HIGHLIGHT)); AddCell(afi.m_sSourceFilename); AddCell(afi.m_bReferencedInLevels ? "USED" : "NOT USED", afi.m_bReferencedInLevels ? CELL_CENTERED : CELL_BOLD | CELL_CENTERED); AddCell(ComputeSizeInKB(afi.m_DstFileSize)); AddCell((nMeshSizeTotal + 512) / 1024); AddCell((afi.m_geomInfo.nMeshSize + 512) / 1024); AddCell(afi.m_geomInfo.nLods); AddCell(afi.m_geomInfo.nSubMeshCount); AddCell(afi.m_geomInfo.nVertices); AddCell(afi.m_geomInfo.nIndices / 3); AddCell(afi.m_geomInfo.nJoints); AddCell(afi.m_geomInfo.nPhysTriCount); AddCell((afi.m_geomInfo.nPhysProxySize + 512) / 1024); AddCell((afi.m_geomInfo.nPhysProxyCount)); if (afi.m_geomInfo.nLods > 1) { // Print lod1/lod2/lod3 ... char tempstr[256]; char numstr[32]; tempstr[0] = 0; int numlods = 0; for (int lod = 0; lod < CAssetFileInfo::kMaxCgfLods; lod++) { if (afi.m_geomInfo.nIndicesPerLod[lod] != 0) { azsnprintf(numstr, sizeof(numstr), "%d", (afi.m_geomInfo.nIndicesPerLod[lod] / 3)); if (numlods > 0) { cry_strcat(tempstr, " / "); } cry_strcat(tempstr, numstr); numlods++; } } AddCell(tempstr, CELL_CENTERED); } else { AddCell(""); } AddCell((afi.m_geomInfo.bSplitLods) ? "Yes" : ""); AddCell(afi.m_sErrorLog); } } ////////////////////////////////////////////////////////////////////////// void CExcelReport::ExportCHR(const std::vector& files) { NewWorksheet("Characters"); FreezeFirstRow(); AutoFilter(1, 15); BeginColumns(); AddColumn("Ok", 40); AddColumn("File", 400); AddColumn("In Levels", 60); AddColumn("User", 80); AddColumn("File Size", 80); AddColumn("Mesh Size (KB)", 80); AddColumn("Mesh Size Lod0 (KB)", 80); AddColumn("LODs", 50); AddColumn("Sub Meshes", 50); AddColumn("Vertices", 50); AddColumn("Tris", 50); AddColumn("Phys Tris", 80); AddColumn("Phys Size (KB)", 80); AddColumn("Phys Proxies", 80); AddColumn("LODs Tris", 80); AddColumn("Perforce", 100); AddColumn("Error", 100); EndColumns(); for (uint32 i = 0; i < files.size(); i++) { const CAssetFileInfo& afi = *files[i]; if (afi.m_type != CAssetFileInfo::eCHR) { continue; } int nMeshSizeTotal = 0; for (int lod = 0; lod < CAssetFileInfo::kMaxCgfLods; lod++) { nMeshSizeTotal += afi.m_geomInfo.nMeshSizePerLod[lod]; } AddRow(); AddCell(afi.m_bSuccess ? "OK" : "FAIL", (afi.m_bSuccess ? 0 : CELL_HIGHLIGHT)); AddCell(afi.m_sSourceFilename); AddCell(afi.m_bReferencedInLevels ? "USED" : "NOT USED", afi.m_bReferencedInLevels ? CELL_CENTERED : CELL_BOLD | CELL_CENTERED); AddCell(ComputeSizeInKB(afi.m_DstFileSize)); AddCell((nMeshSizeTotal + 512) / 1024); AddCell((afi.m_geomInfo.nMeshSize + 512) / 1024); AddCell(afi.m_geomInfo.nLods); AddCell(afi.m_geomInfo.nSubMeshCount); AddCell(afi.m_geomInfo.nVertices); AddCell(afi.m_geomInfo.nIndices / 3); AddCell(afi.m_geomInfo.nPhysTriCount); AddCell((afi.m_geomInfo.nPhysProxySize + 512) / 1024); AddCell((afi.m_geomInfo.nPhysProxyCount)); if (afi.m_geomInfo.nLods > 1) { // Print lod1/lod2/lod3 ... char tempstr[256]; char numstr[32]; tempstr[0] = 0; int numlods = 0; for (int lod = 0; lod < CAssetFileInfo::kMaxCgfLods; lod++) { if (afi.m_geomInfo.nIndicesPerLod[lod] != 0) { sprintf_s(numstr, sizeof(numstr), "%d", (afi.m_geomInfo.nIndicesPerLod[lod] / 3)); if (numlods > 0) { cry_strcat(tempstr, " / "); } cry_strcat(tempstr, numstr); numlods++; } } AddCell(tempstr, CELL_CENTERED); } else { AddCell(""); } AddCell(afi.m_sErrorLog); } } ////////////////////////////////////////////////////////////////////////// void CExcelReport::ExportCAF(const std::vector& files) { NewWorksheet("Animations"); FreezeFirstRow(); AutoFilter(1, 5); BeginColumns(); AddColumn("Ok", 40); AddColumn("File", 400); AddColumn("User", 80); AddColumn("File Size", 80); AddColumn("Perforce", 100); AddColumn("Error", 100); EndColumns(); for (uint32 i = 0; i < files.size(); i++) { const CAssetFileInfo& afi = *files[i]; if (afi.m_type != CAssetFileInfo::eCAF) { continue; } int nMeshSizeTotal = 0; for (int lod = 0; lod < CAssetFileInfo::kMaxCgfLods; lod++) { nMeshSizeTotal += afi.m_geomInfo.nMeshSizePerLod[lod]; } AddRow(); AddCell(afi.m_bSuccess ? "OK" : "FAIL", (afi.m_bSuccess ? 0 : CELL_HIGHLIGHT)); AddCell(afi.m_sSourceFilename); AddCell(ComputeSizeInKB(afi.m_DstFileSize)); AddCell(afi.m_sErrorLog); } }