Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This example operator adds an offset to a joint transform.

Code Block
languagecpp

#include <AtomsGraph/Ports.h>
#include <Atoms/Globals.h>
#include <Atoms/Graph/Operator.h>

class JointOffsetOperator : public Atoms::Operator
{
public:

	NODE_STANDARD_MEMBERS

	JointOffsetOperator();

	virtual ~JointOffsetOperator();

	bool	compute(const AtomsGraph::ComputeData* computeData);

	void reset();

private:

	AtomsGraph::PosePort* m_inPose;
	AtomsGraph::StringPort *m_jointName;
	AtomsGraph::MatrixPort *m_offsetMatrix;
	AtomsGraph::BooleanPort *m_worldSpace;
		
	int m_jointId;
	bool m_first;
};

// this must be unique
#define JOINT_OFFSET_OPERATOR_ID 9999991 

NODE_STANDARD_MEMBERS_IMPL(JointOffsetOperator)
unsigned int JointOffsetOperator::staticTypeId() { return JOINT_OFFSET_OPERATOR_ID; }
std::string JointOffsetOperator::staticTypeStr() { return std::string("JointOffsetOperator"); }

JointOffsetOperator::JointOffsetOperator() : Operator()
{
	m_jointName= new AtomsGraph::StringPort("jointName");
	m_jointName->set("");
	addInputPort(m_jointName);

	m_offsetMatrix = new AtomsGraph::MatrixPort("offsetMatrix");
	addInputPort(m_offsetMatrix);

	m_inPose = new AtomsGraph::PosePort("inPose");
	addInputPort(m_inPose);

	m_worldSpace = new AtomsGraph::BooleanPort("worldSpace");
	m_worldSpace->set(false);
	addInputPort(m_worldSpace );

	m_jointId= -1;
	m_first = true;
}

JointConstraintOperator::~JointConstraintOperator()
{
}

bool JointConstraintOperator::compute(const AtomsGraph::ComputeData* computeData)
{
	AtomsCore::Pose &inPose = m_inPose->getRef();
	if (inPose.numJoints() == 0)
	{
		AtomsUtils::Logger::warning() << "Empty input pose";
		return false;
	}


	AtomsCore::Pose &outPose = m_outPose->getRef();
	// Copy the input pose to the out pose port
	outPose = inPose;

	// Check if the agent and the agent type are valid
	if (!m_agent) 
	{
		AtomsUtils::Logger::error() << "Invalid agent type";
		return false;
	}

	if(!m_agent->agentType())
	{
		AtomsUtils::Logger::error() << "Invalid agent type";
		return false;
	}

	// Get the skeleton from the agent type
	const AtomsCore::Skeleton& skeleton = m_agent->agentType()->skeleton();
	
	if (m_first)
	{
		m_jointId = skeleton.jointId(m_targetJoint->getRef());
	}

	if (m_jointId == -1)
	{
		Logger::error() << "Could not find " << m_targetJoint->getRef() << "joint.";
		return false;
	}


	if (worldSpace->get())
	{
		// Compute the offset in world space
		AtomsCore::Poser poser(&skeleton);
		AtomsCore::Matrix currentMtx = poser.getWorldMatrix(pose, jointId);
		poser.setWorldMatrix(pose, m_offsetMatrix->getRef()* currentMtx, jointIdTmp);
	}
	else
	{
		// Compute the offset in local space		
		AtomsCore::JointPose& jp = outPose.jointPose(m_jointId);
		jp.setMatrix(m_offsetMatrix->getRef() * jp.matrix());
	}
	return true;
}

void JointConstraintOperator::reset()
{
	Operator::reset();
	m_jointName->set("");
	m_worldSpace->set(false);
	m_jointId= -1;
	m_first = true;
}


The operator can be added by this custom behaviour module.

...