aboutsummaryrefslogtreecommitdiff
path: root/sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2018-05-31 11:36:08 -0700
committerBryan Galdrikian <[email protected]>2018-05-31 11:36:08 -0700
commit7115f60b91b5717d90f643fd692010905c7004db (patch)
treeeffd68c6978751c517d54c2f2bb5bb6e7dc93e18 /sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp
parentUpdating BlastTool zip (diff)
downloadblast-7115f60b91b5717d90f643fd692010905c7004db.tar.xz
blast-7115f60b91b5717d90f643fd692010905c7004db.zip
Blast 1.1.3. See docs/release_notes.txt.v1.1.3_rc1
Diffstat (limited to 'sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp')
-rwxr-xr-x[-rw-r--r--]sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp720
1 files changed, 360 insertions, 360 deletions
diff --git a/sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp b/sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp
index ea01ab5..6f0d2ca 100644..100755
--- a/sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp
+++ b/sdk/extensions/authoring/source/VHACD/src/VHACD-ASYNC.cpp
@@ -1,360 +1,360 @@
-#include "../public/VHACD.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <thread>
-#include <atomic>
-#include <mutex>
-#include <string>
-#include <float.h>
-
-#define ENABLE_ASYNC 1
-
-#define HACD_ALLOC(x) malloc(x)
-#define HACD_FREE(x) free(x)
-#define HACD_ASSERT(x) assert(x)
-
-namespace VHACD
-{
-
-class MyHACD_API : public VHACD::IVHACD, public VHACD::IVHACD::IUserCallback, VHACD::IVHACD::IUserLogger
-{
-public:
- MyHACD_API(void)
- {
- mVHACD = VHACD::CreateVHACD();
- }
-
- virtual ~MyHACD_API(void)
- {
- releaseHACD();
- Cancel();
- mVHACD->Release();
- }
-
-
- virtual bool Compute(const double* const _points,
- const uint32_t countPoints,
- const uint32_t* const _triangles,
- const uint32_t countTriangles,
- const Parameters& _desc) final
- {
-#if ENABLE_ASYNC
- Cancel(); // if we previously had a solution running; cancel it.
- releaseHACD();
-
- // We need to copy the input vertices and triangles into our own buffers so we can operate
- // on them safely from the background thread.
- mVertices = (double *)HACD_ALLOC(sizeof(double)*countPoints * 3);
- mIndices = (uint32_t *)HACD_ALLOC(sizeof(uint32_t)*countTriangles * 3);
- memcpy(mVertices, _points, sizeof(double)*countPoints * 3);
- memcpy(mIndices, _triangles, sizeof(uint32_t)*countTriangles * 3);
- mRunning = true;
- mThread = new std::thread([this, countPoints, countTriangles, _desc]()
- {
- ComputeNow(mVertices, countPoints, mIndices, countTriangles, _desc);
- mRunning = false;
- });
-#else
- releaseHACD();
- ComputeNow(_points, countPoints, _triangles, countTriangles, _desc);
-#endif
- return true;
- }
-
- bool ComputeNow(const double* const points,
- const uint32_t countPoints,
- const uint32_t* const triangles,
- const uint32_t countTriangles,
- const Parameters& _desc)
- {
- uint32_t ret = 0;
-
- mHullCount = 0;
- mCallback = _desc.m_callback;
- mLogger = _desc.m_logger;
-
- IVHACD::Parameters desc = _desc;
- // Set our intercepting callback interfaces if non-null
- desc.m_callback = desc.m_callback ? this : nullptr;
- desc.m_logger = desc.m_logger ? this : nullptr;
-
- if ( countPoints )
- {
- bool ok = mVHACD->Compute(points, countPoints, triangles, countTriangles, desc);
- if (ok)
- {
- ret = mVHACD->GetNConvexHulls();
- mHulls = new IVHACD::ConvexHull[ret];
- for (uint32_t i = 0; i < ret; i++)
- {
- VHACD::IVHACD::ConvexHull vhull;
- mVHACD->GetConvexHull(i, vhull);
- VHACD::IVHACD::ConvexHull h;
- h.m_nPoints = vhull.m_nPoints;
- h.m_points = (double *)HACD_ALLOC(sizeof(double) * 3 * h.m_nPoints);
- memcpy(h.m_points, vhull.m_points, sizeof(double) * 3 * h.m_nPoints);
- h.m_nTriangles = vhull.m_nTriangles;
- h.m_triangles = (uint32_t *)HACD_ALLOC(sizeof(uint32_t) * 3 * h.m_nTriangles);
- memcpy(h.m_triangles, vhull.m_triangles, sizeof(uint32_t) * 3 * h.m_nTriangles);
- h.m_volume = vhull.m_volume;
- h.m_center[0] = vhull.m_center[0];
- h.m_center[1] = vhull.m_center[1];
- h.m_center[2] = vhull.m_center[2];
- mHulls[i] = h;
- if (mCancel)
- {
- ret = 0;
- break;
- }
- }
- }
- }
-
- mHullCount = ret;
- return ret ? true : false;
- }
-
- void releaseHull(VHACD::IVHACD::ConvexHull &h)
- {
- HACD_FREE((void *)h.m_triangles);
- HACD_FREE((void *)h.m_points);
- h.m_triangles = nullptr;
- h.m_points = nullptr;
- }
-
- virtual void GetConvexHull(const uint32_t index, VHACD::IVHACD::ConvexHull& ch) const final
- {
- if ( index < mHullCount )
- {
- ch = mHulls[index];
- }
- }
-
- void releaseHACD(void) // release memory associated with the last HACD request
- {
- for (uint32_t i=0; i<mHullCount; i++)
- {
- releaseHull(mHulls[i]);
- }
- delete[]mHulls;
- mHulls = nullptr;
- mHullCount = 0;
- HACD_FREE(mVertices);
- mVertices = nullptr;
- HACD_FREE(mIndices);
- mIndices = nullptr;
- }
-
-
- virtual void release(void) // release the HACD_API interface
- {
- delete this;
- }
-
- virtual uint32_t getHullCount(void)
- {
- return mHullCount;
- }
-
- virtual void Cancel() final
- {
- if (mRunning)
- {
- mVHACD->Cancel(); // Set the cancel signal to the base VHACD
- }
- if (mThread)
- {
- mThread->join(); // Wait for the thread to fully exit before we delete the instance
- delete mThread;
- mThread = nullptr;
- Log("Convex Decomposition thread canceled\n");
- }
- mCancel = false; // clear the cancel semaphore
- }
-
- virtual bool Compute(const float* const points,
- const uint32_t countPoints,
- const uint32_t* const triangles,
- const uint32_t countTriangles,
- const Parameters& params) final
- {
-
- double *vertices = (double *)HACD_ALLOC(sizeof(double)*countPoints * 3);
- const float *source = points;
- double *dest = vertices;
- for (uint32_t i = 0; i < countPoints; i++)
- {
- dest[0] = source[0];
- dest[1] = source[1];
- dest[2] = source[2];
- dest += 3;
- source += 3;
- }
-
- bool ret = Compute(vertices, countPoints, triangles, countTriangles, params);
- HACD_FREE(vertices);
- return ret;
- }
-
- virtual uint32_t GetNConvexHulls() const final
- {
- processPendingMessages();
- return mHullCount;
- }
-
- virtual void Clean(void) final // release internally allocated memory
- {
- Cancel();
- releaseHACD();
- mVHACD->Clean();
- }
-
- virtual void Release(void) final // release IVHACD
- {
- delete this;
- }
-
- virtual bool OCLInit(void* const oclDevice,
- IVHACD::IUserLogger* const logger = 0) final
- {
- return mVHACD->OCLInit(oclDevice, logger);
- }
-
- virtual bool OCLRelease(IVHACD::IUserLogger* const logger = 0) final
- {
- return mVHACD->OCLRelease(logger);
- }
-
- virtual void Update(const double overallProgress,
- const double stageProgress,
- const double operationProgress,
- const char* const stage,
- const char* const operation) final
- {
- mMessageMutex.lock();
- mHaveUpdateMessage = true;
- mOverallProgress = overallProgress;
- mStageProgress = stageProgress;
- mOperationProgress = operationProgress;
- mStage = std::string(stage);
- mOperation = std::string(operation);
- mMessageMutex.unlock();
- }
-
- virtual void Log(const char* const msg) final
- {
- mMessageMutex.lock();
- mHaveLogMessage = true;
- mMessage = std::string(msg);
- mMessageMutex.unlock();
- }
-
- virtual bool IsReady(void) const final
- {
- processPendingMessages();
- return !mRunning;
- }
-
- // As a convenience for the calling application we only send it update and log messages from it's own main
- // thread. This reduces the complexity burden on the caller by making sure it only has to deal with log
- // messages in it's main application thread.
- void processPendingMessages(void) const
- {
- // If we have a new update message and the user has specified a callback we send the message and clear the semaphore
- if (mHaveUpdateMessage && mCallback)
- {
- mMessageMutex.lock();
- mCallback->Update(mOverallProgress, mStageProgress, mOperationProgress, mStage.c_str(), mOperation.c_str());
- mHaveUpdateMessage = false;
- mMessageMutex.unlock();
- }
- // If we have a new log message and the user has specified a callback we send the message and clear the semaphore
- if (mHaveLogMessage && mLogger)
- {
- mMessageMutex.lock();
- mLogger->Log(mMessage.c_str());
- mHaveLogMessage = false;
- mMessageMutex.unlock();
- }
- }
-
- // Will compute the center of mass of the convex hull decomposition results and return it
- // in 'centerOfMass'. Returns false if the center of mass could not be computed.
- virtual bool ComputeCenterOfMass(double centerOfMass[3]) const
- {
- bool ret = false;
-
- centerOfMass[0] = 0;
- centerOfMass[1] = 0;
- centerOfMass[2] = 0;
-
- if (mVHACD && IsReady() )
- {
- ret = mVHACD->ComputeCenterOfMass(centerOfMass);
- }
- return ret;
- }
-
- // Will analyze the HACD results and compute the constraints solutions.
- // It will analyze the point at which any two convex hulls touch each other and
- // return the total number of constraint pairs found
- virtual uint32_t ComputeConstraints(void) final
- {
- uint32_t ret = 0;
- if (mVHACD && IsReady())
- {
- ret = mVHACD->ComputeConstraints();
- }
- return ret;
- }
-
- virtual const Constraint *GetConstraint(uint32_t index) const final
- {
- const Constraint * ret = nullptr;
- if (mVHACD && IsReady())
- {
- ret = mVHACD->GetConstraint(index);
- }
- return ret;
-
- }
-
-
-
-private:
- double *mVertices{ nullptr };
- uint32_t *mIndices{ nullptr };
- std::atomic< uint32_t> mHullCount{ 0 };
- VHACD::IVHACD::ConvexHull *mHulls{ nullptr };
- VHACD::IVHACD::IUserCallback *mCallback{ nullptr };
- VHACD::IVHACD::IUserLogger *mLogger{ nullptr };
- VHACD::IVHACD *mVHACD{ nullptr };
- std::thread *mThread{ nullptr };
- std::atomic< bool > mRunning{ false };
- std::atomic<bool> mCancel{ false };
-
- // Thread safe caching mechanism for messages and update status.
- // This is so that caller always gets messages in his own thread
- // Member variables are marked as 'mutable' since the message dispatch function
- // is called from const query methods.
- mutable std::mutex mMessageMutex;
- mutable std::atomic< bool > mHaveUpdateMessage{ false };
- mutable std::atomic< bool > mHaveLogMessage{ false };
- mutable double mOverallProgress{ 0 };
- mutable double mStageProgress{ 0 };
- mutable double mOperationProgress{ 0 };
- mutable std::string mStage;
- mutable std::string mOperation;
- mutable std::string mMessage;
-};
-
-IVHACD* CreateVHACD_ASYNC(void)
-{
- MyHACD_API *m = new MyHACD_API;
- return static_cast<IVHACD *>(m);
-}
-
-
-}; // end of VHACD namespace
-
+#include "../public/VHACD.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <thread>
+#include <atomic>
+#include <mutex>
+#include <string>
+#include <float.h>
+
+#define ENABLE_ASYNC 1
+
+#define HACD_ALLOC(x) malloc(x)
+#define HACD_FREE(x) free(x)
+#define HACD_ASSERT(x) assert(x)
+
+namespace VHACD
+{
+
+class MyHACD_API : public VHACD::IVHACD, public VHACD::IVHACD::IUserCallback, VHACD::IVHACD::IUserLogger
+{
+public:
+ MyHACD_API(void)
+ {
+ mVHACD = VHACD::CreateVHACD();
+ }
+
+ virtual ~MyHACD_API(void)
+ {
+ releaseHACD();
+ Cancel();
+ mVHACD->Release();
+ }
+
+
+ virtual bool Compute(const double* const _points,
+ const uint32_t countPoints,
+ const uint32_t* const _triangles,
+ const uint32_t countTriangles,
+ const Parameters& _desc) final
+ {
+#if ENABLE_ASYNC
+ Cancel(); // if we previously had a solution running; cancel it.
+ releaseHACD();
+
+ // We need to copy the input vertices and triangles into our own buffers so we can operate
+ // on them safely from the background thread.
+ mVertices = (double *)HACD_ALLOC(sizeof(double)*countPoints * 3);
+ mIndices = (uint32_t *)HACD_ALLOC(sizeof(uint32_t)*countTriangles * 3);
+ memcpy(mVertices, _points, sizeof(double)*countPoints * 3);
+ memcpy(mIndices, _triangles, sizeof(uint32_t)*countTriangles * 3);
+ mRunning = true;
+ mThread = new std::thread([this, countPoints, countTriangles, _desc]()
+ {
+ ComputeNow(mVertices, countPoints, mIndices, countTriangles, _desc);
+ mRunning = false;
+ });
+#else
+ releaseHACD();
+ ComputeNow(_points, countPoints, _triangles, countTriangles, _desc);
+#endif
+ return true;
+ }
+
+ bool ComputeNow(const double* const points,
+ const uint32_t countPoints,
+ const uint32_t* const triangles,
+ const uint32_t countTriangles,
+ const Parameters& _desc)
+ {
+ uint32_t ret = 0;
+
+ mHullCount = 0;
+ mCallback = _desc.m_callback;
+ mLogger = _desc.m_logger;
+
+ IVHACD::Parameters desc = _desc;
+ // Set our intercepting callback interfaces if non-null
+ desc.m_callback = desc.m_callback ? this : nullptr;
+ desc.m_logger = desc.m_logger ? this : nullptr;
+
+ if ( countPoints )
+ {
+ bool ok = mVHACD->Compute(points, countPoints, triangles, countTriangles, desc);
+ if (ok)
+ {
+ ret = mVHACD->GetNConvexHulls();
+ mHulls = new IVHACD::ConvexHull[ret];
+ for (uint32_t i = 0; i < ret; i++)
+ {
+ VHACD::IVHACD::ConvexHull vhull;
+ mVHACD->GetConvexHull(i, vhull);
+ VHACD::IVHACD::ConvexHull h;
+ h.m_nPoints = vhull.m_nPoints;
+ h.m_points = (double *)HACD_ALLOC(sizeof(double) * 3 * h.m_nPoints);
+ memcpy(h.m_points, vhull.m_points, sizeof(double) * 3 * h.m_nPoints);
+ h.m_nTriangles = vhull.m_nTriangles;
+ h.m_triangles = (uint32_t *)HACD_ALLOC(sizeof(uint32_t) * 3 * h.m_nTriangles);
+ memcpy(h.m_triangles, vhull.m_triangles, sizeof(uint32_t) * 3 * h.m_nTriangles);
+ h.m_volume = vhull.m_volume;
+ h.m_center[0] = vhull.m_center[0];
+ h.m_center[1] = vhull.m_center[1];
+ h.m_center[2] = vhull.m_center[2];
+ mHulls[i] = h;
+ if (mCancel)
+ {
+ ret = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ mHullCount = ret;
+ return ret ? true : false;
+ }
+
+ void releaseHull(VHACD::IVHACD::ConvexHull &h)
+ {
+ HACD_FREE((void *)h.m_triangles);
+ HACD_FREE((void *)h.m_points);
+ h.m_triangles = nullptr;
+ h.m_points = nullptr;
+ }
+
+ virtual void GetConvexHull(const uint32_t index, VHACD::IVHACD::ConvexHull& ch) const final
+ {
+ if ( index < mHullCount )
+ {
+ ch = mHulls[index];
+ }
+ }
+
+ void releaseHACD(void) // release memory associated with the last HACD request
+ {
+ for (uint32_t i=0; i<mHullCount; i++)
+ {
+ releaseHull(mHulls[i]);
+ }
+ delete[]mHulls;
+ mHulls = nullptr;
+ mHullCount = 0;
+ HACD_FREE(mVertices);
+ mVertices = nullptr;
+ HACD_FREE(mIndices);
+ mIndices = nullptr;
+ }
+
+
+ virtual void release(void) // release the HACD_API interface
+ {
+ delete this;
+ }
+
+ virtual uint32_t getHullCount(void)
+ {
+ return mHullCount;
+ }
+
+ virtual void Cancel() final
+ {
+ if (mRunning)
+ {
+ mVHACD->Cancel(); // Set the cancel signal to the base VHACD
+ }
+ if (mThread)
+ {
+ mThread->join(); // Wait for the thread to fully exit before we delete the instance
+ delete mThread;
+ mThread = nullptr;
+ Log("Convex Decomposition thread canceled\n");
+ }
+ mCancel = false; // clear the cancel semaphore
+ }
+
+ virtual bool Compute(const float* const points,
+ const uint32_t countPoints,
+ const uint32_t* const triangles,
+ const uint32_t countTriangles,
+ const Parameters& params) final
+ {
+
+ double *vertices = (double *)HACD_ALLOC(sizeof(double)*countPoints * 3);
+ const float *source = points;
+ double *dest = vertices;
+ for (uint32_t i = 0; i < countPoints; i++)
+ {
+ dest[0] = source[0];
+ dest[1] = source[1];
+ dest[2] = source[2];
+ dest += 3;
+ source += 3;
+ }
+
+ bool ret = Compute(vertices, countPoints, triangles, countTriangles, params);
+ HACD_FREE(vertices);
+ return ret;
+ }
+
+ virtual uint32_t GetNConvexHulls() const final
+ {
+ processPendingMessages();
+ return mHullCount;
+ }
+
+ virtual void Clean(void) final // release internally allocated memory
+ {
+ Cancel();
+ releaseHACD();
+ mVHACD->Clean();
+ }
+
+ virtual void Release(void) final // release IVHACD
+ {
+ delete this;
+ }
+
+ virtual bool OCLInit(void* const oclDevice,
+ IVHACD::IUserLogger* const logger = 0) final
+ {
+ return mVHACD->OCLInit(oclDevice, logger);
+ }
+
+ virtual bool OCLRelease(IVHACD::IUserLogger* const logger = 0) final
+ {
+ return mVHACD->OCLRelease(logger);
+ }
+
+ virtual void Update(const double overallProgress,
+ const double stageProgress,
+ const double operationProgress,
+ const char* const stage,
+ const char* const operation) final
+ {
+ mMessageMutex.lock();
+ mHaveUpdateMessage = true;
+ mOverallProgress = overallProgress;
+ mStageProgress = stageProgress;
+ mOperationProgress = operationProgress;
+ mStage = std::string(stage);
+ mOperation = std::string(operation);
+ mMessageMutex.unlock();
+ }
+
+ virtual void Log(const char* const msg) final
+ {
+ mMessageMutex.lock();
+ mHaveLogMessage = true;
+ mMessage = std::string(msg);
+ mMessageMutex.unlock();
+ }
+
+ virtual bool IsReady(void) const final
+ {
+ processPendingMessages();
+ return !mRunning;
+ }
+
+ // As a convenience for the calling application we only send it update and log messages from it's own main
+ // thread. This reduces the complexity burden on the caller by making sure it only has to deal with log
+ // messages in it's main application thread.
+ void processPendingMessages(void) const
+ {
+ // If we have a new update message and the user has specified a callback we send the message and clear the semaphore
+ if (mHaveUpdateMessage && mCallback)
+ {
+ mMessageMutex.lock();
+ mCallback->Update(mOverallProgress, mStageProgress, mOperationProgress, mStage.c_str(), mOperation.c_str());
+ mHaveUpdateMessage = false;
+ mMessageMutex.unlock();
+ }
+ // If we have a new log message and the user has specified a callback we send the message and clear the semaphore
+ if (mHaveLogMessage && mLogger)
+ {
+ mMessageMutex.lock();
+ mLogger->Log(mMessage.c_str());
+ mHaveLogMessage = false;
+ mMessageMutex.unlock();
+ }
+ }
+
+ // Will compute the center of mass of the convex hull decomposition results and return it
+ // in 'centerOfMass'. Returns false if the center of mass could not be computed.
+ virtual bool ComputeCenterOfMass(double centerOfMass[3]) const
+ {
+ bool ret = false;
+
+ centerOfMass[0] = 0;
+ centerOfMass[1] = 0;
+ centerOfMass[2] = 0;
+
+ if (mVHACD && IsReady() )
+ {
+ ret = mVHACD->ComputeCenterOfMass(centerOfMass);
+ }
+ return ret;
+ }
+
+ // Will analyze the HACD results and compute the constraints solutions.
+ // It will analyze the point at which any two convex hulls touch each other and
+ // return the total number of constraint pairs found
+ virtual uint32_t ComputeConstraints(void) final
+ {
+ uint32_t ret = 0;
+ if (mVHACD && IsReady())
+ {
+ ret = mVHACD->ComputeConstraints();
+ }
+ return ret;
+ }
+
+ virtual const Constraint *GetConstraint(uint32_t index) const final
+ {
+ const Constraint * ret = nullptr;
+ if (mVHACD && IsReady())
+ {
+ ret = mVHACD->GetConstraint(index);
+ }
+ return ret;
+
+ }
+
+
+
+private:
+ double *mVertices{ nullptr };
+ uint32_t *mIndices{ nullptr };
+ std::atomic< uint32_t> mHullCount{ 0 };
+ VHACD::IVHACD::ConvexHull *mHulls{ nullptr };
+ VHACD::IVHACD::IUserCallback *mCallback{ nullptr };
+ VHACD::IVHACD::IUserLogger *mLogger{ nullptr };
+ VHACD::IVHACD *mVHACD{ nullptr };
+ std::thread *mThread{ nullptr };
+ std::atomic< bool > mRunning{ false };
+ std::atomic<bool> mCancel{ false };
+
+ // Thread safe caching mechanism for messages and update status.
+ // This is so that caller always gets messages in his own thread
+ // Member variables are marked as 'mutable' since the message dispatch function
+ // is called from const query methods.
+ mutable std::mutex mMessageMutex;
+ mutable std::atomic< bool > mHaveUpdateMessage{ false };
+ mutable std::atomic< bool > mHaveLogMessage{ false };
+ mutable double mOverallProgress{ 0 };
+ mutable double mStageProgress{ 0 };
+ mutable double mOperationProgress{ 0 };
+ mutable std::string mStage;
+ mutable std::string mOperation;
+ mutable std::string mMessage;
+};
+
+IVHACD* CreateVHACD_ASYNC(void)
+{
+ MyHACD_API *m = new MyHACD_API;
+ return static_cast<IVHACD *>(m);
+}
+
+
+}; // end of VHACD namespace
+