aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2018-01-26 21:55:41 -0800
committerBryan Galdrikian <[email protected]>2018-01-26 21:55:41 -0800
commitac961c33c61b487d982ca9cf9b04ba4ac754ecda (patch)
tree2600d61bb009f065384d548eb16fdc2d12f0f227 /tools
parentUpdated release notes (diff)
downloadblast-ac961c33c61b487d982ca9cf9b04ba4ac754ecda.tar.xz
blast-ac961c33c61b487d982ca9cf9b04ba4ac754ecda.zip
Apex dependency removed (used in ExtImport)
Mesh corruption and crash fit for UV fitting function Updated release_notes.txt
Diffstat (limited to 'tools')
-rw-r--r--tools/ApexImporter/src/ApexDestructibleObjExporter.cpp328
-rw-r--r--tools/ApexImporter/src/ApexDestructibleObjExporter.h4
-rw-r--r--tools/ApexImporter/src/Main.cpp26
-rw-r--r--tools/compiler/cmake/ApexImporter.cmake10
4 files changed, 34 insertions, 334 deletions
diff --git a/tools/ApexImporter/src/ApexDestructibleObjExporter.cpp b/tools/ApexImporter/src/ApexDestructibleObjExporter.cpp
index ca557b3..145b796 100644
--- a/tools/ApexImporter/src/ApexDestructibleObjExporter.cpp
+++ b/tools/ApexImporter/src/ApexDestructibleObjExporter.cpp
@@ -32,7 +32,6 @@
#include "PsFastXml.h"
#include "PsFileBuffer.h"
-#include "PxInputDataFromPxFileBuf.h"
#include <PxVec2.h>
#include <PxVec3.h>
#include <map>
@@ -40,6 +39,7 @@
#include <NvBlastExtAuthoringTypes.h>
+
using namespace nvidia;
using namespace Nv::Blast;
@@ -47,324 +47,15 @@ using namespace Nv::Blast;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Material Parser
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const float VEC_EPS = 1e-4;
-
-class MaterialXmlParser : public physx::shdfnd::FastXml::Callback
-{
-public:
- std::string textureFile;
-
-protected:
- // encountered a comment in the XML
- virtual bool processComment(const char* /*comment*/)
- {
- return true;
- }
-
- 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
- {
- PX_UNUSED(attr);
- 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)
- {
- textureFile = elementData;
- }
- }
-
- return true;
- }
-};
-
-std::string getTextureFromMaterial(const char* materialPath)
-{
- PsFileBuffer fileBuffer(materialPath, general_PxIOStream2::PxFileBuf::OPEN_READ_ONLY);
- PxInputDataFromPxFileBuf inputData(fileBuffer);
- MaterialXmlParser parser;
- physx::shdfnd::FastXml* xml = physx::shdfnd::createFastXml(&parser);
- xml->processXml(inputData, false);
- xml->release();
-
- // trim folders
- std::string textureFile = parser.textureFile.substr(parser.textureFile.find_last_of("/\\") + 1);
-
- return textureFile;
-}
-
-
-bool ApexDestructibleGeometryExporter::exportToFile(NvBlastAsset* asset, const DestructibleAsset& apexAsset, const std::string& name,
+bool ApexDestructibleGeometryExporter::exportToFile(NvBlastAsset* asset, const NvParameterized::Interface* dmeshIfs, ApexImporter::ApexImportTool& tool, const std::string& name,
const std::vector<uint32_t>& chunkReorderInvMap, bool toFbx, bool toObj, bool fbxascii, bool nonSkinned, const std::vector<std::vector<CollisionHull*> >& hulls)
{
- const RenderMeshAsset* rAsset = apexAsset.getRenderMeshAsset();
Nv::Blast::ExporterMeshData meshData;
meshData.asset = asset;
- meshData.submeshCount = rAsset->getSubmeshCount();
- meshData.submeshMats = new Materials[meshData.submeshCount];
- std::vector<std::string> materialPathes;
- materialPathes.reserve(meshData.submeshCount);
- // gather materials
- {
- for (uint32_t submeshIndex = 0; submeshIndex < meshData.submeshCount; ++submeshIndex)
- {
- const char* materialName = rAsset->getMaterialName(submeshIndex);
- std::ostringstream materialPath;
- materialPath << m_materialsDir << "\\" << materialName;
- std::string texturePath = getTextureFromMaterial(materialPath.str().c_str());
- materialPathes.push_back(texturePath);
- meshData.submeshMats[submeshIndex].diffuse_tex = materialPathes[submeshIndex].c_str();
- meshData.submeshMats[submeshIndex].name = materialPathes[submeshIndex].c_str();
- }
- }
- struct vc3Comp
- {
- bool operator()(const PxVec3& a, const PxVec3& b) const
- {
- if (a.x + VEC_EPS < b.x) return true;
- if (a.x - VEC_EPS > b.x) return false;
- if (a.y + VEC_EPS < b.y) return true;
- if (a.y - VEC_EPS > b.y) return false;
- if (a.z + VEC_EPS < b.z) return true;
- return false;
- }
- };
- struct vc2Comp
- {
- bool operator()(const PxVec2& a, const PxVec2& b) const
- {
- if (a.x + VEC_EPS < b.x) return true;
- if (a.x - VEC_EPS > b.x) return false;
- if (a.y + VEC_EPS < b.y) return true;
- return false;
- }
- };
-
- std::vector<PxVec3> compressedPositions;
- std::vector<PxVec3> compressedNormals;
- std::vector<PxVec2> compressedTextures;
-
- std::vector<uint32_t> positionsMapping;
- std::vector<uint32_t> normalsMapping;
- std::vector<uint32_t> texturesMapping;
-
- std::map<PxVec3, uint32_t, vc3Comp> posMap;
- std::map<PxVec3, uint32_t, vc3Comp> normMap;
- std::map<PxVec2, uint32_t, vc2Comp> texMap;
-
-
- // gather data for export
- {
- for (uint32_t submeshIndex = 0; submeshIndex < meshData.submeshCount; ++submeshIndex)
- {
- const RenderSubmesh& currentSubmesh = rAsset->getSubmesh(submeshIndex);
- uint32_t indexCount = currentSubmesh.getVertexBuffer().getVertexCount();
- const VertexFormat& fmt = currentSubmesh.getVertexBuffer().getFormat();
- // Find position buffer index
- uint32_t bufferId = 0;
- {
- for (; bufferId < fmt.getBufferCount(); ++bufferId)
- {
- if (fmt.getBufferSemantic(bufferId) != RenderVertexSemantic::POSITION)
- continue;
- else
- break;
- }
- if (bufferId == fmt.getBufferCount())
- {
- lout() << "Can't find positions buffer" << std::endl;
- return false;
- }
- }
- const PxVec3* posistions = reinterpret_cast<const PxVec3*>(currentSubmesh.getVertexBuffer().getBuffer(bufferId));
- uint32_t oldSize = (uint32_t)positionsMapping.size();
- positionsMapping.resize(oldSize + indexCount);
- for (uint32_t i = 0; i < indexCount; ++i)
- {
- auto it = posMap.find(posistions[i]);
- if (it == posMap.end())
- {
- posMap[posistions[i]] = (uint32_t)compressedPositions.size();
- positionsMapping[oldSize + i] = (uint32_t)compressedPositions.size();
- compressedPositions.push_back(posistions[i]);
- }
- else
- {
- positionsMapping[oldSize + i] = it->second;
- }
- }
- }
-
- for (uint32_t submeshIndex = 0; submeshIndex < meshData.submeshCount; ++submeshIndex)
- {
- const RenderSubmesh& currentSubmesh = rAsset->getSubmesh(submeshIndex);
- uint32_t indexCount = currentSubmesh.getVertexBuffer().getVertexCount();
- const VertexFormat& fmt = currentSubmesh.getVertexBuffer().getFormat();
- // Find normal buffer index
- uint32_t bufferId = 0;
- {
- for (; bufferId < fmt.getBufferCount(); ++bufferId)
- {
- if (fmt.getBufferSemantic(bufferId) != RenderVertexSemantic::NORMAL)
- continue;
- else
- break;
- }
- if (bufferId == fmt.getBufferCount())
- {
- lout() << "Can't find positions buffer" << std::endl;
- return false;
- }
- }
- const PxVec3* normals = reinterpret_cast<const PxVec3*>(currentSubmesh.getVertexBuffer().getBuffer(bufferId));
- uint32_t oldSize = (uint32_t)normalsMapping.size();
- normalsMapping.resize(oldSize + indexCount);
- for (uint32_t i = 0; i < indexCount; ++i)
- {
- auto it = normMap.find(normals[i]);
- if (it == normMap.end())
- {
- normMap[normals[i]] = (uint32_t)compressedNormals.size();
- normalsMapping[oldSize + i] = (uint32_t)compressedNormals.size();
- compressedNormals.push_back(normals[i]);
- }
- else
- {
- normalsMapping[oldSize + i] = it->second;
- }
- }
-
- }
- for (uint32_t submeshIndex = 0; submeshIndex < meshData.submeshCount; ++submeshIndex)
- {
- const RenderSubmesh& currentSubmesh = rAsset->getSubmesh(submeshIndex);
- uint32_t indexCount = currentSubmesh.getVertexBuffer().getVertexCount();
- const VertexFormat& fmt = currentSubmesh.getVertexBuffer().getFormat();
-
- // Find texture coords buffer index
- uint32_t bufferId = 0;
- {
- for (; bufferId < fmt.getBufferCount(); ++bufferId)
- {
- if (fmt.getBufferSemantic(bufferId) != RenderVertexSemantic::TEXCOORD0)
- continue;
- else
- break;
- }
- if (bufferId == fmt.getBufferCount())
- {
- lout() << "Can't find positions buffer" << std::endl;
- return false;
- }
- }
- const PxVec2* texCoord = reinterpret_cast<const PxVec2*>(currentSubmesh.getVertexBuffer().getBuffer(bufferId));
- uint32_t oldSize = (uint32_t)texturesMapping.size();
- texturesMapping.resize(oldSize + indexCount);
- for (uint32_t i = 0; i < indexCount; ++i)
- {
- auto it = texMap.find(texCoord[i]);
- if (it == texMap.end())
- {
- texMap[texCoord[i]] = (uint32_t)compressedTextures.size();
- texturesMapping[oldSize + i] = (uint32_t)compressedTextures.size();
- compressedTextures.push_back(texCoord[i]);
- }
- else
- {
- texturesMapping[oldSize + i] = it->second;
- }
- }
- }
- for (uint32_t i = 0; i < compressedTextures.size(); ++i)
- {
- std::swap(compressedTextures[i].x, compressedTextures[i].y);
- }
-
-
- meshData.positionsCount = (uint32_t)compressedPositions.size();
- //meshData.positions = compressedPositions.data();
- meshData.positions = new PxVec3[meshData.positionsCount];
- memcpy(meshData.positions, compressedPositions.data(), sizeof(PxVec3) * meshData.positionsCount);
- meshData.normalsCount = (uint32_t)compressedNormals.size();
- //meshData.normals = compressedNormals.data();
- meshData.normals = new PxVec3[meshData.normalsCount];
- memcpy(meshData.normals, compressedNormals.data(), sizeof(PxVec3) * meshData.normalsCount);
- meshData.uvsCount = (uint32_t)compressedTextures.size();
- //meshData.uvs = compressedTextures.data();
- meshData.uvs = new PxVec2[meshData.uvsCount];
- memcpy(meshData.uvs, compressedTextures.data(), sizeof(PxVec2) * meshData.uvsCount);
+ tool.importRendermesh(chunkReorderInvMap, dmeshIfs, &meshData, m_materialsDir.c_str());
- uint32_t apexChunkCount = apexAsset.getChunkCount();
- meshData.meshCount = (uint32_t)chunkReorderInvMap.size();
- meshData.submeshOffsets = new uint32_t[meshData.meshCount * meshData.submeshCount + 1]{ 0 };
-
- //count total number of indices
- for (uint32_t chunkIndex = 0; chunkIndex < meshData.meshCount; ++chunkIndex)
- {
- uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
- if (apexChunkIndex >= apexChunkCount)
- {
- PX_ALWAYS_ASSERT();
- continue;
- }
- uint32_t part = apexAsset.getPartIndex(apexChunkIndex);
- for (uint32_t submeshIndex = 0; submeshIndex < meshData.submeshCount; ++submeshIndex)
- {
- uint32_t indexCount = rAsset->getSubmesh(submeshIndex).getIndexCount(part);
- uint32_t* firstIdx = meshData.submeshOffsets + chunkIndex * meshData.submeshCount + submeshIndex;
- *(firstIdx + 1) = *firstIdx + indexCount;
- }
- }
- meshData.posIndex = new uint32_t[meshData.submeshOffsets[meshData.meshCount * meshData.submeshCount]];
- meshData.normIndex = new uint32_t[meshData.submeshOffsets[meshData.meshCount * meshData.submeshCount]];
- meshData.texIndex = new uint32_t[meshData.submeshOffsets[meshData.meshCount * meshData.submeshCount]];
- //copy indices
- for (uint32_t chunkIndex = 0; chunkIndex < meshData.meshCount; ++chunkIndex)
- {
- uint32_t apexChunkIndex = chunkReorderInvMap[chunkIndex];
- if (apexChunkIndex >= apexChunkCount)
- {
- PX_ALWAYS_ASSERT();
- continue;
- }
- uint32_t part = apexAsset.getPartIndex(apexChunkIndex);
- uint32_t offset = 0;
- for (uint32_t submeshIndex = 0; submeshIndex < meshData.submeshCount; ++submeshIndex)
- {
- const RenderSubmesh& currentSubmesh = rAsset->getSubmesh(submeshIndex);
- const uint32_t* indexArray = currentSubmesh.getIndexBuffer(part);
- uint32_t indexCount = currentSubmesh.getIndexCount(part);
- uint32_t firstIdx = meshData.submeshOffsets[chunkIndex * meshData.submeshCount + submeshIndex];
-
- for (uint32_t i = 0; i < indexCount;++i)
- {
- meshData.posIndex[firstIdx + i] = positionsMapping[indexArray[i] + offset];
- meshData.normIndex[firstIdx + i] = normalsMapping[indexArray[i] + offset];
- meshData.texIndex[firstIdx + i] = texturesMapping[indexArray[i] + offset];
- }
- offset += currentSubmesh.getVertexBuffer().getVertexCount();
- }
- }
-
if (!hulls.empty())
{
meshData.hullsOffsets = new uint32_t[hulls.size() + 1]{ 0 };
@@ -385,7 +76,6 @@ bool ApexDestructibleGeometryExporter::exportToFile(NvBlastAsset* asset, const D
{
meshData.hulls = nullptr;
meshData.hullsOffsets = nullptr;
-
}
if (toObj)
{
@@ -411,9 +101,15 @@ bool ApexDestructibleGeometryExporter::exportToFile(NvBlastAsset* asset, const D
delete[] meshData.positions;
delete[] meshData.submeshOffsets;
delete[] meshData.texIndex;
- delete[] meshData.submeshMats;
+
delete[] meshData.uvs;
- }
- return true;
+ for (uint32_t i = 0; i < meshData.submeshCount; ++i)
+ {
+ delete[] meshData.submeshMats[i].diffuse_tex;
+ delete[] meshData.submeshMats[i].name;
+ }
+ delete[] meshData.submeshMats;
+
+ return true;
}
diff --git a/tools/ApexImporter/src/ApexDestructibleObjExporter.h b/tools/ApexImporter/src/ApexDestructibleObjExporter.h
index f5ead5c..3ecb9ae 100644
--- a/tools/ApexImporter/src/ApexDestructibleObjExporter.h
+++ b/tools/ApexImporter/src/ApexDestructibleObjExporter.h
@@ -31,8 +31,8 @@
#include <string>
#include <vector>
-#include "DestructibleAsset.h"
#include <NvBlastExtAuthoringCollisionBuilder.h>
+#include <NvBlastExtApexImportTool.h>
@@ -55,7 +55,7 @@ public:
ApexDestructibleGeometryExporter(std::string materialsDir, std::string exportDir) : m_materialsDir(materialsDir), m_exportDir(exportDir)
{}
- bool exportToFile(NvBlastAsset* asset, const nvidia::apex::DestructibleAsset& apexAsset, const std::string& name,
+ bool exportToFile(NvBlastAsset* asset, const NvParameterized::Interface* dmeshIfs, ApexImporter::ApexImportTool& tool, const std::string& name,
const std::vector<uint32_t>& chunkReorderInvMap, bool toFbx, bool toObj, bool fbxascii, bool nonSkinned,
const std::vector<std::vector<CollisionHull*> >& hulls = std::vector<std::vector<CollisionHull*> >());
diff --git a/tools/ApexImporter/src/Main.cpp b/tools/ApexImporter/src/Main.cpp
index b47f578..bc7253b 100644
--- a/tools/ApexImporter/src/Main.cpp
+++ b/tools/ApexImporter/src/Main.cpp
@@ -32,10 +32,6 @@
#endif
#include "PxPhysicsAPI.h"
-#include "Apex.h"
-#include <ModuleDestructible.h>
-#include <DestructibleAsset.h>
-#include "NullRenderer.h"
#include "NvBlastExtApexImportTool.h"
#include "Log.h"
#include <string>
@@ -53,6 +49,8 @@
#include "NvBlastExtLlSerialization.h"
#include "NvBlastExtTkSerialization.h"
#include "NvBlastExtPxSerialization.h"
+#include <nvparameterized\NvSerializer.h>
+#include <PsFileBuffer.h>
#define DEFAULT_INPUT_FILE "../../../tools/ApexImporter/resources/assets/table.apb"
#define DEFAULT_OUTPUT_DIR "C:/TestFracturer/"
#define DEFAULT_ASSET_NAME "table"
@@ -103,18 +101,20 @@ void run(const std::string& inFilepath, const std::string& outDir, const std::st
ApexImportTool blast;
lout() << Log::TYPE_INFO << "ApexImportTool initialization" << std::endl;
- blast.initialize();
if (!blast.isValid())
{
lout() << Log::TYPE_ERROR << "Failed to create BlastSDK" << std::endl;
return;
}
+
// load asset
lout() << Log::TYPE_INFO << "Loading asset: " << inFilepath << std::endl;
- physx::PxFileBuf* apexAssetStream = nvidia::apex::GetApexSDK()->createStream(inFilepath.c_str(), physx::PxFileBuf::OPEN_READ_ONLY);
- nvidia::apex::DestructibleAsset* apexAsset = blast.loadAssetFromFile(apexAssetStream);
- if (!apexAsset)
+ physx::PxFileBuf* apexAssetStream = PX_NEW(physx::general_PxIOStream::PsFileBuffer)(inFilepath.c_str(), physx::PxFileBuf::OPEN_READ_ONLY);
+
+ NvParameterized::Serializer::DeserializedData data;
+ blast.loadAssetFromFile(apexAssetStream, data);
+ if (data.size() == 0)
{
return;
}
@@ -138,14 +138,14 @@ void run(const std::string& inFilepath, const std::string& outDir, const std::st
std::vector<ExtPxAssetDesc::ChunkDesc> physicsChunks;
std::vector<ExtPxAssetDesc::SubchunkDesc> physicsSubchunks;
- bool result = blast.importApexAsset(chunkReorderInvMap, apexAsset, chunkDesc, bondDescs, flags, config);
+ bool result = blast.importApexAsset(chunkReorderInvMap, data[0], chunkDesc, bondDescs, flags, config);
if (!result)
{
lout() << Log::TYPE_ERROR << "Failed to build Blast asset data" << std::endl;
return;
};
std::vector<std::vector<CollisionHull*>> hulls;
- result = blast.getCollisionGeometry(apexAsset, static_cast<uint32_t>(chunkDesc.size()), chunkReorderInvMap, flags, physicsChunks, physicsSubchunks, hulls);
+ result = blast.getCollisionGeometry(data[0], static_cast<uint32_t>(chunkDesc.size()), chunkReorderInvMap, flags, physicsChunks, physicsSubchunks, hulls);
if (!result)
{
lout() << Log::TYPE_ERROR << "Failed to build physics data" << std::endl;
@@ -155,7 +155,7 @@ void run(const std::string& inFilepath, const std::string& outDir, const std::st
// save asset
lout() << Log::TYPE_INFO << "Saving blast asset: " << outDir << std::endl;
- BlastDataExporter blExpr(framework, nvidia::apex::GetApexSDK()->getPhysXSDK(), nvidia::apex::GetApexSDK()->getCookingInterface());
+ BlastDataExporter blExpr(framework, blast.getPxSdk(), blast.getCooking());
NvBlastAsset* llAsset = blExpr.createLlBlastAsset(bondDescs, chunkDesc);
std::cout <<"Chunk count: " << NvBlastAssetGetChunkCount(llAsset, NULL) << std::endl;
@@ -187,11 +187,11 @@ void run(const std::string& inFilepath, const std::string& outDir, const std::st
ApexDestructibleGeometryExporter objSaver(inputDir, outDir);
if (fbxCollision)
{
- objSaver.exportToFile(llAsset, *apexAsset, assetName, chunkReorderInvMap, fbx, obj, fbxascii, nonSkinned, hulls);
+ objSaver.exportToFile(llAsset, data[0], blast, assetName, chunkReorderInvMap, fbx, obj, fbxascii, nonSkinned, hulls);
}
else
{
- objSaver.exportToFile(llAsset, *apexAsset, assetName, chunkReorderInvMap, fbx, obj, fbxascii, nonSkinned);
+ objSaver.exportToFile(llAsset, data[0], blast, assetName, chunkReorderInvMap, fbx, obj, fbxascii, nonSkinned);
}
NVBLAST_FREE(llAsset);
}
diff --git a/tools/compiler/cmake/ApexImporter.cmake b/tools/compiler/cmake/ApexImporter.cmake
index cc5c463..f8e4a45 100644
--- a/tools/compiler/cmake/ApexImporter.cmake
+++ b/tools/compiler/cmake/ApexImporter.cmake
@@ -5,8 +5,9 @@
SET(APEXIMPORTER_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ApexImporter/src)
SET(TOOLS_COMMON_DIR ${BLAST_ROOT_DIR}/tools/common)
SET(TOOLS_COMMON_DIR ${BLAST_ROOT_DIR}/tools/common)
+SET(APEX_MODULES_DIR ${BLAST_ROOT_DIR}/sdk/extensions/import/apexmodules)
+
FIND_PACKAGE(PhysXSDK $ENV{PM_PhysX_VERSION} REQUIRED)
-FIND_PACKAGE(ApexSDK $ENV{PM_Apex_VERSION} REQUIRED)
FIND_PACKAGE(PxSharedSDK $ENV{PM_PxShared_VERSION} REQUIRED)
FIND_PACKAGE(tclap $ENV{PM_tclap_VERSION} REQUIRED)
FIND_PACKAGE(FBXSDK $ENV{PM_FBXSDK_VERSION} REQUIRED)
@@ -47,10 +48,13 @@ TARGET_INCLUDE_DIRECTORIES(ApexImporter
PRIVATE ${TOOLS_COMMON_DIR}
PRIVATE ${PHYSXSDK_INCLUDE_DIRS}
- PRIVATE ${APEXSDK_INCLUDE_DIRS}
PRIVATE ${PXSHAREDSDK_INCLUDE_DIRS}
PRIVATE ${TCLAP_INCLUDE_DIRS}
PRIVATE ${FBXSDK_INCLUDE_DIRS}
+
+ PRIVATE ${APEX_MODULES_DIR}/nvparutils
+
+ PRIVATE ${APEX_MODULES_DIR}/NvParameterized/include
)
TARGET_COMPILE_DEFINITIONS(ApexImporter
@@ -72,6 +76,6 @@ TARGET_LINK_LIBRARIES(ApexImporter
ADD_CUSTOM_COMMAND(TARGET ApexImporter POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
- ${APEXSDK_DLLS} ${PHYSXSDK_DLLS} ${PXSHAREDSDK_DLLS}
+ ${PHYSXSDK_DLLS} ${PXSHAREDSDK_DLLS}
${BL_EXE_OUTPUT_DIR}
)