File SkeletonSetupManager.cpp
File List > api > cppSDK > SDKBase > SkeletonSetupManager.cpp
Go to the documentation of this file
#include <mutex>
#include <vector>
#include <string>
#include <atomic>
#include "ManusSDKExtendedTypes.h"
#include "SkeletonSetupManager.hpp"
#include "SkeletonSetup.hpp"
#include "Logging.hpp"
// shared code for both windows and android versions of the SDK.
namespace ManusSDK
{
SkeletonSetupManager::~SkeletonSetupManager()
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
ClearAllTemporarySkeletonsFromBuffer();
}
void SkeletonSetupManager::IfEmptyClearSkeletonSetupBuffer()
{
for (size_t i = 0; i < m_SkeletonSetupBuffer.size(); i++)
{
if (m_SkeletonSetupBuffer[i] != nullptr)
return;
}
m_SkeletonSetupBuffer.clear();
}
SDKReturnCode SkeletonSetupManager::CreateSkeletonSetup(const SkeletonSetupInfo& p_SkeletonSetupInfo, uint32_t& p_SkeletonSetupIndex)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = new SkeletonSetup(p_SkeletonSetupInfo);
for (size_t i = 0; i < m_SkeletonSetupBuffer.size(); i++)
{
if (m_SkeletonSetupBuffer[i] == nullptr)
{
p_SkeletonSetupIndex = (uint32_t)i;
m_SkeletonSetupBuffer[p_SkeletonSetupIndex] = t_Skl;
return SDKReturnCode::SDKReturnCode_Success;
}
}
if (m_SkeletonSetupBuffer.size() == MAX_NUMBER_OF_SKELETONS_PER_SESSION)
{
delete t_Skl;
Log::Warn(__FUNCTION__, "The max number of temporary skeletons per session has been reached, either load or clear a temporary skeleton.");
return SDKReturnCode::SDKReturnCode_ArgumentSizeMismatch;
}
p_SkeletonSetupIndex = (uint32_t)m_SkeletonSetupBuffer.size();
m_SkeletonSetupBuffer.push_back(t_Skl);
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::AddNodeToSkeletonSetup(uint32_t p_SkeletonSetupIndex, const NodeSetup& p_Node)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
t_Skl->nodes.push_back(new NodeSetup(p_Node));
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::OverwriteChainToSkeletonSetup(uint32_t p_SkeletonSetupIndex, const ChainSetup& p_Chain)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
for (size_t i = 0; i < t_Skl->chains.size(); i++)
{
if (t_Skl->chains[i]->id == p_Chain.id)
{
delete t_Skl->chains[i];
t_Skl->chains[i] = new ChainSetup(p_Chain);
return SDKReturnCode::SDKReturnCode_Success;
}
}
return SDKReturnCode::SDKReturnCode_InvalidID;
}
SDKReturnCode SkeletonSetupManager::OverwriteNodeToSkeletonSetup(uint32_t p_SkeletonSetupIndex, const NodeSetup& p_Node)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
for (size_t i = 0; i < t_Skl->nodes.size(); i++)
{
if (t_Skl->nodes[i]->id == p_Node.id)
{
delete t_Skl->nodes[i];
t_Skl->nodes[i] = new NodeSetup(p_Node);
return SDKReturnCode::SDKReturnCode_Success;
}
}
return SDKReturnCode::SDKReturnCode_InvalidID;
}
SDKReturnCode SkeletonSetupManager::AddChainToSkeletonSetup(uint32_t p_SkeletonSetupIndex, const ChainSetup& p_Chain)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
t_Skl->chains.push_back(new ChainSetup(p_Chain));
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::AddColliderToSkeletonSetup(uint32_t p_SkeletonSetupIndex, const ColliderSetup& p_Collider)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
t_Skl->colliders.push_back(new ColliderSetup(p_Collider));
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::AddMeshSetupToSkeletonSetup(uint32_t p_SkeletonSetupIndex, uint32_t p_NodeId, uint32_t& p_MeshSetupIndex)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
t_Skl->meshes.push_back(new MeshSetup(p_NodeId));
p_MeshSetupIndex = (uint32_t)(t_Skl->meshes.size() - 1);
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::AddVertexToMeshSetup(uint32_t p_SkeletonSetupIndex, uint32_t p_MeshSetupIndex, const Vertex& p_Vertex)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
MeshSetup* t_Mesh = nullptr;
if (t_Skl->meshes.size() > p_MeshSetupIndex)
{
t_Mesh = t_Skl->meshes[p_MeshSetupIndex];
}
if (t_Mesh == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
t_Mesh->vertices.push_back(new Vertex(p_Vertex));
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::AddTriangleToMeshSetup(uint32_t p_SkeletonSetupIndex, uint32_t p_MeshSetupIndex, const Triangle& p_Triangle)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
MeshSetup* t_Mesh = nullptr;
if (t_Skl->meshes.size() > p_MeshSetupIndex)
{
t_Mesh = t_Skl->meshes[p_MeshSetupIndex];
}
if (t_Mesh == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
t_Mesh->triangles.push_back(new Triangle(p_Triangle));
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::GetMeshSetupInfo(uint32_t p_SkeletonSetupIndex, uint32_t p_MeshSetupIndex, MeshSetupInfo& p_MeshSetupInfo)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
MeshSetup* t_Mesh = nullptr;
if (t_Skl->meshes.size() > p_MeshSetupIndex)
{
t_Mesh = t_Skl->meshes[p_MeshSetupIndex];
}
if (t_Mesh == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
p_MeshSetupInfo.nodeId = t_Mesh->nodeID;
p_MeshSetupInfo.vertexCount = (uint32_t)t_Mesh->vertices.size();
p_MeshSetupInfo.triangleCount = (uint32_t)t_Mesh->triangles.size();
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::GetVertexData(uint32_t p_SkeletonSetupIndex, uint32_t p_MeshSetupIndex, uint32_t p_VertexIndex, Vertex& p_Vertex)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
MeshSetup* t_Mesh = nullptr;
if (t_Skl->meshes.size() > p_MeshSetupIndex)
{
t_Mesh = t_Skl->meshes[p_MeshSetupIndex];
}
if (t_Mesh == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
Vertex* t_Vertex = nullptr;
if (t_Mesh->vertices.size() > p_VertexIndex)
{
t_Vertex = t_Mesh->vertices[p_VertexIndex];
}
if (t_Vertex == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
p_Vertex = *t_Vertex;
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::GetTriangleData(uint32_t p_SkeletonSetupIndex, uint32_t p_MeshSetupIndex, uint32_t p_TriangleIndex, Triangle& p_Triangle)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
MeshSetup* t_Mesh = nullptr;
if (t_Skl->meshes.size() > p_MeshSetupIndex)
{
t_Mesh = t_Skl->meshes[p_MeshSetupIndex];
}
if (t_Mesh == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
Triangle* t_Triangle = nullptr;
if (t_Mesh->triangles.size() > p_TriangleIndex)
{
t_Triangle = t_Mesh->triangles[p_TriangleIndex];
}
if (t_Triangle == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
p_Triangle = *t_Triangle;
return SDKReturnCode::SDKReturnCode_Success;
}
SkeletonSetup* SkeletonSetupManager::GetSkeletonSetup(uint32_t p_SkeletonSetupIndex)
{
SkeletonSetup* t_Skl = nullptr;
if (m_SkeletonSetupBuffer.size() > p_SkeletonSetupIndex)
{
t_Skl = m_SkeletonSetupBuffer[p_SkeletonSetupIndex];
}
return t_Skl;
}
void SkeletonSetupManager::ClearSkeletonSetup(uint32_t p_SkeletonSetupIndex)
{
if (p_SkeletonSetupIndex >= m_SkeletonSetupBuffer.size())
{
Log::Error(__FUNCTION__, "tried to delete non existing skeleton setup.");
return;
}
delete m_SkeletonSetupBuffer[p_SkeletonSetupIndex];
m_SkeletonSetupBuffer[p_SkeletonSetupIndex] = nullptr;
IfEmptyClearSkeletonSetupBuffer();
}
void SkeletonSetupManager::InsertSkeletonSetup(uint32_t p_SkeletonSetupIndex, SkeletonSetup* p_LocalSkl)
{
if (m_SkeletonSetupBuffer.size() > p_SkeletonSetupIndex)
{
if (m_SkeletonSetupBuffer[p_SkeletonSetupIndex] == nullptr) delete m_SkeletonSetupBuffer[p_SkeletonSetupIndex];
m_SkeletonSetupBuffer[p_SkeletonSetupIndex] = p_LocalSkl;
}
else
{
for (uint32_t i = (uint32_t)m_SkeletonSetupBuffer.size(); i < p_SkeletonSetupIndex; i++)
{
m_SkeletonSetupBuffer.push_back(nullptr);
}
m_SkeletonSetupBuffer.push_back(p_LocalSkl);
}
}
void SkeletonSetupManager::ClearAllTemporarySkeletonsFromBuffer()
{
for (size_t i = 0; i < m_SkeletonSetupBuffer.size(); i++)
{
if (m_SkeletonSetupBuffer[i] != nullptr)
{
delete m_SkeletonSetupBuffer[i];
}
}
m_SkeletonSetupBuffer.clear();
}
SDKReturnCode SkeletonSetupManager::OverwriteSkeletonSetup(uint32_t p_SkeletonSetupIndex, const SkeletonSetupInfo& p_SkeletonSetupInfo)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
if (m_SkeletonSetupBuffer.size() <= p_SkeletonSetupIndex)
{
//SPDLOG_WARN("No skeleton setup with index {} was found to overwrite", p_SkeletonSetupIndex);
return SDKReturnCode::SDKReturnCode_InvalidID;
}
SkeletonSetup* t_Skl = new SkeletonSetup(p_SkeletonSetupInfo);
if (m_SkeletonSetupBuffer[p_SkeletonSetupIndex] != nullptr)delete m_SkeletonSetupBuffer[p_SkeletonSetupIndex];
m_SkeletonSetupBuffer[p_SkeletonSetupIndex] = t_Skl;
if (m_SkeletonSetupBuffer[p_SkeletonSetupIndex] != nullptr)
{
return SDKReturnCode::SDKReturnCode_Success;
}
return SDKReturnCode::SDKReturnCode_NullPointer;
}
SDKReturnCode SkeletonSetupManager::GetSkeletonSetupArraySizes(uint32_t p_SkeletonSetupIndex, SkeletonSetupArraySizes& p_SkeletonInfo)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
p_SkeletonInfo.nodesCount = (uint32_t)t_Skl->nodes.size();
p_SkeletonInfo.chainsCount = (uint32_t)t_Skl->chains.size();
p_SkeletonInfo.collidersCount = (uint32_t)t_Skl->colliders.size();
p_SkeletonInfo.meshCount = (uint32_t)t_Skl->meshes.size();
return SDKReturnCode::SDKReturnCode_Success;
}
// p_SDK is a pre allocated array of chainsetups! check SkeletonSetupArraySizes to determine its size before allocating!
SDKReturnCode SkeletonSetupManager::GetSkeletonChains(uint32_t p_SkeletonSetupIndex, ChainSetup* p_SDK)
{
if (p_SDK == nullptr)
{
return SDKReturnCode::SDKReturnCode_NullPointer;
}
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
for (size_t i = 0; i < t_Skl->chains.size(); i++)
{
p_SDK[i] = *t_Skl->chains[i];
}
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::GetSkeletonChains(uint32_t p_SkeletonSetupIndex, ChainSetup* p_ChainSetupArray, uint32_t p_ArraySize)
{
if (p_ChainSetupArray == nullptr)
{
return SDKReturnCode::SDKReturnCode_NullPointer;
}
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
if (p_ArraySize != t_Skl->chains.size())
{
return SDKReturnCode::SDKReturnCode_ArgumentSizeMismatch;
}
for (size_t i = 0; i < t_Skl->chains.size(); i++)
{
p_ChainSetupArray[i] = *t_Skl->chains[i];
}
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::GetSkeletonSetupInfo(uint32_t p_SkeletonSetupIndex, SkeletonSetupInfo* p_SDK)
{
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
p_SDK->id = t_Skl->info->id;
p_SDK->type = t_Skl->info->type;
for (int i = 0; i < MAX_NUM_CHARS_IN_SKELETON_NAME; i++) // note this is not a regular string. but an UTF8 array. hence this form of copy.
{
p_SDK->name[i] = t_Skl->info->name[i];
}
p_SDK->settings.collisionType = t_Skl->info->settings.collisionType;
p_SDK->settings.scaleToTarget = t_Skl->info->settings.scaleToTarget;
p_SDK->settings.skeletonGloveData.gloveID = t_Skl->info->settings.skeletonGloveData.gloveID;
for (int i = 0; i < MAX_NUM_CHARS_IN_TARGET_ID; i++) // note this is not a regular string. but an UTF8 array. hence this form of copy.
{
p_SDK->settings.skeletonTargetAnimationData.id[i] = t_Skl->info->settings.skeletonTargetAnimationData.id[i];
}
p_SDK->settings.skeletonTargetUserData.userID = t_Skl->info->settings.skeletonTargetUserData.userID;
p_SDK->settings.skeletonTargetUserIndexData.userIndex = t_Skl->info->settings.skeletonTargetUserIndexData.userIndex;
p_SDK->settings.targetType = t_Skl->info->settings.targetType;
p_SDK->settings.useEndPointApproximations = t_Skl->info->settings.useEndPointApproximations;
return SDKReturnCode::SDKReturnCode_Success;
}
// p_SDK is a pre allocated array of nodesetups! check chainskeletoninfo to determine its size before allocating!
SDKReturnCode SkeletonSetupManager::GetSkeletonNodes(uint32_t p_SkeletonSetupIndex, NodeSetup* p_SDK)
{
if (p_SDK == nullptr)
{
return SDKReturnCode::SDKReturnCode_NullPointer;
}
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
for (size_t i = 0; i < t_Skl->nodes.size(); i++)
{
p_SDK[i] = *t_Skl->nodes[i];
}
return SDKReturnCode::SDKReturnCode_Success;
}
SDKReturnCode SkeletonSetupManager::GetSkeletonNodes(uint32_t p_SkeletonSetupIndex, NodeSetup* p_NodeSetupArray, uint32_t p_ArraySize)
{
if (p_NodeSetupArray == nullptr)
{
return SDKReturnCode::SDKReturnCode_NullPointer;
}
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
if (p_ArraySize != t_Skl->nodes.size())
{
return SDKReturnCode::SDKReturnCode_ArgumentSizeMismatch;
}
for (size_t i = 0; i < t_Skl->nodes.size(); i++)
{
p_NodeSetupArray[i] = *t_Skl->nodes[i];
}
return SDKReturnCode::SDKReturnCode_Success;
}
// p_SDK is a pre allocated array of collider setups! check chainskeletoninfo to determine its size before allocating!
SDKReturnCode SkeletonSetupManager::GetSkeletonColliders(uint32_t p_SkeletonSetupIndex, ColliderSetup* p_SDK)
{
if (p_SDK == nullptr)
{
return SDKReturnCode::SDKReturnCode_NullPointer;
}
const std::lock_guard<std::mutex> t_ManagedMutexLock(m_SkeletonSetupMutex);
SkeletonSetup* t_Skl = GetSkeletonSetup(p_SkeletonSetupIndex);
if (t_Skl == nullptr)
{
return SDKReturnCode::SDKReturnCode_InvalidID;
}
for (size_t i = 0; i < t_Skl->colliders.size(); i++)
{
p_SDK[i] = *t_Skl->colliders[i];
}
return SDKReturnCode::SDKReturnCode_Success;
}
std::mutex& SkeletonSetupManager::GetSkeletonSetupMutex()
{
return m_SkeletonSetupMutex;
}
size_t SkeletonSetupManager::GetSkeletonSetupBufferSize()
{
return m_SkeletonSetupBuffer.size();
}
}