diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/shared/external/src/ApexMaterial.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'APEX_1.4/shared/external/src/ApexMaterial.cpp')
| -rw-r--r-- | APEX_1.4/shared/external/src/ApexMaterial.cpp | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/APEX_1.4/shared/external/src/ApexMaterial.cpp b/APEX_1.4/shared/external/src/ApexMaterial.cpp new file mode 100644 index 00000000..e05116fb --- /dev/null +++ b/APEX_1.4/shared/external/src/ApexMaterial.cpp @@ -0,0 +1,642 @@ +/* + * 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. + */ + +#define NOMINMAX +#include <stdio.h> + +#include "RenderMesh.h" +#include "PxVec3.h" +#include "PxFileBuf.h" +#include "PsAllocator.h" +#include "ApexUsingNamespace.h" +#include "ApexMaterial.h" + +// Local utilities + +PX_INLINE bool pathsMatch(const char* pathA, const char* pathB, int length) +{ + while (length-- > 0) + { + char a = *pathA++; + char b = *pathB++; + if (a == '\\') + { + a = '/'; + } + if (b == '\\') + { + b = '/'; + } + if (a != b) + { + return false; + } + if (a == '\0') + { + return true; + } + } + + return true; +} + +struct MaterialNameComponents +{ + const char* path; + int pathLen; + const char* filename; + int filenameLen; + const char* ext; + int extLen; + const char* name; + int nameLen; + + bool operator <= (const MaterialNameComponents& c) const + { + if (pathLen > 0 && !pathsMatch(path, c.path, pathLen)) + { + return false; + } + if (filenameLen > 0 && strncmp(filename, c.filename, (uint32_t)filenameLen)) + { + return false; + } + if (extLen > 0 && strncmp(ext, c.ext, (uint32_t)extLen)) + { + return false; + } + return 0 == strncmp(name, c.name, (uint32_t)nameLen); + } +}; + +PX_INLINE void decomposeMaterialName(MaterialNameComponents& components, const char* materialName) +{ + components.path = materialName; + components.pathLen = 0; + components.filename = materialName; + components.filenameLen = 0; + components.ext = materialName; + components.extLen = 0; + components.name = materialName; + components.nameLen = 0; + + if (materialName == NULL) + { + return; + } + + const int len = (int)strlen(materialName); + + // Get name - will exclude any '#' deliniator + components.name += len; + while (components.name > materialName) + { + if (*(components.name - 1) == '#') + { + break; + } + --components.name; + } + components.nameLen = len - (int)(components.name - materialName); + if (components.name == materialName) + { + return; + } + + // Get extension - will include '.' + components.ext = components.name; + while (components.ext > materialName) + { + if (*(--components.ext) == '.') + { + break; + } + } + if (components.ext != materialName) + { + components.extLen = (int)(components.name - components.ext) - 1; + } + + // Get filename + components.filename = components.ext; + while (components.filename > materialName) + { + if (*(components.filename - 1) == '/' || *(components.filename - 1) == '\\') + { + break; + } + --components.filename; + } + if (components.filename != materialName) + { + components.filenameLen = (int)(components.ext - components.filename); + } + + // Get path + components.path = materialName; + components.pathLen = (int)(components.filename - materialName); +} + +PX_INLINE void copyToStringBufferSafe(char*& buffer, int& bufferSize, const char* src, int copySize) +{ + if (copySize >= bufferSize) + { + copySize = bufferSize - 1; + } + memcpy(buffer, src, (uint32_t)copySize); + buffer += copySize; + bufferSize -= copySize; +} + +struct ApexDefaultMaterialLibraryVersion +{ + enum + { + Initial = 0, + AddedBumpMapType, + AddedMaterialNamingConvention, + RemovedMaterialNamingConvention, + + Count, + Current = Count - 1 + }; +}; + + +PX_INLINE void serialize_string(physx::PxFileBuf& stream, const std::string& string) +{ + const uint32_t length = (uint32_t)string.length(); + stream.storeDword(length); + stream.write(string.c_str(), length); +} + +PX_INLINE void deserialize_string(physx::PxFileBuf& stream, std::string& string) +{ + const uint32_t length = stream.readDword(); + char* cstr = (char*)PxAlloca(length + 1); + stream.read(cstr, length); + cstr[length] = '\0'; + string = cstr; +} + + +// ApexDefaultTextureMap functions + +ApexDefaultTextureMap::ApexDefaultTextureMap() : + mPixelFormat(PIXEL_FORMAT_UNKNOWN), + mWidth(0), + mHeight(0), + mComponentCount(0), + mPixelBufferSize(0), + mPixelBuffer(NULL) +{ +} + +ApexDefaultTextureMap& ApexDefaultTextureMap::operator = (const ApexDefaultTextureMap& textureMap) +{ + mPixelFormat = textureMap.mPixelFormat; + mWidth = textureMap.mWidth; + mHeight = textureMap.mHeight; + mComponentCount = textureMap.mComponentCount; + mPixelBufferSize = textureMap.mPixelBufferSize; + mPixelBuffer = new uint8_t[mPixelBufferSize]; + memcpy(mPixelBuffer, textureMap.mPixelBuffer, mPixelBufferSize); + return *this; +} + +ApexDefaultTextureMap::~ApexDefaultTextureMap() +{ + unload(); +} + +void +ApexDefaultTextureMap::build(PixelFormat format, uint32_t width, uint32_t height, uint32_t* fillColor) +{ + uint8_t fillBuffer[4]; + int componentCount; + + switch (format) + { + case PIXEL_FORMAT_RGB: + componentCount = 3; + if (fillColor != NULL) + { + fillBuffer[0] = (*fillColor >> 16) & 0xFF; + fillBuffer[1] = (*fillColor >> 8) & 0xFF; + fillBuffer[2] = (*fillColor) & 0xFF; + } + break; + case PIXEL_FORMAT_BGR_EXT: + componentCount = 3; + if (fillColor != NULL) + { + fillBuffer[0] = (*fillColor) & 0xFF; + fillBuffer[1] = (*fillColor >> 8) & 0xFF; + fillBuffer[2] = (*fillColor >> 16) & 0xFF; + } + break; + case PIXEL_FORMAT_BGRA_EXT: + componentCount = 4; + if (fillColor != NULL) + { + fillBuffer[0] = (*fillColor) & 0xFF; + fillBuffer[1] = (*fillColor >> 8) & 0xFF; + fillBuffer[2] = (*fillColor >> 16) & 0xFF; + fillBuffer[3] = (*fillColor >> 24) & 0xFF; + } + break; + default: + return; // Not supported + } + + unload(); + + mPixelBufferSize = componentCount * width * height; + mPixelBuffer = new uint8_t[mPixelBufferSize]; + mPixelFormat = format; + mComponentCount = (uint32_t)componentCount; + mWidth = width; + mHeight = height; + + if (fillColor != NULL) + { + uint8_t* write = mPixelBuffer; + uint8_t* writeStop = mPixelBuffer + mPixelBufferSize; + uint8_t* read = fillBuffer; + uint8_t* readStop = fillBuffer + componentCount; + while (write < writeStop) + { + *write++ = *read++; + if (read == readStop) + { + read = fillBuffer; + } + } + } +} + +void ApexDefaultTextureMap::unload() +{ + mPixelFormat = PIXEL_FORMAT_UNKNOWN; + mWidth = 0; + mHeight = 0; + mComponentCount = 0; + mPixelBufferSize = 0; + delete [] mPixelBuffer; + mPixelBuffer = NULL; +} + +void ApexDefaultTextureMap::serialize(physx::PxFileBuf& stream) const +{ + stream.storeDword((uint32_t)mPixelFormat); + stream.storeDword(mWidth); + stream.storeDword(mHeight); + stream.storeDword(mComponentCount); + stream.storeDword(mPixelBufferSize); + if (mPixelBufferSize != 0) + { + stream.write(mPixelBuffer, mPixelBufferSize); + } +} + +void ApexDefaultTextureMap::deserialize(physx::PxFileBuf& stream, uint32_t /*version*/) +{ + unload(); + mPixelFormat = (PixelFormat)stream.readDword(); + mWidth = stream.readDword(); + mHeight = stream.readDword(); + mComponentCount = stream.readDword(); + mPixelBufferSize = stream.readDword(); + if (mPixelBufferSize != 0) + { + mPixelBuffer = new uint8_t[mPixelBufferSize]; + stream.read(mPixelBuffer, mPixelBufferSize); + } +} + + +// ApexDefaultMaterial functions +ApexDefaultMaterial::ApexDefaultMaterial() : + mAmbient(0.0f), + mDiffuse(0.0f), + mSpecular(0.0f), + mAlpha(0.0f), + mShininess(0.0f) +{ + for (uint32_t i = 0; i < TEXTURE_MAP_TYPE_COUNT; ++i) + { + mTextureMaps[i] = NULL; + } +} + +ApexDefaultMaterial& ApexDefaultMaterial::operator = (const ApexDefaultMaterial& material) +{ + mName = material.mName; + + for (uint32_t i = 0; i < TEXTURE_MAP_TYPE_COUNT; ++i) + { + if (material.mTextureMaps[i]) + { + mTextureMaps[i] = new ApexDefaultTextureMap(*material.mTextureMaps[i]); + } + else + { + mTextureMaps[i] = NULL; + } + } + + mAmbient = material.mAmbient; + mDiffuse = material.mDiffuse; + mSpecular = material.mSpecular; + mAlpha = material.mAlpha; + mShininess = material.mShininess; + + return *this; +} + +ApexDefaultMaterial::~ApexDefaultMaterial() +{ + unload(); +} + +void ApexDefaultMaterial::setName(const char* name) +{ + mName = name; +} + +bool ApexDefaultMaterial::setTextureMap(TextureMapType type, ApexDefaultTextureMap* textureMap) +{ + if (type < 0 || type >= TEXTURE_MAP_TYPE_COUNT) + { + return false; + } + + delete mTextureMaps[type]; + + mTextureMaps[type] = textureMap; + + return true; +} + +void ApexDefaultMaterial::unload() +{ + mName.clear(); + + for (uint32_t i = 0; i < TEXTURE_MAP_TYPE_COUNT; ++i) + { + delete mTextureMaps[i]; + mTextureMaps[i] = NULL; + } + + mAmbient = physx::PxVec3(0.0f); + mDiffuse = physx::PxVec3(0.0f); + mSpecular = physx::PxVec3(0.0f); + mAlpha = 0.0f; + mShininess = 0.0f; +} + + +void ApexDefaultMaterial::serialize(physx::PxFileBuf& stream) const +{ + serialize_string(stream, mName); + + for (uint32_t i = 0; i < TEXTURE_MAP_TYPE_COUNT; ++i) + { + if (mTextureMaps[i] == NULL) + { + stream.storeDword((uint32_t)0); + } + else + { + stream.storeDword((uint32_t)1); + mTextureMaps[i]->serialize(stream); + } + } + + stream.storeFloat(mAmbient.x); + stream.storeFloat(mAmbient.y); + stream.storeFloat(mAmbient.z); + stream.storeFloat(mDiffuse.x); + stream.storeFloat(mDiffuse.y); + stream.storeFloat(mDiffuse.z); + stream.storeFloat(mSpecular.x); + stream.storeFloat(mSpecular.y); + stream.storeFloat(mSpecular.z); + stream.storeFloat(mAlpha); + stream.storeFloat(mShininess); +} + +void ApexDefaultMaterial::deserialize(physx::PxFileBuf& stream, uint32_t version) +{ + unload(); + + deserialize_string(stream, mName); + + if (version < ApexDefaultMaterialLibraryVersion::AddedBumpMapType) + { + for (uint32_t i = 0; i < 2; ++i) + { + const uint32_t pointerIsValid = stream.readDword(); + if (pointerIsValid) + { + mTextureMaps[i] = new ApexDefaultTextureMap(); + mTextureMaps[i]->deserialize(stream, version); + } + } + mTextureMaps[2] = mTextureMaps[1]; + mTextureMaps[1] = NULL; + } + else + { + for (uint32_t i = 0; i < TEXTURE_MAP_TYPE_COUNT; ++i) + { + const uint32_t pointerIsValid = stream.readDword(); + if (pointerIsValid) + { + mTextureMaps[i] = new ApexDefaultTextureMap(); + mTextureMaps[i]->deserialize(stream, version); + } + } + } + + mAmbient.x = stream.readFloat(); + mAmbient.y = stream.readFloat(); + mAmbient.z = stream.readFloat(); + mDiffuse.x = stream.readFloat(); + mDiffuse.y = stream.readFloat(); + mDiffuse.z = stream.readFloat(); + mSpecular.x = stream.readFloat(); + mSpecular.y = stream.readFloat(); + mSpecular.z = stream.readFloat(); + mAlpha = stream.readFloat(); + mShininess = stream.readFloat(); +} + +TextureMap* ApexDefaultMaterial::getTextureMap(TextureMapType type) const +{ + if (type < 0 || type >= TEXTURE_MAP_TYPE_COUNT) + { + return NULL; + } + + return mTextureMaps[type]; +} + + +// ApexDefaultMaterialLibrary functions +ApexDefaultMaterialLibrary::ApexDefaultMaterialLibrary() +{ +} + +ApexDefaultMaterialLibrary& ApexDefaultMaterialLibrary::operator = (const ApexDefaultMaterialLibrary& materialLibrary) +{ + mMaterials.resize(materialLibrary.getMaterialCount()); + for (uint32_t i = 0; i < materialLibrary.getMaterialCount(); ++i) + { + ApexDefaultMaterial* material = materialLibrary.getMaterial(i); + PX_ASSERT(material != NULL); + mMaterials[i] = new ApexDefaultMaterial(*material); + } + + return *this; +} + +ApexDefaultMaterialLibrary::~ApexDefaultMaterialLibrary() +{ + unload(); +} + +void ApexDefaultMaterialLibrary::unload() +{ + const uint32_t size = (uint32_t)mMaterials.size(); + for (uint32_t i = 0; i < size; ++i) + { + delete mMaterials[i]; + mMaterials[i] = NULL; + } + mMaterials.resize(0); +} + +ApexDefaultMaterial* ApexDefaultMaterialLibrary::getMaterial(uint32_t materialIndex) const +{ + if (materialIndex >= mMaterials.size()) + { + return NULL; + } + + return mMaterials[materialIndex]; +} + +void ApexDefaultMaterialLibrary::merge(const ApexDefaultMaterialLibrary& materialLibrary) +{ + for (uint32_t i = 0; i < materialLibrary.getMaterialCount(); ++i) + { + ApexDefaultMaterial* material = materialLibrary.getMaterial(i); + PX_ASSERT(material != NULL); + const uint32_t size = (uint32_t)mMaterials.size(); + uint32_t j = 0; + for (; j < size; ++j) + { + if (!strcmp(mMaterials[j]->getName(), material->getName())) + { + break; + } + } + if (j == size) + { + ApexDefaultMaterial* newMaterial = new ApexDefaultMaterial(*material); + mMaterials.push_back(newMaterial); + } + } +} + +void ApexDefaultMaterialLibrary::serialize(physx::PxFileBuf& stream) const +{ + stream.storeDword((uint32_t)ApexDefaultMaterialLibraryVersion::Current); + + const uint32_t size = (uint32_t)mMaterials.size(); + stream.storeDword(size); + for (uint32_t i = 0; i < size; ++i) + { + mMaterials[i]->serialize(stream); + } +} + +void ApexDefaultMaterialLibrary::deserialize(physx::PxFileBuf& stream) +{ + unload(); + + uint32_t version = stream.readDword(); + + uint32_t size = stream.readDword(); + mMaterials.resize(size); + for (uint32_t i = 0; i < size; ++i) + { + mMaterials[i] = new ApexDefaultMaterial(); + mMaterials[i]->deserialize(stream, version); + } + + if (version >= ApexDefaultMaterialLibraryVersion::AddedMaterialNamingConvention && version < ApexDefaultMaterialLibraryVersion::RemovedMaterialNamingConvention) + { + stream.readDword(); // Eat naming convention + } +} + +Material* ApexDefaultMaterialLibrary::getMaterial(const char* materialName, bool& created) +{ + int32_t index = findMaterialIndex(materialName); + if (index >= 0) + { + created = false; + return mMaterials[(uint32_t)index]; + } + + ApexDefaultMaterial* newMaterial = new ApexDefaultMaterial(); + newMaterial->setName(materialName); + mMaterials.push_back(newMaterial); + created = true; + return newMaterial; +} + +bool ApexDefaultMaterialLibrary::deleteMaterial(const char* materialName) +{ + int32_t index = findMaterialIndex(materialName); + if (index < 0) + { + return false; + } + + ApexDefaultMaterial* material = mMaterials[(uint32_t)index]; + delete material; + + mMaterials[(uint32_t)index] = mMaterials[mMaterials.size() - 1]; + mMaterials.resize(mMaterials.size() - 1); + + return true; +} + +int32_t ApexDefaultMaterialLibrary::findMaterialIndex(const char* materialName) +{ + const char blank[] = ""; + materialName = materialName ? materialName : blank; + + const uint32_t size = (uint32_t)mMaterials.size(); + int32_t index = 0; + for (; index < (int32_t)size; ++index) + { + const char* existingMaterialName = mMaterials[(uint32_t)index]->getName() ? mMaterials[(uint32_t)index]->getName() : blank; + if (!strcmp(existingMaterialName, materialName)) + { + return index; + } + } + + return -1; +} |