C++ performance surprise

C++ performance surprise

Anonymous
Not applicable
1,008 Views
5 Replies
Message 1 of 6

C++ performance surprise

Anonymous
Not applicable

Hi again, I was trying to overcome some performance issues I have with a tool I'm developing. The main tool is in python and I thought that c++ would be the right choice at least for the most costly process. Iterate for the selected nodes in a given time range. So I did and expose the function to maxscript. To my dismay I didn't aprecciate significance performance improvement. Some how the  action of setting an transformation matrix in a given times keep being extremely slow whe you have to do it in a nested loop iteration. I don't know if anyone can share another aproach or method that could be faster.

This is an snippet to test performance just assigning and identity matrix to every node. 

 

void NoMagic::do_something()
{
	int n = GetCOREInterface()->GetSelNodeCount();
	Matrix3 f(1);

	for (int frame = 0; frame < 100; frame++)
	{
		TimeValue t = frame * 160;
		for (int i = 0; i < n; i++)
		{
			INode *node = GetCOREInterface()->GetSelNode(i);

			node->SetNodeTM(t, f);
		}
	}
0 Likes
1,009 Views
5 Replies
Replies (5)
Message 2 of 6

istan
Advisor
Advisor

a) how many nodes you are changing?

b) is the screen updating at each SetNodeTM() ?

c) what if you exchange the two loops? make e.g. "i" the outer loop.

d) you also could directly access the node controllers instead of using SetNodeTM()

 

remark: I use SetNodeTM() for realtime updates (but w/o animations).

0 Likes
Message 3 of 6

Anonymous
Not applicable

a) how many nodes you are changing?

In the tests I'm running are 30 nodes. The tool is intended to interate all way down the hierarchy, in this case, of a biped, applying the transform matrixes extracted of an fbx file. This number could be up to 50 or more in a regular char with five fingers and all. The main isue is with the animation range, this could be much more than the 100 frames I'm testing in this example.

b) is the screen updating at each SetNodeTM() ?

Apparently not, but to be sure I add in maxscript disableSceneRedraw() but I didn't see any improvement. I did notice a significant inmproment, from 16 second to 9 seconds if I execute this function with the create tab instead of the motion tab.

c) what if you exchange the two loops? make e.g. "i" the outer loop.

I did previouly in python but it was slightly slower. I could give a try in C++ and see what happens.

d) you also could directly access the node controllers instead of using SetNodeTM()

The reason because I'm using that method is because the node controller could be different depending of the rig is getting the animation info. The transform matrix I understand is kind of brute force but is quite "universal" and besides the performance issue it was behaving quite well.

0 Likes
Message 4 of 6

istan
Advisor
Advisor

Due to the known limitations of a Matrix3 orientation I do not use SetNodeTM() for animations - I always modify and access the controllers directly..

0 Likes
Message 5 of 6

Anonymous
Not applicable

Thank you for your answer again. I found something in interface9 of the biped it could be usefull to make things faster, but I haven't had the time yet to try it. I'll post here if I get positive results.

0 Likes
Message 6 of 6

Anonymous
Not applicable

Finally I found some time to spend in this issue.

My new attemp to try to increase speed in the task of transform all nodes in a biped for a good amount of frames my new approach was this. In BipedInterface9 you can find this methods that hopefully will let you get a better performance

	//! \brief Function for specifying that we will be setting a group of biped keys.
	
	//! Calling this function means that biped will soon get a large number of keys set on different biped body parts, usually via a
	//! SetNodeTM function call.  Internally, this will allow biped to correctly set the keys based upon biped peculiarities, for example
	//! we need to set the biped up all at once per each frame that has a key (per pose), and we need to handle shared keys caused by 
	//! unseperated tracks.
	virtual void StartSettingBipedKeys() = 0;


	//! \brief Function for specifying that we will are done setting a group of biped keys.

	//! Calling this function means that the biped is done setting keys on it, and we can now go ahead and key the biped
	//! based upon all of the values that were set after the previous StartSettingBipedKeys call.  Note that if no StartSettingBipedKeys
	//! function was called, then nothing happens.
	virtual void StopSettingBipedKeys() = 0;

	//! \brief Function for setting world transforms on a biped.
	
	//! This function will set the world transform on a biped, similarly to INode::GetNodeTM.  This function however will cache values based
	//! upon biped body part, when called within StartSettingBipedSetKeys/StopSettingBipedKeys().  This allows us to correctly and optimally
	//! set up a bipeds animation pose per pose.
	//! \param[in] t The time at which to set the pose.
	//! \param[in] mat The world transform.
	//! \param[in] id The internal 'id' of the biped node.  You get this by calling IBipMaster::GetIdLink.
	//! \param[in] link The internal 'link' of the biped node.  You get this by calling IBipMaster::GetIdLink.
	virtual void SetBipedTM(TimeValue t,Matrix3 &mat,int id, int link) = 0;

I tried to implement those functions in a gup plugin and expose to maxscript throught function publishing. For some reason it just doesn't seems to work.

All my searches in the internet about using this methods got me nothing. Maybe someone have some experience using this methods in this forum an can help me to get it to work.

Thank in advance.

0 Likes