<commit_before>#pragma once
#include "Skeleton.h"

namespace DEM::Anim
{

void CSkeleton::SetRootNode(Scene::CSceneNode* pNode)
{
	if (_Nodes.empty())
	{
		if (pNode) _Nodes.push_back(pNode);
	}
	else _Nodes[0] = pNode;

	//!!!could rebind instead of invalidating!
	//!!!to rebind, needs to remember name+parent when port is created!
	for (size_t i = 1; i < _Nodes.size(); ++i)
		_Nodes[i] = nullptr;
}
//---------------------------------------------------------------------

U16 CSkeleton::BindNode(CStrID NodeID, U16 ParentPort)
{
	// Return root port is no parent is specified
	if (ParentPort == InvalidPort) return _Nodes.empty() ? InvalidPort : 0;

	const Scene::CSceneNode* pParent = _Nodes[ParentPort].Get();
	if (!pParent) return InvalidPort;

	Scene::CSceneNode* pNode = pParent->GetChild(NodeID);
	if (!pNode) return InvalidPort;

	// Check if this node is already bound to some port
	auto It = std::find(_Nodes.cbegin(), _Nodes.cend(), pNode);
	if (It != _Nodes.cend()) return static_cast<U16>(std::distance(_Nodes.cbegin(), It));

	// Create new port, if not
	_Nodes.push_back(pNode);
	return static_cast<U16>(_Nodes.size() - 1);
}
//---------------------------------------------------------------------

bool CSkeleton::IsPortActive(U16 Port) const
{
	return _Nodes.size() > Port && _Nodes[Port] && _Nodes[Port]->IsActive();
}
//---------------------------------------------------------------------

void CSkeleton::SetScale(U16 Port, const vector3& Scale)
{
	_Nodes[Port]->SetLocalScale(Scale);
}
//---------------------------------------------------------------------

void CSkeleton::SetRotation(U16 Port, const quaternion& Rotation)
{
	_Nodes[Port]->SetLocalRotation(Rotation);
}
//---------------------------------------------------------------------<commit_msg>Binding nodes by path from root if no parent is defined (for animated nodes with not animated parents)<commit_after>#pragma once
#include "Skeleton.h"

namespace DEM::Anim
{

void CSkeleton::SetRootNode(Scene::CSceneNode* pNode)
{
	if (_Nodes.empty())
	{
		if (pNode) _Nodes.push_back(pNode);
	}
	else _Nodes[0] = pNode;

	//!!!could rebind instead of invalidating!
	//!!!to rebind, needs to remember name+parent when port is created!
	for (size_t i = 1; i < _Nodes.size(); ++i)
		_Nodes[i] = nullptr;
}
//---------------------------------------------------------------------

U16 CSkeleton::BindNode(CStrID NodeID, U16 ParentPort)
{
	// Root must be set before binding other nodes
	if (_Nodes.empty() || !_Nodes[0]) return InvalidPort;

	Scene::CSceneNode* pNode = nullptr;
	if (ParentPort == InvalidPort)
	{
		// When no parent specified, we search by path from the root node.
		// Empty path is the root node itself, and root port is always 0.
		// FIXME: either require name matching or always store empty ID for clip root in DEM ACL files!
		if (!NodeID || NodeID == _Nodes[0]->GetName()) return 0;
		pNode = _Nodes[0]->FindNodeByPath(NodeID.CStr());
	}
	else if (auto pParent = _Nodes[ParentPort].Get())
	{
		// When parent is specified, the node is its direct child
		pNode = pParent->GetChild(NodeID);
	}

	if (!pNode) return InvalidPort;

	// Check if this node is already bound to some port
	auto It = std::find(_Nodes.cbegin(), _Nodes.cend(), pNode);
	if (It != _Nodes.cend()) return static_cast<U16>(std::distance(_Nodes.cbegin(), It));

	// Create new port, if not
	_Nodes.push_back(pNode);
	return static_cast<U16>(_Nodes.size() - 1);
}
//---------------------------------------------------------------------

bool CSkeleton::IsPortActive(U16 Port) const
{
	return _Nodes.size() > Port && _Nodes[Port] && _Nodes[Port]->IsActive();
}
//---------------------------------------------------------------------

void CSkeleton::SetScale(U16 Port, const vector3& Scale)
{
	_Nodes[Port]->SetLocalScale(Scale);
}
//---------------------------------------------------------------------

void CSkeleton::SetRotation(U16 Port, const quaternion& Rotation)
{
	_Nodes[Port]->SetLocalRotation(Rotation);
}
//---------------------------------------------------------------------
{'fraction_non_alphanumeric': 0.293711467324291, 'fraction_numerical': 0.010357583230579531, 'mean_word_length': 2.1490683229813663, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '800119', 'n_tokens_mistral': 1237, 'n_tokens_neox': 1172, 'n_words': 335}