aboutsummaryrefslogtreecommitdiff
path: root/NvBlast/sdk/common
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2017-02-21 12:07:59 -0800
committerBryan Galdrikian <[email protected]>2017-02-21 12:07:59 -0800
commit446ce137c6823ba9eff273bdafdaf266287c7c98 (patch)
treed20aab3e2ed08d7b3ca71c2f40db6a93ea00c459 /NvBlast/sdk/common
downloadblast-1.0.0-beta.tar.xz
blast-1.0.0-beta.zip
first commitv1.0.0-beta
Diffstat (limited to 'NvBlast/sdk/common')
-rw-r--r--NvBlast/sdk/common/NvBlastAssert.cpp50
-rw-r--r--NvBlast/sdk/common/NvBlastAssert.h63
-rw-r--r--NvBlast/sdk/common/NvBlastAtomic.cpp73
-rw-r--r--NvBlast/sdk/common/NvBlastAtomic.h32
-rw-r--r--NvBlast/sdk/common/NvBlastDLink.h285
-rw-r--r--NvBlast/sdk/common/NvBlastFixedArray.h128
-rw-r--r--NvBlast/sdk/common/NvBlastFixedBitmap.h118
-rw-r--r--NvBlast/sdk/common/NvBlastFixedBoolArray.h106
-rw-r--r--NvBlast/sdk/common/NvBlastFixedPriorityQueue.h192
-rw-r--r--NvBlast/sdk/common/NvBlastGeometry.h122
-rw-r--r--NvBlast/sdk/common/NvBlastIncludeWindows.h90
-rw-r--r--NvBlast/sdk/common/NvBlastIndexFns.h127
-rw-r--r--NvBlast/sdk/common/NvBlastIteratorBase.h135
-rw-r--r--NvBlast/sdk/common/NvBlastMath.h79
-rw-r--r--NvBlast/sdk/common/NvBlastMemory.h123
-rw-r--r--NvBlast/sdk/common/NvBlastPreprocessorInternal.h36
-rw-r--r--NvBlast/sdk/common/NvBlastTime.cpp23
-rw-r--r--NvBlast/sdk/common/NvBlastTime.h108
-rw-r--r--NvBlast/sdk/common/NvBlastTimers.cpp29
19 files changed, 1919 insertions, 0 deletions
diff --git a/NvBlast/sdk/common/NvBlastAssert.cpp b/NvBlast/sdk/common/NvBlastAssert.cpp
new file mode 100644
index 0000000..7731a53
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastAssert.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016-2017, 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 "NvBlastAssert.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if NV_WINDOWS_FAMILY
+#include <crtdbg.h>
+#endif
+
+extern "C"
+{
+
+void NvBlastAssertHandler(const char* expr, const char* file, int line, bool& ignore)
+{
+ NV_UNUSED(ignore); // is used only in debug windows config
+ char buffer[1024];
+#if NV_WINDOWS_FAMILY
+ sprintf_s(buffer, 1024, "%s(%d) : Assertion failed: %s\n", file, line, expr);
+#else
+ sprintf(buffer, "%s(%d) : Assertion failed: %s\n", file, line, expr);
+#endif
+ puts(buffer);
+#if NV_WINDOWS_FAMILY && NV_DEBUG
+ // _CrtDbgReport returns -1 on error, 1 on 'retry', 0 otherwise including 'ignore'.
+ // Hitting 'abort' will terminate the process immediately.
+ int result = _CrtDbgReport(_CRT_ASSERT, file, line, NULL, "%s", buffer);
+ int mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_REPORT_MODE);
+ ignore = _CRTDBG_MODE_WNDW == mode && result == 0;
+ if (ignore)
+ return;
+ __debugbreak();
+#elif (NV_WINDOWS_FAMILY && NV_CHECKED) || NV_CLANG
+ __debugbreak();
+#else
+ abort();
+#endif
+}
+
+} // extern "C"
diff --git a/NvBlast/sdk/common/NvBlastAssert.h b/NvBlast/sdk/common/NvBlastAssert.h
new file mode 100644
index 0000000..b1b7ca5
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastAssert.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef NVBLASTASSERT_H
+#define NVBLASTASSERT_H
+
+
+#include "NvBlastPreprocessor.h"
+
+
+#if !NV_ENABLE_ASSERTS
+#define NVBLAST_ASSERT(exp) ((void)0)
+#define NVBLAST_ALWAYS_ASSERT_MESSAGE(exp) ((void)0)
+#define NVBLAST_ASSERT_WITH_MESSAGE(condition, message) ((void)0)
+#else
+#if NV_VC
+#define NVBLAST_CODE_ANALYSIS_ASSUME(exp) \
+ __analysis_assume(!!(exp)) // This macro will be used to get rid of analysis warning messages if a NVBLAST_ASSERT is used
+// to "guard" illegal mem access, for example.
+#else
+#define NVBLAST_CODE_ANALYSIS_ASSUME(exp)
+#endif
+#define NVBLAST_ASSERT(exp) \
+{ \
+ static bool _ignore = false; \
+ if (!(exp) && !_ignore) NvBlastAssertHandler(#exp, __FILE__, __LINE__, _ignore); \
+ NVBLAST_CODE_ANALYSIS_ASSUME(exp); \
+} ((void)0)
+#define NVBLAST_ALWAYS_ASSERT_MESSAGE(exp) \
+{ \
+ static bool _ignore = false; \
+ if(!_ignore) \
+ { \
+ NvBlastAssertHandler(exp, __FILE__, __LINE__, _ignore); \
+ } \
+} ((void)0)
+#define NVBLAST_ASSERT_WITH_MESSAGE(exp, message) \
+{ \
+ static bool _ignore = false; \
+ if (!(exp) && !_ignore) NvBlastAssertHandler(message, __FILE__, __LINE__, _ignore); \
+ NVBLAST_CODE_ANALYSIS_ASSUME(exp); \
+} ((void)0)
+#endif
+
+#define NVBLAST_ALWAYS_ASSERT() NVBLAST_ASSERT(0)
+
+
+extern "C"
+{
+
+NVBLAST_API void NvBlastAssertHandler(const char* expr, const char* file, int line, bool& ignore);
+
+} // extern "C"
+
+
+#endif // #ifndef NVBLASTASSERT_H
diff --git a/NvBlast/sdk/common/NvBlastAtomic.cpp b/NvBlast/sdk/common/NvBlastAtomic.cpp
new file mode 100644
index 0000000..6b9d94b
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastAtomic.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016-2017, 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 "NvBlastAtomic.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Windows/XBOXONE Implementation
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if NV_WINDOWS_FAMILY || NV_XBOXONE
+
+#include "NvBlastIncludeWindows.h"
+
+int32_t atomicIncrement(volatile int32_t* val)
+{
+ return (int32_t)InterlockedIncrement((volatile LONG*)val);
+}
+
+int32_t atomicDecrement(volatile int32_t* val)
+{
+ return (int32_t)InterlockedDecrement((volatile LONG*)val);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Unix/PS4 Implementation
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#elif(NV_UNIX_FAMILY || NV_PS4)
+
+int32_t atomicIncrement(volatile int32_t* val)
+{
+ return __sync_add_and_fetch(val, 1);
+}
+
+int32_t atomicDecrement(volatile int32_t* val)
+{
+ return __sync_sub_and_fetch(val, 1);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Unsupported Platforms
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#else
+
+#error "Platform not supported!"
+
+#endif
+
+
+} // namespace Blast
+} // namespace Nv
+
diff --git a/NvBlast/sdk/common/NvBlastAtomic.h b/NvBlast/sdk/common/NvBlastAtomic.h
new file mode 100644
index 0000000..a3e6755
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastAtomic.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef NVBLASTATOMIC_H
+#define NVBLASTATOMIC_H
+
+#include "NvBlastTypes.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+/* increment the specified location. Return the incremented value */
+int32_t atomicIncrement(volatile int32_t* val);
+
+
+/* decrement the specified location. Return the decremented value */
+int32_t atomicDecrement(volatile int32_t* val);
+
+} // namespace Blast
+} // namespace Nv
+
+#endif // #ifndef NVBLASTATOMIC_H
diff --git a/NvBlast/sdk/common/NvBlastDLink.h b/NvBlast/sdk/common/NvBlastDLink.h
new file mode 100644
index 0000000..bfcee24
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastDLink.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef NVBLASTDLINK_H
+#define NVBLASTDLINK_H
+
+
+#include "NvBlastAssert.h"
+#include "NvBlastIndexFns.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+template<typename IndexType>
+struct IndexDLink
+{
+ IndexType m_adj[2];
+};
+
+
+template<typename IndexType>
+class IndexDList
+{
+public:
+ void initLinksSolitary(IndexDLink<IndexType>* links, IndexType linkCount)
+ {
+ for (IndexType i = 0; i < linkCount; ++i)
+ {
+ links[i].m_adj[0] = invalidIndex<IndexType>();
+ links[i].m_adj[1] = invalidIndex<IndexType>();
+ }
+ }
+
+ void initLinksChain(IndexDLink<IndexType>* links, IndexType linkCount)
+ {
+ if (linkCount > 0)
+ {
+ links[0].m_adj[0] = invalidIndex<IndexType>();
+ for (IndexType i = 1; i < linkCount; ++i)
+ {
+ links[i - 1].m_adj[1] = i;
+ links[i].m_adj[0] = i - 1;
+ }
+ links[linkCount - 1].m_adj[1] = invalidIndex<IndexType>();
+ }
+ }
+
+ IndexType getAdj(IndexDLink<IndexType>* links, IndexType linkIndex, int which)
+ {
+ return links[linkIndex].m_adj[which & 1];
+ }
+
+ void remove(IndexDLink<IndexType>* links, IndexType linkIndex)
+ {
+ IndexDLink<IndexType>& link = links[linkIndex];
+ const IndexType adj0 = link.m_adj[0];
+ const IndexType adj1 = link.m_adj[1];
+ if (!isInvalidIndex(adj1))
+ {
+ links[adj1].m_adj[0] = adj0;
+ link.m_adj[1] = invalidIndex<IndexType>();
+ }
+ if (!isInvalidIndex(adj0))
+ {
+ links[adj0].m_adj[1] = adj1;
+ link.m_adj[0] = invalidIndex<IndexType>();
+ }
+ }
+
+ bool isSolitary(IndexDLink<IndexType>* links, IndexType linkIndex)
+ {
+ const IndexDLink<IndexType>& link = links[linkIndex];
+ return isInvalidIndex(link.m_adj[0]) && isInvalidIndex(link.m_adj[1]);
+ }
+
+ void insertListHead(IndexType& listHead, IndexDLink<IndexType>* links, IndexType linkIndex)
+ {
+ NVBLAST_ASSERT(!isInvalidIndex(linkIndex));
+ if (!isInvalidIndex(listHead))
+ {
+ links[listHead].m_adj[0] = linkIndex;
+ }
+ links[linkIndex].m_adj[1] = listHead;
+ listHead = linkIndex;
+ }
+
+ IndexType removeListHead(IndexType& listHead, IndexDLink<IndexType>* links)
+ {
+ const IndexType linkIndex = listHead;
+ if (!isInvalidIndex(linkIndex))
+ {
+ listHead = links[linkIndex].m_adj[1];
+ if (!isInvalidIndex(listHead))
+ {
+ links[listHead].m_adj[0] = invalidIndex<IndexType>();
+ }
+ links[linkIndex].m_adj[1] = invalidIndex<IndexType>();
+ }
+ return linkIndex;
+ }
+
+ void removeFromList(IndexType& listHead, IndexDLink<IndexType>* links, IndexType linkIndex)
+ {
+ NVBLAST_ASSERT(!isInvalidIndex(linkIndex));
+ if (listHead == linkIndex)
+ {
+ listHead = links[linkIndex].m_adj[1];
+ }
+ remove(links, linkIndex);
+ }
+};
+
+
+struct DLink
+{
+ DLink() : m_prev(nullptr), m_next(nullptr) {}
+
+ DLink* getPrev() const
+ {
+ return m_prev;
+ }
+
+ DLink* getNext() const
+ {
+ return m_next;
+ }
+
+private:
+ DLink* m_prev;
+ DLink* m_next;
+
+ friend class DList;
+};
+
+
+class DList
+{
+public:
+ DList() : m_head(nullptr), m_tail(nullptr) {}
+
+ bool isEmpty() const
+ {
+ NVBLAST_ASSERT((m_head == nullptr) == (m_tail == nullptr));
+ return m_head == nullptr;
+ }
+
+ bool isSolitary(const DLink& link) const
+ {
+ return link.m_prev == nullptr && link.m_next == nullptr && m_head != &link;
+ }
+
+ DLink* getHead() const
+ {
+ return m_head;
+ }
+
+ DLink* getTail() const
+ {
+ return m_tail;
+ }
+
+ bool insertHead(DLink& link)
+ {
+ NVBLAST_ASSERT(isSolitary(link));
+ if (!isSolitary(link))
+ {
+ return false;
+ }
+
+ link.m_next = m_head;
+ if (m_head != nullptr)
+ {
+ m_head->m_prev = &link;
+ }
+ m_head = &link;
+ if (m_tail == nullptr)
+ {
+ m_tail = &link;
+ }
+
+ return true;
+ }
+
+ bool insertTail(DLink& link)
+ {
+ NVBLAST_ASSERT(isSolitary(link));
+ if (!isSolitary(link))
+ {
+ return false;
+ }
+
+ link.m_prev = m_tail;
+ if (m_tail != nullptr)
+ {
+ m_tail->m_next = &link;
+ }
+ m_tail = &link;
+ if (m_head == nullptr)
+ {
+ m_head = &link;
+ }
+
+ return true;
+ }
+
+ void remove(DLink& link)
+ {
+ if (link.m_prev != nullptr)
+ {
+ link.m_prev->m_next = link.m_next;
+ }
+ else
+ if (m_head == &link)
+ {
+ m_head = link.m_next;
+ }
+
+ if (link.m_next != nullptr)
+ {
+ link.m_next->m_prev = link.m_prev;
+ }
+ else
+ if (m_tail == &link)
+ {
+ m_tail = link.m_prev;
+ }
+
+ link.m_next = link.m_prev = nullptr;
+ }
+
+ class It
+ {
+ public:
+ enum Direction { Reverse, Forward };
+
+ It(const DList& list, Direction dir = Forward) : m_curr(dir == Forward ? list.getHead() : list.getTail()) {}
+
+ /** Validity of current value. */
+ operator bool() const
+ {
+ return m_curr != nullptr;
+ }
+
+ /** Current value. */
+ operator const DLink*() const
+ {
+ return m_curr;
+ }
+
+ /** Pre-increment. */
+ const DLink* operator ++ ()
+ {
+ return m_curr = m_curr->getNext();
+ }
+
+ /** Pre-deccrement. */
+ const DLink* operator -- ()
+ {
+ return m_curr = m_curr->getPrev();
+ }
+
+ private:
+ const DLink* m_curr;
+ };
+
+private:
+ DLink* m_head;
+ DLink* m_tail;
+};
+
+} // end namespace Blast
+} // end namespace Nv
+
+
+#endif // #ifndef NVBLASTDLINK_H
diff --git a/NvBlast/sdk/common/NvBlastFixedArray.h b/NvBlast/sdk/common/NvBlastFixedArray.h
new file mode 100644
index 0000000..654158b
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastFixedArray.h
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTFIXEDARRAY_H
+#define NVBLASTFIXEDARRAY_H
+
+#include "NvBlastAssert.h"
+#include "NvBlastMemory.h"
+
+namespace Nv
+{
+namespace Blast
+{
+
+/*!
+FixedArray is a sequential container which is intended to be used with placement new on chunk of memory.
+It'll use following memory for data layout. As follows:
+
+// some memory
+char ​*buf = new char[64 *​ 1024];
+
+// placement new on this memory
+FixedArray<SomeClass>* arr = new (buf) FixedArray<SomeClass>();
+
+// you can get max requiredMemorySize by an array of 'capacity' elements count to use memory left
+buf = buf + FixedArray<SomeClass>::requiredMemorySize(capacity);
+
+buf:
+
++------------------------------------------------------------+
+| uint32_t | T[0] | T[1] | T[2] | ... |
++------------------------------------------------------------+
+
+
+!!!TODO:
+- check ctor/dtor of elements calls
+*/
+template <class T>
+class FixedArray
+{
+public:
+ explicit FixedArray() : m_size(0)
+ {
+ }
+
+ static size_t requiredMemorySize(uint32_t capacity)
+ {
+ return align16(sizeof(FixedArray<T>)) + align16(capacity * sizeof(T));
+ }
+
+ NV_FORCE_INLINE T& pushBack(T& t)
+ {
+ new (data() + m_size) T(t);
+ return data()[m_size++];
+ }
+
+ T popBack()
+ {
+ NVBLAST_ASSERT(m_size);
+ T t = data()[m_size - 1];
+ data()[--m_size].~T();
+ return t;
+ }
+
+ void clear()
+ {
+ for(T* first = data(); first < data() + m_size; ++first)
+ first->~T();
+ m_size = 0;
+ }
+
+ NV_FORCE_INLINE void forceSize_Unsafe(uint32_t s)
+ {
+ m_size = s;
+ }
+
+ NV_FORCE_INLINE T& operator[](uint32_t idx)
+ {
+ NVBLAST_ASSERT(idx < m_size);
+ return data()[idx];
+ }
+
+ NV_FORCE_INLINE const T& operator[](uint32_t idx) const
+ {
+ NVBLAST_ASSERT(idx < m_size);
+ return data()[idx];
+ }
+
+ NV_FORCE_INLINE T& at(uint32_t idx)
+ {
+ NVBLAST_ASSERT(idx < m_size);
+ return data()[idx];
+ }
+
+ NV_FORCE_INLINE const T& at(uint32_t idx) const
+ {
+ NVBLAST_ASSERT(idx < m_size);
+ return data()[idx];
+ }
+
+ NV_FORCE_INLINE uint32_t size() const
+ {
+ return m_size;
+ }
+
+private:
+ uint32_t m_size;
+
+ NV_FORCE_INLINE T* data()
+ {
+ return (T*)((char*)this + sizeof(FixedArray<T>));
+ }
+
+private:
+ FixedArray(const FixedArray& that);
+};
+
+} // namespace Blast
+} // namespace Nv
+
+#endif // ifndef NVBLASTFIXEDARRAY_H
diff --git a/NvBlast/sdk/common/NvBlastFixedBitmap.h b/NvBlast/sdk/common/NvBlastFixedBitmap.h
new file mode 100644
index 0000000..af835cf
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastFixedBitmap.h
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTFIXEDBITMAP_H
+#define NVBLASTFIXEDBITMAP_H
+
+#include "NvBlastAssert.h"
+#include "NvBlastMemory.h"
+#include <cstring>
+
+namespace Nv
+{
+namespace Blast
+{
+
+/*!
+FixedBitmap is a bitset (bitmap) of fixed side, it's intended to be used with placement new on chunk of memory.
+It'll use following memory for data layout. As follows:
+
+// some memory
+char ​*buf = new char[64 *​ 1024];
+
+const uint32_t bitsCount = 100;
+
+// placement new on this memory
+FixedBitmap* arr = new (buf) FixedBitmap(bitsCount);
+
+// you can get max requiredMemorySize by an bitMap to use memory left
+buf = buf + FixedBitmap<SomeClass>::requiredMemorySize(bitsCount);
+
+buf:
+
++------------------------------------------------------------+
+| uint32_t | word0 | word1 | word2 | ... |
++------------------------------------------------------------+
+
+*/
+class FixedBitmap
+{
+public:
+ explicit FixedBitmap(uint32_t bitsCount)
+ {
+ m_bitsCount = bitsCount;
+ }
+
+ static uint32_t getWordsCount(uint32_t bitsCount)
+ {
+ return (bitsCount + 31) >> 5;
+ }
+
+ static size_t requiredMemorySize(uint32_t bitsCount)
+ {
+ return align16(sizeof(FixedBitmap)) + align16(getWordsCount(bitsCount) * sizeof(uint32_t));
+ }
+
+ void clear()
+ {
+ memset(data(), 0, getWordsCount(m_bitsCount) * sizeof(uint32_t));
+ }
+
+ void fill()
+ {
+ const uint32_t wordCount = getWordsCount(m_bitsCount);
+ uint32_t* mem = data();
+ memset(mem, 0xFF, wordCount * sizeof(uint32_t));
+ const uint32_t bitsRemainder = m_bitsCount & 31;
+ if (bitsRemainder > 0)
+ {
+ mem[wordCount - 1] &= ~(0xFFFFFFFF << bitsRemainder);
+ }
+ }
+
+ int test(uint32_t index) const
+ {
+ NVBLAST_ASSERT(index < m_bitsCount);
+ return data()[index >> 5] & (1 << (index & 31));
+ }
+
+ void set(uint32_t index)
+ {
+ NVBLAST_ASSERT(index < m_bitsCount);
+ data()[index >> 5] |= 1 << (index & 31);
+ }
+
+ void reset(uint32_t index)
+ {
+ NVBLAST_ASSERT(index < m_bitsCount);
+ data()[index >> 5] &= ~(1 << (index & 31));
+ }
+
+private:
+ uint32_t m_bitsCount;
+
+ NV_FORCE_INLINE uint32_t* data()
+ {
+ return (uint32_t*)((char*)this + sizeof(FixedBitmap));
+ }
+
+ NV_FORCE_INLINE const uint32_t* data() const
+ {
+ return (uint32_t*)((char*)this + sizeof(FixedBitmap));
+ }
+
+private:
+ FixedBitmap(const FixedBitmap& that);
+};
+
+} // namespace Blast
+} // namespace Nv
+
+#endif // ifndef NVBLASTFIXEDBITMAP_H
diff --git a/NvBlast/sdk/common/NvBlastFixedBoolArray.h b/NvBlast/sdk/common/NvBlastFixedBoolArray.h
new file mode 100644
index 0000000..253bed6
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastFixedBoolArray.h
@@ -0,0 +1,106 @@
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTFIXEDBOOLARRAY_H
+#define NVBLASTFIXEDBOOLARRAY_H
+
+#include "NvBlastAssert.h"
+#include "NvBlastMemory.h"
+#include <cstring>
+
+namespace Nv
+{
+namespace Blast
+{
+
+/*!
+FixedBoolArray is an array of bools of fixed size, it's intended to be used with placement new on chunk of memory.
+It'll use following memory for data layout. As follows:
+
+// some memory
+char ​*buf = new char[64 *​ 1024];
+
+const uint32_t size = 100;
+
+// placement new on this memory
+FixedBoolArray* arr = new (buf) FixedBoolArray(size);
+
+// you can get max requiredMemorySize by an bitMap to use memory left
+buf = buf + FixedBoolArray<SomeClass>::requiredMemorySize(size);
+
+buf:
+
++------------------------------------------------------------+
+| uint32_t | bool0 | bool1 | bool2 | ... |
++------------------------------------------------------------+
+
+*/
+class FixedBoolArray
+{
+public:
+ explicit FixedBoolArray(uint32_t size)
+ {
+ m_size = size;
+ }
+
+ static size_t requiredMemorySize(uint32_t size)
+ {
+ return align16(sizeof(FixedBoolArray)) + align16(size);
+ }
+
+ void clear()
+ {
+ memset(data(), 0, m_size);
+ }
+
+ void fill()
+ {
+ memset(data(), 1, m_size);
+ }
+
+ int test(uint32_t index) const
+ {
+ NVBLAST_ASSERT(index < m_size);
+ return data()[index];
+ }
+
+ void set(uint32_t index)
+ {
+ NVBLAST_ASSERT(index < m_size);
+ data()[index] = 1;
+ }
+
+ void reset(uint32_t index)
+ {
+ NVBLAST_ASSERT(index < m_size);
+ data()[index] = 0;
+ }
+
+private:
+ uint32_t m_size;
+
+ NV_FORCE_INLINE char* data()
+ {
+ return ((char*)this + sizeof(FixedBoolArray));
+ }
+
+ NV_FORCE_INLINE const char* data() const
+ {
+ return ((char*)this + sizeof(FixedBoolArray));
+ }
+
+private:
+ FixedBoolArray(const FixedBoolArray& that);
+};
+
+} // namespace Blast
+} // namespace Nv
+
+#endif // ifndef NVBLASTFIXEDBOOLARRAY_H
diff --git a/NvBlast/sdk/common/NvBlastFixedPriorityQueue.h b/NvBlast/sdk/common/NvBlastFixedPriorityQueue.h
new file mode 100644
index 0000000..5079edb
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastFixedPriorityQueue.h
@@ -0,0 +1,192 @@
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTFIXEDPRIORITYQUEUE_H
+#define NVBLASTFIXEDPRIORITYQUEUE_H
+
+#include "NvBlastAssert.h"
+#include "NvBlastMemory.h"
+
+namespace Nv
+{
+
+namespace Blast
+{
+
+/*!
+FixedPriorityQueue is a priority queue container which is intended to be used with placement new on chunk of memory.
+It'll use following memory for data layout. As follows:
+
+// some memory
+char ​*buf = new char[64 *​ 1024];
+
+// placement new on this memory
+FixedPriorityQueue<SomeClass>* arr = new (buf) FixedPriorityQueue<SomeClass>();
+
+// you can get max requiredMemorySize by an array of 'capacity' elements count to use memory left
+buf = buf + FixedPriorityQueue<SomeClass>::requiredMemorySize(capacity);
+
+buf:
+
++------------------------------------------------------------+
+| uint32_t | T[0] | T[1] | T[2] | ... |
++------------------------------------------------------------+
+
+*/
+
+template <typename A>
+struct Less
+{
+ bool operator()(const A& a, const A& b) const
+ {
+ return a < b;
+ }
+};
+
+
+template<class Element, class Comparator = Less<Element> >
+class FixedPriorityQueue : protected Comparator // inherit so that stateless comparators take no space
+{
+public:
+ FixedPriorityQueue(const Comparator& less = Comparator()) : Comparator(less), mHeapSize(0)
+ {
+ }
+
+ ~FixedPriorityQueue()
+ {
+ }
+
+ static size_t requiredMemorySize(uint32_t capacity)
+ {
+ return align16(sizeof(FixedPriorityQueue<Element, Comparator>)) + align16(capacity * sizeof(Element));
+ }
+
+ //! Get the element with the highest priority
+ const Element top() const
+ {
+ return data()[0];
+ }
+
+ //! Get the element with the highest priority
+ Element top()
+ {
+ return data()[0];
+ }
+
+ //! Check to whether the priority queue is empty
+ bool empty() const
+ {
+ return (mHeapSize == 0);
+ }
+
+ //! Empty the priority queue
+ void clear()
+ {
+ mHeapSize = 0;
+ }
+
+ //! Insert a new element into the priority queue. Only valid when size() is less than Capacity
+ void push(const Element& value)
+ {
+ uint32_t newIndex;
+ uint32_t parentIndex = parent(mHeapSize);
+
+ for (newIndex = mHeapSize; newIndex > 0 && compare(value, data()[parentIndex]); newIndex = parentIndex, parentIndex= parent(newIndex))
+ {
+ data()[ newIndex ] = data()[parentIndex];
+ }
+ data()[newIndex] = value;
+ mHeapSize++;
+ NVBLAST_ASSERT(valid());
+ }
+
+ //! Delete the highest priority element. Only valid when non-empty.
+ Element pop()
+ {
+ NVBLAST_ASSERT(mHeapSize > 0);
+ uint32_t i, child;
+ //try to avoid LHS
+ uint32_t tempHs = mHeapSize-1;
+ mHeapSize = tempHs;
+ Element min = data()[0];
+ Element last = data()[tempHs];
+
+ for (i = 0; (child = left(i)) < tempHs; i = child)
+ {
+ /* Find highest priority child */
+ const uint32_t rightChild = child + 1;
+
+ child += ((rightChild < tempHs) & compare((data()[rightChild]), (data()[child]))) ? 1 : 0;
+
+ if(compare(last, data()[child]))
+ break;
+
+ data()[i] = data()[child];
+ }
+ data()[ i ] = last;
+
+ NVBLAST_ASSERT(valid());
+ return min;
+ }
+
+ //! Make sure the priority queue sort all elements correctly
+ bool valid() const
+ {
+ const Element& min = data()[0];
+ for(uint32_t i=1; i<mHeapSize; ++i)
+ {
+ if(compare(data()[i], min))
+ return false;
+ }
+
+ return true;
+ }
+
+ //! Return number of elements in the priority queue
+ uint32_t size() const
+ {
+ return mHeapSize;
+ }
+
+private:
+ uint32_t mHeapSize;
+
+ NV_FORCE_INLINE Element* data()
+ {
+ return (Element*)((char*)this + sizeof(FixedPriorityQueue<Element, Comparator>));
+ }
+
+ NV_FORCE_INLINE Element* data() const
+ {
+ return (Element*)((char*)this + sizeof(FixedPriorityQueue<Element, Comparator>));
+ }
+
+ bool compare(const Element& a, const Element& b) const
+ {
+ return Comparator::operator()(a,b);
+ }
+
+ static uint32_t left(uint32_t nodeIndex)
+ {
+ return (nodeIndex << 1) + 1;
+ }
+
+ static uint32_t parent(uint32_t nodeIndex)
+ {
+ return (nodeIndex - 1) >> 1;
+ }
+
+ FixedPriorityQueue<Element, Comparator>& operator = (const FixedPriorityQueue<Element, Comparator>);
+};
+
+} // namespace Blast
+} // namespace Nv
+
+#endif // ifndef NVBLASTFIXEDPRIORITYQUEUE_H
diff --git a/NvBlast/sdk/common/NvBlastGeometry.h b/NvBlast/sdk/common/NvBlastGeometry.h
new file mode 100644
index 0000000..e83ff95
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastGeometry.h
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+
+#ifndef NVBLASTGEOMETRY_H
+#define NVBLASTGEOMETRY_H
+
+#include "NvBlastTypes.h"
+#include "NvBlastMath.h"
+
+#include<limits>
+
+
+namespace Nv {
+namespace Blast{
+
+NV_FORCE_INLINE uint32_t findNodeByPositionLinked(const float point[4],
+ const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks,
+ const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices,
+ const NvBlastBond* bonds, const float* bondHealths)
+{
+ uint32_t nodeIndex = firstGraphNodeIndex;
+ uint32_t closestNode = nodeIndex;
+ float minDist = std::numeric_limits<float>().max();
+
+ while (!Nv::Blast::isInvalidIndex(nodeIndex))
+ {
+ const uint32_t startIndex = adjacencyPartition[nodeIndex];
+ const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1];
+
+ for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++)
+ {
+ const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex];
+ if (nodeIndex < neighbourIndex)
+ {
+ const uint32_t bondIndex = adjacentBondIndices[adjacentIndex];
+ if (bondHealths[bondIndex] > 0.0f)
+ {
+ const NvBlastBond& bond = bonds[bondIndex];
+
+ const float* centroid = bond.centroid;
+ float d[3]; VecMath::sub(point, centroid, d);
+ float dist = VecMath::dot(d, d);
+
+ if (dist < minDist)
+ {
+ minDist = dist;
+ float s = VecMath::dot(d, bond.normal);
+ closestNode = s < 0 ? nodeIndex : neighbourIndex;
+ }
+ }
+ }
+ }
+ nodeIndex = familyGraphNodeIndexLinks[nodeIndex];
+ }
+
+ return closestNode;
+}
+
+
+NV_FORCE_INLINE uint32_t findNodeByPosition(const float point[4],
+ const uint32_t graphNodesCount, const uint32_t* graphNodeIndices,
+ const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices,
+ const NvBlastBond* bonds, const float* bondHealths)
+{
+ uint32_t closestNode = graphNodesCount > 2 ? invalidIndex<uint32_t>() : graphNodeIndices[0];
+ float minDist = std::numeric_limits<float>().max();
+
+ for (uint32_t i = 0; i < graphNodesCount; i++)
+ {
+ const uint32_t nodeIndex = graphNodeIndices[i];
+ const uint32_t startIndex = adjacencyPartition[nodeIndex];
+ const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1];
+
+ for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++)
+ {
+ const uint32_t bondIndex = adjacentBondIndices[adjacentIndex];
+ if (bondHealths[bondIndex] > 0.0f)
+ {
+ const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex];
+ if (nodeIndex < neighbourIndex)
+ {
+ const NvBlastBond& bond = bonds[bondIndex];
+
+ const float* centroid = bond.centroid;
+ float d[3]; VecMath::sub(point, centroid, d);
+ float dist = VecMath::dot(d, d);
+
+ if (dist < minDist)
+ {
+ minDist = dist;
+ float s = VecMath::dot(d, bond.normal);
+ closestNode = s < 0 ? nodeIndex : neighbourIndex;
+ }
+ }
+ }
+ }
+ }
+ return closestNode;
+}
+
+
+NV_FORCE_INLINE uint32_t findNodeByPosition(const float point[4],
+ const uint32_t graphNodesCount, const uint32_t* graphNodeIndices,
+ const NvBlastSupportGraph& graph,
+ const NvBlastBond* bonds, const float* bondHealths)
+{
+ return findNodeByPosition(point, graphNodesCount, graphNodeIndices, graph.adjacencyPartition, graph.adjacentNodeIndices, graph.adjacentBondIndices, bonds, bondHealths);
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // NVBLASTGEOMETRY_H
diff --git a/NvBlast/sdk/common/NvBlastIncludeWindows.h b/NvBlast/sdk/common/NvBlastIncludeWindows.h
new file mode 100644
index 0000000..9115fd4
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastIncludeWindows.h
@@ -0,0 +1,90 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTINCLUDEWINDOWS_H
+#define NVBLASTINCLUDEWINDOWS_H
+
+#ifndef _WINDOWS_ // windows already included if this is defined
+
+#include "NvBlastPreprocessor.h"
+
+#ifndef _WIN32
+#error "This file should only be included by Windows builds!!"
+#endif
+
+// We only support >= Windows XP, and we need this for critical section and
+#if !NV_WINRT
+#define _WIN32_WINNT 0x0501
+#else
+#define _WIN32_WINNT 0x0602
+#endif
+
+// turn off as much as we can for windows. All we really need is the thread functions(critical sections/Interlocked*
+// etc)
+#define NOGDICAPMASKS
+#define NOVIRTUALKEYCODES
+#define NOWINMESSAGES
+#define NOWINSTYLES
+#define NOSYSMETRICS
+#define NOMENUS
+#define NOICONS
+#define NOKEYSTATES
+#define NOSYSCOMMANDS
+#define NORASTEROPS
+#define NOSHOWWINDOW
+#define NOATOM
+#define NOCLIPBOARD
+#define NOCOLOR
+#define NOCTLMGR
+#define NODRAWTEXT
+#define NOGDI
+#define NOMB
+#define NOMEMMGR
+#define NOMETAFILE
+#define NOMINMAX
+#define NOOPENFILE
+#define NOSCROLL
+#define NOSERVICE
+#define NOSOUND
+#define NOTEXTMETRIC
+#define NOWH
+#define NOWINOFFSETS
+#define NOCOMM
+#define NOKANJI
+#define NOHELP
+#define NOPROFILER
+#define NODEFERWINDOWPOS
+#define NOMCX
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#if !NV_WINRT
+#define NOUSER
+#define NONLS
+#define NOMSG
+#endif
+
+#pragma warning(push)
+#pragma warning(disable : 4668) //'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
+#include <windows.h>
+#pragma warning(pop)
+
+#if NV_SSE2
+#include <xmmintrin.h>
+#endif
+
+#endif // #ifndef _WINDOWS_
+
+#endif // #ifndef NVBLASTINCLUDEWINDOWS_H
diff --git a/NvBlast/sdk/common/NvBlastIndexFns.h b/NvBlast/sdk/common/NvBlastIndexFns.h
new file mode 100644
index 0000000..a800a73
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastIndexFns.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2008-2017, 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.
+ */
+
+#ifndef NVBLASTINDEXFNS_H
+#define NVBLASTINDEXFNS_H
+
+
+#include "NvBlastTypes.h"
+
+#include <cstring>
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+/**
+Set to invalid index.
+*/
+template<typename T>
+NV_INLINE T invalidIndex()
+{
+ return ~(T)0;
+}
+
+
+/**
+Test for invalid index (max representable integer).
+*/
+template<typename T>
+NV_INLINE bool isInvalidIndex(T index)
+{
+ return index == invalidIndex<T>();
+}
+
+
+/**
+ Create a lookup table for data sorted by a templated index type.
+
+ Note: when using this function with unsigned integer index types invalidIndex<T>() is treated as a value less than zero.
+
+ On input:
+
+ The indices must lie in the interval [indexBase, indexBase+indexRange].
+
+ indexSource must point to the first index in the data.
+
+ indexCount must be set to the number of indices in the data.
+
+ indexByteStride must be set to the distance, in bytes, between subequent indices.
+
+ lookup must point to a T array of size indexRange+2.
+
+ On return:
+
+ lookup will be filled such that:
+
+ lookup[i] = the position of first data element with index (i + indexBase)
+
+ lookup[indexRange+1] = indexCount
+
+ The last (indexRange+1) element is used so that one may always determine the number of data elements with the given index using:
+
+ count = lookup[i+1] - lookup[i]
+
+ Note, if an index (i + indexBase) is not present in the data then, lookup[i+1] = lookup[i], so the count (above) will correctly be zero.
+ In this case, the actual value of lookup[i] is irrelevant.
+*/
+template<typename T>
+void createIndexStartLookup(T* lookup, T indexBase, T indexRange, T* indexSource, T indexCount, T indexByteStride)
+{
+ ++indexBase; // Ordering invalidIndex<T>() as lowest value
+ T indexPos = 0;
+ for (T i = 0; i <= indexRange; ++i)
+ {
+ for (; indexPos < indexCount; ++indexPos, indexSource = (T*)((uintptr_t)indexSource + indexByteStride))
+ {
+ if (*indexSource + 1 >= i + indexBase) // +1 to order invalidIndex<T>() as lowest value
+ {
+ lookup[i] = indexPos;
+ break;
+ }
+ }
+ if (indexPos == indexCount)
+ {
+ lookup[i] = indexPos;
+ }
+ }
+ lookup[indexRange + 1] = indexCount;
+}
+
+
+/**
+Creates the inverse of a map, such that inverseMap[map[i]] = i.
+Unmapped indices are set to invalidIndex<T>.
+
+\param[out] inverseMap inverse map space of given size
+\param[in] map original map of given size, unmapped entries must contain invalidIndex<T>
+\param[in] size size of the involved maps
+*/
+template<typename T>
+void invertMap(T* inverseMap, const T* map, const T size)
+{
+ memset(inverseMap, invalidIndex<T>(), size*sizeof(T));
+
+ for (T i = 0; i < size; i++)
+ {
+ if (!isInvalidIndex(map[i]))
+ {
+ inverseMap[map[i]] = i;
+ }
+ }
+}
+
+} // end namespace Blast
+} // end namespace Nv
+
+
+#endif // #ifndef NVBLASTINDEXFNS_H
diff --git a/NvBlast/sdk/common/NvBlastIteratorBase.h b/NvBlast/sdk/common/NvBlastIteratorBase.h
new file mode 100644
index 0000000..9053f4b
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastIteratorBase.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef NVBLASTITERATORBASE_H
+#define NVBLASTITERATORBASE_H
+
+
+#include "NvBlastIndexFns.h"
+
+namespace Nv
+{
+namespace Blast
+{
+
+/**
+Common functionality and implementation for iterators over an index, using invalidIndex<T>() to indicate termination.
+Derived class needs to implement increment operators.
+*/
+template<typename T>
+class IteratorBase
+{
+public:
+ /** Constructor sets m_curr value */
+ IteratorBase(T curr);
+
+ /** Validity of current value. */
+ operator bool() const;
+
+ /** Current value. */
+ operator T() const;
+
+protected:
+ T m_curr;
+};
+
+
+//////// IteratorBase<T> inline methods ////////
+
+template<typename T>
+NV_INLINE IteratorBase<T>::IteratorBase(T curr) : m_curr(curr)
+{
+}
+
+
+template<typename T>
+NV_INLINE IteratorBase<T>::operator bool() const
+{
+ return !isInvalidIndex<T>(m_curr);
+}
+
+
+template<typename T>
+NV_INLINE IteratorBase<T>::operator T() const
+{
+ return m_curr;
+}
+
+
+/**
+Common functionality and implementation for an indexed linked list iterator
+*/
+template<typename IndexType>
+class LListIt : public IteratorBase<IndexType>
+{
+public:
+ LListIt(IndexType curr, IndexType* links);
+
+ /** Pre-increment. Only use if valid() == true. */
+ uint32_t operator ++ ();
+
+protected:
+ IndexType* m_links;
+};
+
+
+//////// LListIt<IndexType> inline methods ////////
+
+template<typename IndexType>
+NV_INLINE LListIt<IndexType>::LListIt(IndexType curr, IndexType* links) : IteratorBase<IndexType>(curr), m_links(links)
+{
+}
+
+
+template<typename IndexType>
+NV_INLINE uint32_t LListIt<IndexType>::operator ++ ()
+{
+ NVBLAST_ASSERT((bool)(*this));
+ return (this->m_curr = m_links[this->m_curr]);
+}
+
+
+/**
+Common functionality and implementation for an IndexDList<IndexType> iterator
+*/
+template<typename IndexType>
+class DListIt : public IteratorBase<IndexType>
+{
+public:
+ DListIt(IndexType curr, IndexDLink<IndexType>* links);
+
+ /** Pre-increment. Only use if valid() == true. */
+ uint32_t operator ++ ();
+
+protected:
+ IndexDLink<IndexType>* m_links;
+};
+
+
+//////// DListIt<IndexType> inline methods ////////
+
+template<typename IndexType>
+NV_INLINE DListIt<IndexType>::DListIt(IndexType curr, IndexDLink<IndexType>* links) : IteratorBase<IndexType>(curr), m_links(links)
+{
+}
+
+
+template<typename IndexType>
+NV_INLINE uint32_t DListIt<IndexType>::operator ++ ()
+{
+ NVBLAST_ASSERT((bool)(*this));
+ return (this->m_curr = m_links[this->m_curr].m_adj[1]);
+}
+
+} // end namespace Blast
+} // end namespace Nv
+
+
+#endif // #ifndef NVBLASTITERATORBASE_H
diff --git a/NvBlast/sdk/common/NvBlastMath.h b/NvBlast/sdk/common/NvBlastMath.h
new file mode 100644
index 0000000..0a29f14
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastMath.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef NVBLASTMATH_H
+#define NVBLASTMATH_H
+
+#include <math.h>
+
+namespace Nv
+{
+namespace Blast
+{
+
+namespace VecMath
+{
+
+
+NV_INLINE void div(float a[3], float divisor)
+{
+ for (int i = 0; i < 3; i++)
+ a[i] /= divisor;
+}
+
+NV_INLINE void mul(float a[3], float multiplier)
+{
+ for (int i = 0; i < 3; i++)
+ a[i] *= multiplier;
+}
+
+NV_INLINE void add(const float a[3], float b[3])
+{
+ for (int i = 0; i < 3; i++)
+ b[i] = a[i] + b[i];
+}
+
+NV_INLINE void add(const float a[3], const float b[3], float r[3])
+{
+ for (int i = 0; i < 3; i++)
+ r[i] = a[i] + b[i];
+}
+
+NV_INLINE void sub(const float a[3], const float b[3], float r[3])
+{
+ for (int i = 0; i < 3; i++)
+ r[i] = a[i] - b[i];
+}
+
+NV_INLINE float dot(const float a[3], const float b[3])
+{
+ float r = 0;
+ for (int i = 0; i < 3; i++)
+ r += a[i] * b[i];
+ return r;
+}
+
+NV_INLINE float normal(const float a[3], float r[3])
+{
+ float length = sqrtf(dot(a, a));
+ for (int i = 0; i < 3; i++)
+ r[i] = a[i] / length;
+
+ return length;
+}
+
+
+} // namespace VecMath
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // #ifndef NVBLASTMATH_H
diff --git a/NvBlast/sdk/common/NvBlastMemory.h b/NvBlast/sdk/common/NvBlastMemory.h
new file mode 100644
index 0000000..0fb6a06
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastMemory.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016-2017, 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.
+ */
+
+#ifndef NVBLASTMEMORY_H
+#define NVBLASTMEMORY_H
+
+#include <math.h>
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+/**
+Utility function to align the given value to the next 16-byte boundary.
+
+Returns the aligned value.
+*/
+template<typename T>
+NV_INLINE T align16(T value)
+{
+ return (value + 0xF)&~(T)0xF;
+}
+
+
+/** Offset void* pointer by 'offset' bytes helper-functions */
+
+template <typename T>
+NV_INLINE T pointerOffset(void* p, ptrdiff_t offset)
+{
+ return reinterpret_cast<T>(reinterpret_cast<char*>(p)+offset);
+}
+
+template <typename T>
+NV_INLINE T pointerOffset(const void* p, ptrdiff_t offset)
+{
+ return reinterpret_cast<T>(reinterpret_cast<const char*>(p)+offset);
+}
+
+NV_INLINE const void* pointerOffset(const void* p, ptrdiff_t offset)
+{
+ return pointerOffset<const void*>(p, offset);
+}
+
+NV_INLINE void* pointerOffset(void* p, ptrdiff_t offset)
+{
+ return pointerOffset<void*>(p, offset);
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+/** Block data offset and accessor macro. */
+#define NvBlastBlockData(_dataType, _name, _accessor) \
+_dataType* _accessor() const \
+{ \
+ return (_dataType*)((uintptr_t)this + _name); \
+} \
+uint32_t _name
+
+
+/** Block data offset and accessor macro for an array (includes an _accessor##ArraySize() function which returns the last expression). */
+#define NvBlastBlockArrayData(_dataType, _name, _accessor, _sizeExpr) \
+_dataType* _accessor() const \
+{ \
+ return (_dataType*)((uintptr_t)this + _name); \
+} \
+uint32_t _accessor##ArraySize() const \
+{ \
+ return _sizeExpr; \
+} \
+uint32_t _name
+
+
+/** Block data offset generation macros. */
+
+/** Start offset generation with this. */
+#define NvBlastCreateOffsetStart(_baseOffset) \
+size_t _lastOffset = _baseOffset; \
+size_t _lastSize = 0
+
+/** Create the next offset generation with this. The value will be aligned to a 16-byte boundary. */
+#define NvBlastCreateOffsetAlign16(_name, _size) \
+_name = align16(_lastOffset + _lastSize); \
+_lastOffset = _name; \
+_lastSize = _size
+
+/** End offset generation with this. It evaluates to the (16-byte aligned) total size of the data block. */
+#define NvBlastCreateOffsetEndAlign16() \
+align16(_lastOffset + _lastSize)
+
+
+/** Stack allocation */
+#if NV_WINDOWS_FAMILY
+#include <malloc.h>
+#define NvBlastAlloca(x) _alloca(x)
+#elif NV_LINUX || NV_ANDROID
+#include <malloc.h>
+#define NvBlastAlloca(x) alloca(x)
+#elif NV_APPLE_FAMILY
+#include <alloca.h>
+#define NvBlastAlloca(x) alloca(x)
+#elif NV_PS4
+#include <memory.h>
+#define NvBlastAlloca(x) alloca(x)
+#elif NV_XBOXONE
+#include <malloc.h>
+#define NvBlastAlloca(x) alloca(x)
+#endif
+
+#define NvBlastAllocaAligned16(x) (void*)(((uintptr_t)PxAlloca(x + 0xF) + 0xF) & ~(uintptr_t)0xF)
+
+
+#endif // #ifndef NVBLASTMEMORY_H
diff --git a/NvBlast/sdk/common/NvBlastPreprocessorInternal.h b/NvBlast/sdk/common/NvBlastPreprocessorInternal.h
new file mode 100644
index 0000000..2d3e185
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastPreprocessorInternal.h
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTPREPROCESSORINTERNAL_H
+#define NVBLASTPREPROCESSORINTERNAL_H
+
+
+#include "NvPreprocessor.h"
+
+
+/** Blast will check function parameters for debug and checked builds. */
+#define NVBLAST_CHECK_PARAMS (NV_DEBUG || NV_CHECKED)
+
+
+#if NVBLAST_CHECK_PARAMS
+#define NVBLAST_CHECK(_expr, _logFn, _msg, _onFail) \
+ { \
+ if(!(_expr)) \
+ { \
+ if (_logFn) { _logFn(NvBlastMessage::Error, _msg, __FILE__, __LINE__); } \
+ { _onFail; }; \
+ } \
+ }
+#else
+#define NVBLAST_CHECK(_expr, _logFn, _msg, _onFail) NV_UNUSED(_logFn)
+#endif
+
+
+#endif // ifndef NVBLASTPREPROCESSORINTERNAL_H
diff --git a/NvBlast/sdk/common/NvBlastTime.cpp b/NvBlast/sdk/common/NvBlastTime.cpp
new file mode 100644
index 0000000..b16e573
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastTime.cpp
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2016-2017, 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 "NvBlastTime.h"
+#include "NvBlast.h"
+#include <cstring>
+
+namespace Nv
+{
+namespace Blast
+{
+
+const double Time::s_secondsPerTick = Time::getTickDuration();
+
+} // namespace Blast
+} // namespace Nv
diff --git a/NvBlast/sdk/common/NvBlastTime.h b/NvBlast/sdk/common/NvBlastTime.h
new file mode 100644
index 0000000..47af36b
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastTime.h
@@ -0,0 +1,108 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+/*
+* Copyright (c) 2016-2017, 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.
+*/
+
+#ifndef NVBLASTTIME_H
+#define NVBLASTTIME_H
+
+#include "NvBlastTypes.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+class Time
+{
+public:
+ Time() : m_lastTickCount(getTimeTicks()) {}
+
+ int64_t getElapsedTicks()
+ {
+ const int64_t lastTickCount = m_lastTickCount;
+ m_lastTickCount = getTimeTicks();
+ return m_lastTickCount - lastTickCount;
+ }
+
+ int64_t peekElapsedTicks() const
+ {
+ return getTimeTicks() - m_lastTickCount;
+ }
+
+ int64_t getLastTickCount() const
+ {
+ return m_lastTickCount;
+ }
+
+ static double seconds(int64_t ticks)
+ {
+ return s_secondsPerTick * ticks;
+ }
+
+private:
+ int64_t getTimeTicks() const;
+ static double getTickDuration();
+
+ int64_t m_lastTickCount;
+ static const double s_secondsPerTick;
+};
+
+} // namespace Blast
+} // namespace Nv
+
+
+//////// Time inline functions for various platforms ////////
+
+#if NV_MICROSOFT_FAMILY
+
+#include "NvBlastIncludeWindows.h"
+
+NV_INLINE int64_t Nv::Blast::Time::getTimeTicks() const
+{
+ LARGE_INTEGER a;
+ QueryPerformanceCounter(&a);
+ return a.QuadPart;
+}
+
+NV_INLINE double Nv::Blast::Time::getTickDuration()
+{
+ LARGE_INTEGER a;
+ QueryPerformanceFrequency(&a);
+ return 1.0 / (double)a.QuadPart;
+}
+
+#elif NV_UNIX_FAMILY
+
+#include <time.h>
+
+NV_INLINE int64_t Nv::Blast::Time::getTimeTicks() const
+{
+ struct timespec mCurrTimeInt;
+ clock_gettime(CLOCK_REALTIME, &mCurrTimeInt);
+ return (static_cast<int64_t>(mCurrTimeInt.tv_sec) * 1000000000) + (static_cast<int64_t>(mCurrTimeInt.tv_nsec));
+}
+
+NV_INLINE double Nv::Blast::Time::getTickDuration()
+{
+ return 1.e-9;
+}
+
+#elif NV_PS4
+
+#include "ps4/NvBlastTimePS4.h"
+
+#endif
+
+#endif // #ifndef NVBLASTTIME_H
diff --git a/NvBlast/sdk/common/NvBlastTimers.cpp b/NvBlast/sdk/common/NvBlastTimers.cpp
new file mode 100644
index 0000000..ec93134
--- /dev/null
+++ b/NvBlast/sdk/common/NvBlastTimers.cpp
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2016-2017, 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 "NvBlast.h"
+#include "NvBlastTime.h"
+#include <cstring>
+
+
+extern "C"
+{
+
+void NvBlastTimersReset(NvBlastTimers* timers)
+{
+ memset(timers, 0, sizeof(NvBlastTimers));
+}
+
+double NvBlastTicksToSeconds(int64_t ticks)
+{
+ return Nv::Blast::Time::seconds(ticks);
+}
+
+} // extern "C"