void Causality::BuildJointMirrorRelation(IArmature& armature)
{
	Joint* root = armature.root();
	ArmatureFrameConstView frame = armature.bind_frame();

	float epsilon = 1.00f;
	auto _children = root->descendants_breadth_first();
	std::vector<std::reference_wrapper<Joint>> children(_children.begin(), _children.end());
	std::vector<Joint*> &joints = reinterpret_cast<std::vector<Joint*> &>(children);

	for (int i = 0; i < children.size(); i++)
	{
		auto& bonei = frame[joints[i]->ID];
		auto& ti = bonei.GblTranslation;
		auto ji = joints[i];

		for (int j = i + 1; j < children.size(); j++)
		{
			auto& bonej = frame[joints[j]->ID];
			auto& tj = bonej.GblTranslation;

			auto jj = joints[j];
			
			auto pi = joints[i]->parent();
			auto pj = joints[j]->parent();

			if (((pi == pj && pi->MirrorJoint == nullptr) || pi->MirrorJoint == pj || pj->MirrorJoint == pi) && is_similar(ji, jj))
			{
				if (pi != pj && child_index(ji) != child_index(jj))
					continue;

				ji->MirrorJoint = jj;
				jj->MirrorJoint = ji;
			}
		}
	}

#ifdef _DEBUG
	for (int i = 0; i < children.size(); i++)
	{
		std::cout << joints[i]->Name;
		if (joints[i]->MirrorJoint)
			std::cout << " <==> " <<  joints[i]->MirrorJoint->Name;
		std::cout << std::endl;
	}
#endif
}
void StaticArmature::clone_from(const IArmature & rhs)
{
	for (auto& j : rhs.joints())
		m_order.push_back(j.ID);

	this->m_joints.resize(m_order.size());
	this->m_rootIdx = rhs.root()->ID;
	this->m_defaultFrame = rhs.bind_frame();

	// Copy Joint meta-data
	for (auto& j : rhs.joints())
		m_joints[j.ID] = j;

	// rebuild structure
	for (int i : this->m_order)
	{
		if (m_joints[i].ParentID >= 0 && m_joints[i].ParentID != i)
		{
			m_joints[m_joints[i].ParentID].append_children_back(&m_joints[i]);
		}
	}
}
ArmatureFrame::ArmatureFrame(const IArmature & armature)
{
	assert(this->size() == armature.size());
	auto df = armature.bind_frame();
	BaseType::assign(df.begin(), df.end());
}