MaterialUtils.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
  3. * its licensors.
  4. *
  5. * For complete copyright and license terms please see the LICENSE at the root of this
  6. * distribution (the "License"). All use of this software is governed by the License,
  7. * or, if provided, by the license below or the license accompanying this file. Do not
  8. * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
  9. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. *
  11. */
  12. #pragma once
  13. #ifndef CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
  14. #define CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
  15. #include <AzCore/base.h>
  16. #include <AzCore/IO/SystemFile.h> // for max path len
  17. #include <AzCore/std/string/string.h>
  18. #include <AzCore/Utils/Utils.h>
  19. #include <AzFramework/StringFunc/StringFunc.h>
  20. #include <ISystem.h>
  21. namespace MaterialUtils
  22. {
  23. //! UnifyMaterialName - given a non-unified material name, remove the extension, unify the slashes
  24. //! and fix up any legacy naming issues so that the material name can be used in a hash map
  25. //! and will work each lookup.
  26. inline void UnifyMaterialName(char* inputOutputBuffer)
  27. {
  28. if (!inputOutputBuffer)
  29. {
  30. return;
  31. }
  32. // convert slashes and remove extensions:
  33. size_t inputLength = strlen(inputOutputBuffer);
  34. if (inputLength == 0)
  35. {
  36. return;
  37. }
  38. // this must be done first, so that the extension cutting function below does not mistakenly destroy this when it finds the .
  39. if ((azstrnicmp(inputOutputBuffer, "./", 2) == 0) || (azstrnicmp(inputOutputBuffer, ".\\", 2) == 0))
  40. {
  41. memmove(inputOutputBuffer, inputOutputBuffer + 2, inputLength - 2);
  42. inputOutputBuffer[inputLength - 2] = 0;
  43. inputLength -= 2;
  44. }
  45. for (size_t pos = 0; pos < inputLength; ++pos)
  46. {
  47. if (inputOutputBuffer[pos] == '\\')
  48. {
  49. inputOutputBuffer[pos] = '/'; // unify slashes
  50. }
  51. else
  52. {
  53. inputOutputBuffer[pos] = tolower(inputOutputBuffer[pos]);
  54. }
  55. }
  56. AZStd::string tempString(inputOutputBuffer);
  57. AzFramework::StringFunc::Path::StripExtension(tempString);
  58. AZ_Assert(tempString.length() <= inputLength, "Extension stripped string has to be smaller than/same size as original string!");
  59. // real size of inputOutputBuffer is inputLength + 1 with Null character
  60. azstrcpy(inputOutputBuffer, inputLength + 1, tempString.c_str());
  61. #if defined(SUPPORT_LEGACY_MATERIAL_NAMES)
  62. // LEGACY support Some files may start with ./ in front of them. This is not required anymore.
  63. static const char* removals[2] = {
  64. "engine/",
  65. nullptr // reserved for game name
  66. };
  67. static size_t removalSize = sizeof(removals) / sizeof(removals[0]);
  68. // LEGACY support. Some files may start with gamename in front of them. This is not required anymore.
  69. static char cachedGameName[AZ_MAX_PATH_LEN] = { 0 };
  70. if (!removals[removalSize - 1])
  71. {
  72. auto projectName = AZ::Utils::GetProjectName();
  73. if (!projectName.empty())
  74. {
  75. azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, projectName.c_str());
  76. azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
  77. }
  78. if (cachedGameName[0] == 0)
  79. {
  80. // at least substitute something so that unit tests can make this assumption:
  81. azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, "SamplesProject/");
  82. }
  83. removals[removalSize - 1] = cachedGameName;
  84. }
  85. for (size_t pos = 0; pos < removalSize; ++pos)
  86. {
  87. if (removals[pos])
  88. {
  89. size_t removalLength = strlen(removals[pos]);
  90. if (removalLength >= inputLength)
  91. {
  92. continue;
  93. }
  94. if (azstrnicmp(inputOutputBuffer, removals[pos], removalLength) == 0)
  95. {
  96. memmove(inputOutputBuffer, inputOutputBuffer + removalLength, inputLength - removalLength);
  97. inputOutputBuffer[inputLength - removalLength] = 0;
  98. inputLength -= removalLength;
  99. }
  100. }
  101. }
  102. // legacy: Files were saved into a mtl with many leading forward or back slashes, we eat them all here. We want it to start with a rel path.
  103. const char* actualFileName = inputOutputBuffer;
  104. size_t finalLength = inputLength;
  105. while ((actualFileName[0]) && ((actualFileName[0] == '\\') || (actualFileName[0] == '/')))
  106. {
  107. ++actualFileName;
  108. --finalLength;
  109. }
  110. if (finalLength != inputLength)
  111. {
  112. memmove(inputOutputBuffer, actualFileName, finalLength);
  113. inputOutputBuffer[finalLength] = 0;
  114. inputLength = finalLength;
  115. }
  116. #endif
  117. }
  118. }
  119. #endif // CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H