# directly dealing with TransformState through matrices

Hi,

As part of a robotic project, I’m trying to directly deal with 4x4 matrices (homogeneous coordinate ®+ Translation (T) in 3D World).

In order to re-orient a nodePath NP (transform based on R and T matrices coming from openCV) , this is the tentative code:

...
ConstPointerTo<TransformState> Xform_state = NP.get_net_transform();
LMatrix4f panda_Xform = Xform_state->get_mat();
panda_Xform.set_row(0, LVecBase4f(R.at<float>(0,0), R.at<float>(0,1), R.at<float>(0,2), 0.0f ) );
panda_Xform.set_row(1, LVecBase4f(R.at<float>(1,0), R.at<float>(1,1), R.at<float>(1,2), 0.0f ) );
panda_Xform.set_row(2, LVecBase4f(R.at<float>(2,0), R.at<float>(2,1), R.at<float>(2,2), 0.0f ) );
panda_Xform.set_row(3, LVecBase4f(T.at<float>(0) ,   T.at<float>(1) ,   T.at<float>(2),    1.0f ) );
NP.set_net_transform(Xform_state); // ???????????????????????

My questions:

(1) Apparently there doesn’t seem to be the dual function to ‘nodePath.get_net_transform()’, ie how to get something that would perform as ‘nodePath.set_net_transform’?

(2) same question with ‘nodePath.get_transform()’ !

jean-claude

What about changing the transform state this way? what is still missing?

ConstPointerTo<TransformState> Xform_state = NP.get_net_transform();
LMatrix4f panda_Xform = Xform_state->get_mat();
panda_Xform.set_row(0, LVecBase4f(R.at<float>(0,0), R.at<float>(0,1), R.at<float>(0,2), 0.0f ) );
panda_Xform.set_row(1, LVecBase4f(R.at<float>(1,0), R.at<float>(1,1), R.at<float>(1,2), 0.0f ) );
panda_Xform.set_row(2, LVecBase4f(R.at<float>(2,0), R.at<float>(2,1), R.at<float>(2,2), 0.0f ) );
panda_Xform.set_row(3, LVecBase4f(T.at<float>(0) ,   T.at<float>(1) ,   T.at<float>(2),    1.0f ) );

NP.set_transform(TransformState::make_mat(panda_Xform));   //  ???

ok, just tried to make it simple, that’s where I’m at:

Assume two nodes A and B.
I want to keep the relative positioning of B wrt A, but apply to B a rotation wrt A defined by a 3x3 matrix R (an opencv Mat)

ConstPointerTo<TransformState> Xform_state = B.get_transform(A);
LMatrix4f panda_Xform = Xform_state->get_mat();
panda_Xform.set_row(0, LVecBase4f(R.at<float>(0,0), R.at<float>(0,1), R.at<float>(0,2), 0.0f ) );
panda_Xform.set_row(1, LVecBase4f(R.at<float>(1,0), R.at<float>(1,1), R.at<float>(1,2), 0.0f ) );
panda_Xform.set_row(2, LVecBase4f(R.at<float>(2,0), R.at<float>(2,1), R.at<float>(2,2), 0.0f ) );
B.set_transform(A,TransformState::make_mat(panda_Xform));

As far as I know there is no dedicated function for setting the net transform.
But you can use set_transform:

nodePath.set_transform(NodePath(), Xform_state);'

Hi Enn0x,
Thanks for your input, you’re right set_transform seems to fit the bill!
Actually I made some more test on the matter, one of the difficulty was to deal with
two unattached nodes, so let me summarize just in case it can be helpful to the community:

Starting point: 3 nodes A, B and C with B parented to C
Intent: get node B rotated wrt to node A using a 3x3 rotation matrix (coming from an external openCV input)

Lpoint3f save_pos_wrt_C = B.get_pos();		// save B position wrt to C
B.wrt_reparent_to(A);					// reparent B to A
// now rotate B wrt A
LMatrix4f panda_Xform;  // will be used to Rotate B wrt A
panda_Xform.set_row(0, LVecBase4f(Rx0,  Rx1,   Rx2,  0.0f ) );
panda_Xform.set_row(1, LVecBase4f(Ry0,  Ry1,   Ry2,  0.0f ) );
panda_Xform.set_row(2, LVecBase4f(Rz0,  Rz1,   Rz2,  0.0f ) );
panda_Xform.set_row(3, LVecBase4f(0.0f, 0.0f,  0.0f,  1.0f ) );
B.set_transform(A,TransformState::make_mat(panda_Xform));
// reattach to C
B.wrt_reparent_to(C);
B.set_pos(save_pos_wrt_C);