aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/shared/external/src/MaterialList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'APEX_1.4/shared/external/src/MaterialList.cpp')
-rw-r--r--APEX_1.4/shared/external/src/MaterialList.cpp436
1 files changed, 436 insertions, 0 deletions
diff --git a/APEX_1.4/shared/external/src/MaterialList.cpp b/APEX_1.4/shared/external/src/MaterialList.cpp
new file mode 100644
index 00000000..1679dd99
--- /dev/null
+++ b/APEX_1.4/shared/external/src/MaterialList.cpp
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+
+#include "MaterialList.h"
+
+#include "PxAssert.h"
+
+#if PX_WINDOWS_FAMILY
+#define NOMINMAX
+#include <windows.h>
+#endif
+
+#include "PsFastXml.h"
+#include "PsFileBuffer.h"
+#include "PsString.h"
+
+#include "PxInputDataFromPxFileBuf.h"
+
+namespace Samples
+{
+
+MaterialList::MaterialList()
+{
+}
+
+
+MaterialList::~MaterialList()
+{
+}
+
+
+
+void MaterialList::clear()
+{
+ mMaterialNames.clear();
+ mTextureNames.clear();
+
+ mPaths.clear();
+}
+
+
+
+void MaterialList::addPath(const char* path)
+{
+ PX_UNUSED(path);
+
+#if PX_WINDOWS_FAMILY
+ const char* matPrefixes[2] = { "", "materials/" };
+
+ PX_ASSERT(strlen(path) < 240);
+ char fileMask[256];
+
+ unsigned int materialsAdded = 0;
+
+ for (unsigned int pass = 0; pass < 2; pass++)
+ {
+ physx::shdfnd::snprintf(fileMask, 255, "%s/%s*.xml", path, matPrefixes[(unsigned int)pass]);
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = ::FindFirstFile(fileMask, &ffd);
+
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ materialsAdded += addMaterial(path, matPrefixes[pass], ffd.cFileName);
+ }
+ while (FindNextFile(hFind, &ffd) != 0);
+
+ FindClose(hFind);
+ }
+ }
+
+
+ const char* texPrefixes[2] = { "", "textures/" };
+ const char* texSuffixes[2] = { "dds", "tga" };
+
+ unsigned int texturesAdded = 0;
+
+ for (unsigned int prefixes = 0; prefixes < 2; prefixes++)
+ {
+ for (unsigned int suffixes = 0; suffixes < 2; suffixes++)
+ {
+ physx::shdfnd::snprintf(fileMask, 255, "%s/%s*.%s", path, texPrefixes[prefixes], texSuffixes[suffixes]);
+
+ WIN32_FIND_DATA ffd;
+ HANDLE hFind = ::FindFirstFile(fileMask, &ffd);
+
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ texturesAdded += addTexture(path, texPrefixes[prefixes], ffd.cFileName);
+ }
+ while (FindNextFile(hFind, &ffd) != 0);
+
+ FindClose(hFind);
+ }
+ }
+ }
+
+ if (materialsAdded > 0 || texturesAdded > 0)
+ {
+ mPaths.push_back(path);
+ }
+
+#if 0
+ // verification step
+ for (tMaterialNames::const_iterator it = mMaterialNames.begin(); it != mMaterialNames.end(); ++it)
+ {
+ if (!it->second.diffuseTexture.empty())
+ {
+ tTextureNames::const_iterator tex = mTextureNames.find(it->second.diffuseTexture);
+ if (tex == mTextureNames.end())
+ {
+ PX_ASSERT(!"Texture not found");
+ }
+ else
+ {
+ PX_ASSERT(tex->second.fromPath <= it->second.fromPath);
+ }
+ }
+
+ if (!it->second.normalTexture.empty())
+ {
+ tTextureNames::const_iterator tex = mTextureNames.find(it->second.normalTexture);
+ if (tex == mTextureNames.end())
+ {
+ PX_ASSERT(!"Texture not found");
+ }
+ else
+ {
+ PX_ASSERT(tex->second.fromPath <= it->second.fromPath);
+ }
+ }
+ }
+#endif
+
+#endif
+}
+
+
+
+const MaterialList::MaterialInfo* MaterialList::containsMaterial(const char* materialName) const
+{
+ tMaterialNames::const_iterator it = mMaterialNames.find(materialName);
+
+ if (it != mMaterialNames.end())
+ {
+ return &it->second;
+ }
+
+ return NULL;
+}
+
+
+
+const char* MaterialList::findClosest(const char* materialName) const
+{
+ for (std::map<std::string, MaterialInfo>::const_iterator it = mMaterialNames.begin(); it != mMaterialNames.end(); ++it)
+ {
+ if (it->first.find(materialName) != std::string::npos)
+ {
+ return it->first.c_str();
+ }
+ }
+
+ //return "materials/debug_texture.xml";
+ return "materials/simple_lit.xml";
+}
+
+
+
+const MaterialList::TextureInfo* MaterialList::containsTexture(const char* textureName) const
+{
+ tTextureNames::const_iterator it = mTextureNames.find(textureName);
+
+ if (it != mTextureNames.end())
+ {
+ return &it->second;
+ }
+
+ return NULL;
+}
+
+
+
+
+MaterialList::MaterialInfo::MaterialInfo() :
+ isLit(false),
+ vshaderStatic(false),
+ vshader1bone(false),
+ vshader4bones(false),
+ fromPath(0xffffffff)
+{
+}
+
+
+
+MaterialList::TextureInfo::TextureInfo() :
+ fromPath(0xffffffff)
+{
+}
+
+
+void MaterialList::getFirstMaterial(std::string& name, MaterialInfo& info)
+{
+ mMaterialIterator = mMaterialNames.begin();
+
+ name = mMaterialIterator->first;
+ info = mMaterialIterator->second;
+}
+
+
+
+bool MaterialList::getNextMaterial(std::string& name, MaterialInfo& info)
+{
+ ++mMaterialIterator;
+ if (mMaterialIterator != mMaterialNames.end())
+ {
+ name = mMaterialIterator->first;
+ info = mMaterialIterator->second;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+
+class XmlParser : public physx::shdfnd::FastXml::Callback
+{
+public:
+ XmlParser(unsigned int fromPath) : mIsMaterial(false)
+ {
+ mMaterialInfo.fromPath = fromPath;
+ }
+
+ virtual ~XmlParser() {}
+
+ const MaterialList::MaterialInfo& getMaterialInfo() { return mMaterialInfo; }
+
+ bool isMaterial() { return mIsMaterial; }
+
+protected:
+
+ // encountered a comment in the XML
+ virtual bool processComment(const char * /*comment*/)
+ {
+ return true;
+ }
+
+ // 'element' is the name of the element that is being closed.
+ // depth is the recursion depth of this element.
+ // Return true to continue processing the XML file.
+ // Return false to stop processing the XML file; leaves the read pointer of the stream right after this close tag.
+ // The bool 'isError' indicates whether processing was stopped due to an error, or intentionally canceled early.
+ virtual bool processClose(const char * /*element*/, unsigned int /*depth*/, bool & /*isError*/)
+ {
+ return true;
+ }
+
+ // return true to continue processing the XML document, false to skip.
+ virtual bool processElement(
+ const char *elementName, // name of the element
+ const char *elementData, // element data, null if none
+ const physx::shdfnd::FastXml::AttributePairs& attr,
+ int /*lineno*/) // line number in the source XML file
+ {
+ if (!mIsMaterial && ::strcmp(elementName, "material") != 0)
+ {
+ // not a material file
+ return false;
+ }
+
+ if (::strcmp(elementName, "material") == 0)
+ {
+ for (int i = 0; i < attr.getNbAttr(); i++)
+ {
+ if (::strcmp(attr.getKey(i), "type") == 0)
+ {
+ mMaterialInfo.isLit = ::strcmp(attr.getValue(i), "lit") == 0;
+ }
+ }
+ mIsMaterial = true;
+ }
+ else if (::strcmp(elementName, "shader") == 0)
+ {
+ int nameIndex = -1;
+ for (int i = 0; i < attr.getNbAttr(); i++)
+ {
+ if (::strcmp(attr.getKey(i), "name") == 0)
+ {
+ nameIndex = i;
+ break;
+ }
+ }
+
+ if (::strcmp(attr.getValue(nameIndex), "vertex") == 0)
+ {
+ // identify the three
+ mMaterialInfo.vshaderStatic |= strstr(elementData, "staticmesh") != NULL;
+ mMaterialInfo.vshader1bone |= strstr(elementData, "skeletalmesh_1bone") != NULL;
+ mMaterialInfo.vshader4bones |= strstr(elementData, "skeletalmesh_4bone") != NULL;
+ }
+ }
+ else if (::strcmp(elementName, "sampler2D") == 0)
+ {
+ int nameIndex = -1;
+ for (int i = 0; i < attr.getNbAttr(); i += 2)
+ {
+ if (::strcmp(attr.getKey(i), "name") == 0)
+ {
+ nameIndex = i;
+ break;
+ }
+ }
+
+ if (::strcmp(attr.getValue(nameIndex), "diffuseTexture") == 0)
+ {
+ mMaterialInfo.diffuseTexture = elementData;
+ }
+ else if (::strcmp(attr.getValue(nameIndex), "normalTexture") == 0)
+ {
+ mMaterialInfo.normalTexture = elementData;
+ }
+ }
+
+ return true;
+ }
+
+ virtual void* fastxml_malloc(unsigned int size)
+ {
+ return ::malloc(size);
+ }
+
+ virtual void fastxml_free(void *mem)
+ {
+ ::free(mem);
+ }
+
+private:
+ bool mIsMaterial;
+ MaterialList::MaterialInfo mMaterialInfo;
+};
+
+
+
+unsigned int MaterialList::addMaterial(const char* directory, const char* prefix, const char* materialName)
+{
+ char filename[256];
+ physx::shdfnd::snprintf(filename, 256, "%s/%s%s", directory, prefix, materialName);
+
+ XmlParser parser((unsigned int)mPaths.size());
+ physx::shdfnd::FastXml* fastXml = physx::shdfnd::createFastXml(&parser);
+ if (fastXml != NULL)
+ {
+ physx::PsFileBuffer fileBuffer(filename, physx::PxFileBuf::OPEN_READ_ONLY);
+ physx::PxInputDataFromPxFileBuf id(fileBuffer);
+ fastXml->processXml(id);
+
+ int errorLineNumber = 0;
+ const char* xmlError = fastXml->getError(errorLineNumber);
+
+ if (xmlError != NULL)
+ {
+ if (strncmp(xmlError, "User aborted", 12) == 0)
+ {
+
+ }
+ else
+ {
+#if PX_WINDOWS_FAMILY
+ char error[512];
+ sprintf_s(error, 512, "%s\n%s", filename, xmlError);
+ ::MessageBox(NULL, error, "MaterialList XML Parse error", MB_OK);
+#endif
+ }
+ }
+
+ fastXml->release();
+ }
+
+ if (parser.isMaterial())
+ {
+ char saneFileName[128];
+ physx::shdfnd::snprintf(saneFileName, 128, "%s%s", prefix, materialName);
+
+ if (mMaterialNames.find(saneFileName) != mMaterialNames.end())
+ {
+ PX_ASSERT(!"Duplicated material name found");
+ }
+ else
+ {
+ mMaterialNames[saneFileName] = parser.getMaterialInfo();
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+
+unsigned int MaterialList::addTexture(const char* /*directory*/, const char* prefix, const char* textureName)
+{
+ char saneFileName[128];
+ physx::shdfnd::snprintf(saneFileName, 128, "%s%s", prefix, textureName);
+
+ if (mTextureNames.find(saneFileName) != mTextureNames.end())
+ {
+ PX_ASSERT(!"duplicated texture found!");
+ }
+ else
+ {
+ TextureInfo info;
+ info.fromPath = (unsigned int)mPaths.size();
+ mTextureNames[saneFileName] = info;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+} // namespace Samples