aboutsummaryrefslogtreecommitdiff
path: root/samples/AnselSDKDelayLoader/source/DelayLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'samples/AnselSDKDelayLoader/source/DelayLoader.cpp')
-rw-r--r--samples/AnselSDKDelayLoader/source/DelayLoader.cpp654
1 files changed, 327 insertions, 327 deletions
diff --git a/samples/AnselSDKDelayLoader/source/DelayLoader.cpp b/samples/AnselSDKDelayLoader/source/DelayLoader.cpp
index 362c63a..a7ec5f0 100644
--- a/samples/AnselSDKDelayLoader/source/DelayLoader.cpp
+++ b/samples/AnselSDKDelayLoader/source/DelayLoader.cpp
@@ -1,327 +1,327 @@
-// 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
-// proprietary rights in and to this software and 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.
-//
-// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
-// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
-// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
-// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Information and code furnished is believed to be accurate and reliable.
-// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
-// information or for any infringement of patents or other rights of third parties that may
-// result from its use. No license is granted by implication or otherwise under any patent
-// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
-// This code supersedes and replaces all information previously supplied.
-// NVIDIA Corporation products are not authorized for use as critical
-// components in life support devices or systems without express written approval of
-// NVIDIA Corporation.
-//
-// Copyright 2016 NVIDIA Corporation. All rights reserved.
-
-
-#define ANSEL_SDK_DELAYLOAD
-#include "DelayLoader.h"
-#include <ansel/Camera.h>
-#include <ansel/Hints.h>
-#include <ansel/Configuration.h>
-#include <ansel/UserControls.h>
-#include <cmath>
-#include <Windows.h>
-#include <stdio.h>
-#include <codecvt>
-
-
-namespace
-{
- HMODULE anselSDK = NULL;
-}
-
-namespace ansel
-{
- namespace
- {
- typedef SetConfigurationStatus(__cdecl *PFNSETCONFIGURATION)(const Configuration& cfg);
- typedef void(__cdecl *PFNUPDATECAMERA)(Camera& camera);
- typedef void(__cdecl *PFNSESSIONFUNC)();
- typedef bool(__cdecl *PFNISANSELAVAILABLE)();
- typedef void(__cdecl *PFNMARKBUFFERBIND)(BufferType, HintType, uint64_t);
- typedef void(__cdecl *PFNMARKBUFFERFINISHED)(BufferType, uint64_t);
- typedef UserControlStatus(__cdecl *PFNADDUSERCONTROL)(const UserControlDesc&);
- typedef UserControlStatus(__cdecl *PFNSETUSERCONTROLLABELLOCALIZATION)(uint32_t, const char*, const char*);
- typedef UserControlStatus(__cdecl *PFNREMOVEUSERCONTROL)(uint32_t);
- typedef UserControlStatus(__cdecl *PFNGETUSERCONTROLVALUE)(uint32_t, void*);
-
- PFNMARKBUFFERFINISHED markBufferFinishedFunc = nullptr;
- PFNMARKBUFFERBIND markBufferBindFunc = nullptr;
- PFNSESSIONFUNC stopSessionFunc = nullptr;
- PFNSESSIONFUNC startSessionFunc = nullptr;
- PFNUPDATECAMERA updateCameraFunc = nullptr;
- PFNSETCONFIGURATION setConfigurationFunc = nullptr;
- PFNADDUSERCONTROL addUserControlFunc = nullptr;
- PFNSETUSERCONTROLLABELLOCALIZATION setUserControlLabelLocalizationFunc = nullptr;
- PFNREMOVEUSERCONTROL removeUserControlFunc = nullptr;
- PFNGETUSERCONTROLVALUE getUserControlValueFunc = nullptr;
-
- DelayLoadStatus resolveFunctionPointers()
- {
- if (anselSDK == NULL)
- return kDelayLoadDllNotFound;
-
- setConfigurationFunc = reinterpret_cast<PFNSETCONFIGURATION>(GetProcAddress(anselSDK, "setConfiguration"));
- stopSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "stopSession"));
- startSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "startSession"));
- updateCameraFunc = reinterpret_cast<PFNUPDATECAMERA>(GetProcAddress(anselSDK, "updateCamera"));
- markBufferBindFunc = reinterpret_cast<PFNMARKBUFFERBIND>(GetProcAddress(anselSDK, "markBufferBind"));
- markBufferFinishedFunc = reinterpret_cast<PFNMARKBUFFERFINISHED>(GetProcAddress(anselSDK, "markBufferFinished"));
- addUserControlFunc = reinterpret_cast<PFNADDUSERCONTROL>(GetProcAddress(anselSDK, "addUserControl"));
- setUserControlLabelLocalizationFunc = reinterpret_cast<PFNSETUSERCONTROLLABELLOCALIZATION>(GetProcAddress(anselSDK, "setUserControlLabelLocalization"));
- removeUserControlFunc = reinterpret_cast<PFNREMOVEUSERCONTROL>(GetProcAddress(anselSDK, "removeUserControl"));
- getUserControlValueFunc = reinterpret_cast<PFNGETUSERCONTROLVALUE>(GetProcAddress(anselSDK, "getUserControlValue"));
-
- if (setConfigurationFunc == nullptr ||
- stopSessionFunc == nullptr ||
- startSessionFunc == nullptr ||
- updateCameraFunc == nullptr ||
- markBufferBindFunc == nullptr ||
- markBufferFinishedFunc == nullptr ||
- addUserControlFunc == nullptr ||
- setUserControlLabelLocalizationFunc == nullptr ||
- removeUserControlFunc == nullptr ||
- getUserControlValueFunc == nullptr)
- return kDelayLoadIncompatibleVersion;
-
- return kDelayLoadOk;
- }
-
- void makeQuaternionFromRotationMatrix(nv::Quat& q, const float r[3][3])
- {
- float trace = r[0][0] + r[1][1] + r[2][2];
-
- if (trace > 0.0f) {
- // |w| > 1/2, may as well choose w > 1/2
- float s = sqrtf(trace + 1.0f); // 2w
-
- q.w = s * 0.5f;
- s = 0.5f / s; // 1/(4w)
-
- q.x = (r[2][1] - r[1][2]) * s;
- q.y = (r[0][2] - r[2][0]) * s;
- q.z = (r[1][0] - r[0][1]) * s;
- }
- else {
- // |w| <= 1/2
- int i = 0;
- if (r[1][1] > r[0][0]) i = 1;
- if (r[2][2] > r[i][i]) i = 2;
-
- int j = (1 << i) & 3; // i + 1 modulo 3.
- int k = (1 << j) & 3;
-
- float s = sqrtf(r[i][i] - r[j][j] - r[k][k] + 1.0f);
-
- float* component = &q.x;
- component[i] = s * 0.5f;
- s = 0.5f / s;
- component[j] = (r[i][j] + r[j][i]) * s;
- component[k] = (r[k][i] + r[i][k]) * s;
- q.w = (r[k][j] - r[j][k]) * s;
- }
- }
-
- void makeRotationMatrixFromQuaternion(float rot[3][3], const nv::Quat& q)
- {
- float s = 2.0f;
-
- float xs = q.x * s;
- float ys = q.y * s;
- float zs = q.z * s;
-
- float wx = q.w * xs;
- float wy = q.w * ys;
- float wz = q.w * zs;
-
- float xx = q.x * xs;
- float xy = q.x * ys;
- float xz = q.x * zs;
-
- float yy = q.y * ys;
- float yz = q.y * zs;
- float zz = q.z * zs;
-
- rot[0][0] = 1.0f - (yy + zz);
- rot[0][1] = xy - wz;
- rot[0][2] = xz + wy;
-
- rot[1][0] = xy + wz;
- rot[1][1] = 1.0f - (xx + zz);
- rot[1][2] = yz - wx;
-
- rot[2][0] = xz - wy;
- rot[2][1] = yz + wx;
- rot[2][2] = 1.0f - (xx + yy);
- }
-
- // This may seem like a funky construct so allow me to explain. This code serves only
- // one purpose: to create a signaling object that Ansel (when loaded from driver shim)
- // can use to detect that a game has integrated the SDK. Note that this same object
- // will also be created by the SDK DLL when loaded but this is safe since creating
- // the same mutex again just provides a handle to the already existing mutex.
- class SdkMutex
- {
- public:
- SdkMutex()
- {
- DWORD id = GetCurrentProcessId();
- char name[MAX_PATH];
- sprintf_s(name, "NVIDIA/Ansel/%d", id);
- CreateMutexA(NULL, false, name);
- }
- };
-
- SdkMutex s_mySdkMutex;
- }
-
-
- SetConfigurationStatus setConfiguration(const Configuration& config)
- {
- if (setConfigurationFunc)
- return setConfigurationFunc(config);
- else
- return kSetConfigurationSdkNotLoaded;
- }
-
- void updateCamera(ansel::Camera& cam)
- {
- if (updateCameraFunc)
- updateCameraFunc(cam);
- }
-
- void stopSession()
- {
- if (stopSessionFunc)
- stopSessionFunc();
- }
-
- void startSession()
- {
- if (startSessionFunc)
- startSessionFunc();
- }
-
- bool isAnselAvailable()
- {
- // search for NvCamera32/64 DLL in the process
- const char* moduleName =
-#if _M_AMD64
- "NvCamera64.dll";
-#else
- "NvCamera32.dll";
-#endif
-
- return GetModuleHandleA(moduleName) != nullptr;
- }
-
- void markBufferBind(BufferType bufferType, HintType hintType, uint64_t threadId)
- {
- if (markBufferBindFunc)
- markBufferBindFunc(bufferType, hintType, threadId);
- }
-
- void markBufferFinished(BufferType bufferType, uint64_t threadId)
- {
- if (markBufferFinishedFunc)
- markBufferFinishedFunc(bufferType, threadId);
- }
-
- void quaternionToRotationMatrixVectors(const nv::Quat& q, nv::Vec3& right, nv::Vec3& up, nv::Vec3& forward)
- {
- float rot[3][3];
- makeRotationMatrixFromQuaternion(rot, q);
- right = { rot[0][0], rot[1][0], rot[2][0] };
- up = { rot[0][1], rot[1][1], rot[2][1] };
- forward = { rot[0][2], rot[1][2], rot[2][2] };
- }
-
- void rotationMatrixVectorsToQuaternion(const nv::Vec3& right, const nv::Vec3& up, const nv::Vec3& forward, nv::Quat& q)
- {
- const float rot[3][3] = {
- { right.x, up.x, forward.x },
- { right.y, up.y, forward.y },
- { right.z, up.z, forward.z }
- };
- makeQuaternionFromRotationMatrix(q, rot);
- }
-
- UserControlStatus addUserControl(const UserControlDesc& desc)
- {
- if (addUserControlFunc)
- return addUserControlFunc(desc);
- return UserControlStatus::kUserControlInvalidCallback;
- }
-
- UserControlStatus setUserControlLabelLocalization(uint32_t userControlId, const char* lang, const char* labelUtf8)
- {
- if (setUserControlLabelLocalizationFunc)
- return setUserControlLabelLocalizationFunc(userControlId, lang, labelUtf8);
- return UserControlStatus::kUserControlInvalidCallback;
- }
-
- UserControlStatus removeUserControl(uint32_t userControlId)
- {
- if (removeUserControlFunc)
- return removeUserControlFunc(userControlId);
- return UserControlStatus::kUserControlInvalidCallback;
- }
-
- UserControlStatus getUserControlValue(uint32_t userControlId, void* value)
- {
- if (getUserControlValueFunc)
- return getUserControlValueFunc(userControlId, value);
- return UserControlStatus::kUserControlInvalidCallback;
- }
-}
-
-DelayLoadStatus loadAnselSDKLibrary(const char* pathToLibraryUtf8)
-{
- if (anselSDK == NULL)
- {
- if (pathToLibraryUtf8)
- {
- // convert from utf8 to wchar_t:
- std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
- std::wstring pathWstring = converter.from_bytes(pathToLibraryUtf8);
- anselSDK = LoadLibraryW(pathWstring.c_str());
- }
- else
- {
- #if defined(_M_IX86)
- #define ANSEL_BITNESS "32"
- #elif defined(_M_AMD64)
- #define ANSEL_BITNESS "64"
- #endif
-
- #if defined(_DEBUG)
- #define ANSEL_RUNTIME_FLAVOR "d"
- #else
- #define ANSEL_RUNTIME_FLAVOR ""
- #endif
-
- const char* libName = "AnselSDK" ANSEL_BITNESS ANSEL_RUNTIME_FLAVOR ".dll";
- anselSDK = LoadLibraryA(libName);
- }
-
- if (anselSDK == NULL)
- return kDelayLoadDllNotFound;
- else
- return ansel::resolveFunctionPointers();
- }
-
- return kDelayLoadOk;
-}
+// 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
+// proprietary rights in and to this software and 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright 2016 NVIDIA Corporation. All rights reserved.
+
+
+#define ANSEL_SDK_DELAYLOAD
+#include "DelayLoader.h"
+#include <ansel/Camera.h>
+#include <ansel/Hints.h>
+#include <ansel/Configuration.h>
+#include <ansel/UserControls.h>
+#include <cmath>
+#include <Windows.h>
+#include <stdio.h>
+#include <codecvt>
+
+
+namespace
+{
+ HMODULE anselSDK = NULL;
+}
+
+namespace ansel
+{
+ namespace
+ {
+ typedef SetConfigurationStatus(__cdecl *PFNSETCONFIGURATION)(const Configuration& cfg);
+ typedef void(__cdecl *PFNUPDATECAMERA)(Camera& camera);
+ typedef void(__cdecl *PFNSESSIONFUNC)();
+ typedef bool(__cdecl *PFNISANSELAVAILABLE)();
+ typedef void(__cdecl *PFNMARKBUFFERBIND)(BufferType, HintType, uint64_t);
+ typedef void(__cdecl *PFNMARKBUFFERFINISHED)(BufferType, uint64_t);
+ typedef UserControlStatus(__cdecl *PFNADDUSERCONTROL)(const UserControlDesc&);
+ typedef UserControlStatus(__cdecl *PFNSETUSERCONTROLLABELLOCALIZATION)(uint32_t, const char*, const char*);
+ typedef UserControlStatus(__cdecl *PFNREMOVEUSERCONTROL)(uint32_t);
+ typedef UserControlStatus(__cdecl *PFNGETUSERCONTROLVALUE)(uint32_t, void*);
+
+ PFNMARKBUFFERFINISHED markBufferFinishedFunc = nullptr;
+ PFNMARKBUFFERBIND markBufferBindFunc = nullptr;
+ PFNSESSIONFUNC stopSessionFunc = nullptr;
+ PFNSESSIONFUNC startSessionFunc = nullptr;
+ PFNUPDATECAMERA updateCameraFunc = nullptr;
+ PFNSETCONFIGURATION setConfigurationFunc = nullptr;
+ PFNADDUSERCONTROL addUserControlFunc = nullptr;
+ PFNSETUSERCONTROLLABELLOCALIZATION setUserControlLabelLocalizationFunc = nullptr;
+ PFNREMOVEUSERCONTROL removeUserControlFunc = nullptr;
+ PFNGETUSERCONTROLVALUE getUserControlValueFunc = nullptr;
+
+ DelayLoadStatus resolveFunctionPointers()
+ {
+ if (anselSDK == NULL)
+ return kDelayLoadDllNotFound;
+
+ setConfigurationFunc = reinterpret_cast<PFNSETCONFIGURATION>(GetProcAddress(anselSDK, "setConfiguration"));
+ stopSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "stopSession"));
+ startSessionFunc = reinterpret_cast<PFNSESSIONFUNC>(GetProcAddress(anselSDK, "startSession"));
+ updateCameraFunc = reinterpret_cast<PFNUPDATECAMERA>(GetProcAddress(anselSDK, "updateCamera"));
+ markBufferBindFunc = reinterpret_cast<PFNMARKBUFFERBIND>(GetProcAddress(anselSDK, "markBufferBind"));
+ markBufferFinishedFunc = reinterpret_cast<PFNMARKBUFFERFINISHED>(GetProcAddress(anselSDK, "markBufferFinished"));
+ addUserControlFunc = reinterpret_cast<PFNADDUSERCONTROL>(GetProcAddress(anselSDK, "addUserControl"));
+ setUserControlLabelLocalizationFunc = reinterpret_cast<PFNSETUSERCONTROLLABELLOCALIZATION>(GetProcAddress(anselSDK, "setUserControlLabelLocalization"));
+ removeUserControlFunc = reinterpret_cast<PFNREMOVEUSERCONTROL>(GetProcAddress(anselSDK, "removeUserControl"));
+ getUserControlValueFunc = reinterpret_cast<PFNGETUSERCONTROLVALUE>(GetProcAddress(anselSDK, "getUserControlValue"));
+
+ if (setConfigurationFunc == nullptr ||
+ stopSessionFunc == nullptr ||
+ startSessionFunc == nullptr ||
+ updateCameraFunc == nullptr ||
+ markBufferBindFunc == nullptr ||
+ markBufferFinishedFunc == nullptr ||
+ addUserControlFunc == nullptr ||
+ setUserControlLabelLocalizationFunc == nullptr ||
+ removeUserControlFunc == nullptr ||
+ getUserControlValueFunc == nullptr)
+ return kDelayLoadIncompatibleVersion;
+
+ return kDelayLoadOk;
+ }
+
+ void makeQuaternionFromRotationMatrix(nv::Quat& q, const float r[3][3])
+ {
+ float trace = r[0][0] + r[1][1] + r[2][2];
+
+ if (trace > 0.0f) {
+ // |w| > 1/2, may as well choose w > 1/2
+ float s = sqrtf(trace + 1.0f); // 2w
+
+ q.w = s * 0.5f;
+ s = 0.5f / s; // 1/(4w)
+
+ q.x = (r[2][1] - r[1][2]) * s;
+ q.y = (r[0][2] - r[2][0]) * s;
+ q.z = (r[1][0] - r[0][1]) * s;
+ }
+ else {
+ // |w| <= 1/2
+ int i = 0;
+ if (r[1][1] > r[0][0]) i = 1;
+ if (r[2][2] > r[i][i]) i = 2;
+
+ int j = (1 << i) & 3; // i + 1 modulo 3.
+ int k = (1 << j) & 3;
+
+ float s = sqrtf(r[i][i] - r[j][j] - r[k][k] + 1.0f);
+
+ float* component = &q.x;
+ component[i] = s * 0.5f;
+ s = 0.5f / s;
+ component[j] = (r[i][j] + r[j][i]) * s;
+ component[k] = (r[k][i] + r[i][k]) * s;
+ q.w = (r[k][j] - r[j][k]) * s;
+ }
+ }
+
+ void makeRotationMatrixFromQuaternion(float rot[3][3], const nv::Quat& q)
+ {
+ float s = 2.0f;
+
+ float xs = q.x * s;
+ float ys = q.y * s;
+ float zs = q.z * s;
+
+ float wx = q.w * xs;
+ float wy = q.w * ys;
+ float wz = q.w * zs;
+
+ float xx = q.x * xs;
+ float xy = q.x * ys;
+ float xz = q.x * zs;
+
+ float yy = q.y * ys;
+ float yz = q.y * zs;
+ float zz = q.z * zs;
+
+ rot[0][0] = 1.0f - (yy + zz);
+ rot[0][1] = xy - wz;
+ rot[0][2] = xz + wy;
+
+ rot[1][0] = xy + wz;
+ rot[1][1] = 1.0f - (xx + zz);
+ rot[1][2] = yz - wx;
+
+ rot[2][0] = xz - wy;
+ rot[2][1] = yz + wx;
+ rot[2][2] = 1.0f - (xx + yy);
+ }
+
+ // This may seem like a funky construct so allow me to explain. This code serves only
+ // one purpose: to create a signaling object that Ansel (when loaded from driver shim)
+ // can use to detect that a game has integrated the SDK. Note that this same object
+ // will also be created by the SDK DLL when loaded but this is safe since creating
+ // the same mutex again just provides a handle to the already existing mutex.
+ class SdkMutex
+ {
+ public:
+ SdkMutex()
+ {
+ DWORD id = GetCurrentProcessId();
+ char name[MAX_PATH];
+ sprintf_s(name, "NVIDIA/Ansel/%d", id);
+ CreateMutexA(NULL, false, name);
+ }
+ };
+
+ SdkMutex s_mySdkMutex;
+ }
+
+
+ SetConfigurationStatus setConfiguration(const Configuration& config)
+ {
+ if (setConfigurationFunc)
+ return setConfigurationFunc(config);
+ else
+ return kSetConfigurationSdkNotLoaded;
+ }
+
+ void updateCamera(ansel::Camera& cam)
+ {
+ if (updateCameraFunc)
+ updateCameraFunc(cam);
+ }
+
+ void stopSession()
+ {
+ if (stopSessionFunc)
+ stopSessionFunc();
+ }
+
+ void startSession()
+ {
+ if (startSessionFunc)
+ startSessionFunc();
+ }
+
+ bool isAnselAvailable()
+ {
+ // search for NvCamera32/64 DLL in the process
+ const char* moduleName =
+#if _M_AMD64
+ "NvCamera64.dll";
+#else
+ "NvCamera32.dll";
+#endif
+
+ return GetModuleHandleA(moduleName) != nullptr;
+ }
+
+ void markBufferBind(BufferType bufferType, HintType hintType, uint64_t threadId)
+ {
+ if (markBufferBindFunc)
+ markBufferBindFunc(bufferType, hintType, threadId);
+ }
+
+ void markBufferFinished(BufferType bufferType, uint64_t threadId)
+ {
+ if (markBufferFinishedFunc)
+ markBufferFinishedFunc(bufferType, threadId);
+ }
+
+ void quaternionToRotationMatrixVectors(const nv::Quat& q, nv::Vec3& right, nv::Vec3& up, nv::Vec3& forward)
+ {
+ float rot[3][3];
+ makeRotationMatrixFromQuaternion(rot, q);
+ right = { rot[0][0], rot[1][0], rot[2][0] };
+ up = { rot[0][1], rot[1][1], rot[2][1] };
+ forward = { rot[0][2], rot[1][2], rot[2][2] };
+ }
+
+ void rotationMatrixVectorsToQuaternion(const nv::Vec3& right, const nv::Vec3& up, const nv::Vec3& forward, nv::Quat& q)
+ {
+ const float rot[3][3] = {
+ { right.x, up.x, forward.x },
+ { right.y, up.y, forward.y },
+ { right.z, up.z, forward.z }
+ };
+ makeQuaternionFromRotationMatrix(q, rot);
+ }
+
+ UserControlStatus addUserControl(const UserControlDesc& desc)
+ {
+ if (addUserControlFunc)
+ return addUserControlFunc(desc);
+ return UserControlStatus::kUserControlInvalidCallback;
+ }
+
+ UserControlStatus setUserControlLabelLocalization(uint32_t userControlId, const char* lang, const char* labelUtf8)
+ {
+ if (setUserControlLabelLocalizationFunc)
+ return setUserControlLabelLocalizationFunc(userControlId, lang, labelUtf8);
+ return UserControlStatus::kUserControlInvalidCallback;
+ }
+
+ UserControlStatus removeUserControl(uint32_t userControlId)
+ {
+ if (removeUserControlFunc)
+ return removeUserControlFunc(userControlId);
+ return UserControlStatus::kUserControlInvalidCallback;
+ }
+
+ UserControlStatus getUserControlValue(uint32_t userControlId, void* value)
+ {
+ if (getUserControlValueFunc)
+ return getUserControlValueFunc(userControlId, value);
+ return UserControlStatus::kUserControlInvalidCallback;
+ }
+}
+
+DelayLoadStatus loadAnselSDKLibrary(const char* pathToLibraryUtf8)
+{
+ if (anselSDK == NULL)
+ {
+ if (pathToLibraryUtf8)
+ {
+ // convert from utf8 to wchar_t:
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
+ std::wstring pathWstring = converter.from_bytes(pathToLibraryUtf8);
+ anselSDK = LoadLibraryW(pathWstring.c_str());
+ }
+ else
+ {
+ #if defined(_M_IX86)
+ #define ANSEL_BITNESS "32"
+ #elif defined(_M_AMD64)
+ #define ANSEL_BITNESS "64"
+ #endif
+
+ #if defined(_DEBUG)
+ #define ANSEL_RUNTIME_FLAVOR "d"
+ #else
+ #define ANSEL_RUNTIME_FLAVOR ""
+ #endif
+
+ const char* libName = "AnselSDK" ANSEL_BITNESS ANSEL_RUNTIME_FLAVOR ".dll";
+ anselSDK = LoadLibraryA(libName);
+ }
+
+ if (anselSDK == NULL)
+ return kDelayLoadDllNotFound;
+ else
+ return ansel::resolveFunctionPointers();
+ }
+
+ return kDelayLoadOk;
+}