Notifications
Clear all

[Closed] [SDK] Get the MorphControl from Morp modifier

I’m working on implementing morph support for a exporter, currently I check for all the modifiers, and I do ‘get’ the modifier that I need to work with.

The issue we cannot find a solution for is how I can get the morph control from the modifier.
I need to get that to be able to get the different parameters and such from the modifer\controller.

My code is something like this:


MorphControl *morphc;
Modifier *mMod;

for (int i=0;i<pDerObj->NumModifiers();i++)
{
	mMod = pDerObj->GetModifier(i);
	if (! mMod) continue;
	if (mMod->ClassID() == MORPHMOD_CLASSID)
	{
		MorphControl *mctrl = NULL;
		mctrl = (MorphControl*)mMod; 
		if (mctrl != NULL)
		{
			int nummorphTargets= 0;
			nummorphTargets = mctrl->NumMorphTargs();
			if (nummorphTargets != NULL)
			{
				LogManager::getSingleton().logMessage(::LML_CRITICAL, std::string("We found morph targets."));
			}else
			{
				LogManager::getSingleton().logMessage(::LML_CRITICAL, std::string("could not find number of morph targets."));
			}
		}
		
	}
}

the

 mctrl->NumMorphTargs();

crashes everything, most likely because it’s not initialized correctly, this is what we’re struggling with.

8 Replies

look at IGameMorpher Class Reference

I’m not surprised it crashes casting a Modifier* to a Control* is pretty bad form :D. You should get in the habit of using the c++ casting operators instead of the c style one as it does a better job of catching those kind of errors.

though still wrong it should return NULL as required

mctrl = dynamic_cast<MorphControl*>(mMod);

instead of…

mctrl = (MorphControl*)mMod; 

for the correct method for accessing the morpherAPI there an example project in

...\maxsdk\samples\modifiers\morpher\MorpherView

should show the correct method…

you’ll have to build the morpher project so you can add morpher.lib to your plugins dependencies and #include “wm3.h” somewhere so you’ll probably add the morpher folder to your Additional Include Directories list.

Thanks to both of you for the useful information.
I’ll check on both solutions when I get back to the office tomorrow morning.

I solved it with the Igame Wrapper.
It was easy to use it in the existing code since I just had to send in the Inode, I did not have to change anything of my existing code.

The basic implementation was as easy as:

	Modifier *mMod;
	IGameNode *myIgameNode;
	IGameScene *scn;
	IGameMorpher *myIgameMorpher;
	
	wchar_t propFile[1024] = L"IGameProp.xml";

	scn = GetIGameInterface();
	scn->SetPropertyFile(propFile);
	
	if (scn->InitialiseIGame(false))
	{
		LogManager::getSingleton().logMessage(LML_CRITICAL, std::string("Initialized Igame scene."));
	}else
	{
		LogManager::getSingleton().logMessage(LML_CRITICAL, std::string("Failed to initialize Igame scene."));
	}
	
	myIgameNode = scn->GetIGameNode(node);

	if (myIgameNode != NULL)
	{
		LogManager::getSingleton().logMessage(LML_CRITICAL, std::string("We found the Igame Node."));
	}

	for (int i=0;i<myIgameNode->GetIGameObject()->GetNumModifiers();i++)
	{
		mMod = pDerObj->GetModifier(i);
		if (! mMod) continue;
		if (mMod->ClassID() == MORPHMOD_CLASSID)
		{
			LogManager::getSingleton().logMessage(LML_CRITICAL, std::string("We found Morph Modifier."));
			IGameModifier *pIGameModifier = myIgameNode->GetIGameObject()->GetIGameModifier(i);
			
			if (pIGameModifier->IsMorpher())
			{
				LogManager::getSingleton().logMessage(LML_CRITICAL, std::string("Initialized the Igame Morph code."));
				IGameMorpher *mymorph = static_cast<IGameMorpher*>(pIGameModifier);
				LogManager::getSingleton().logMessage(LML_CRITICAL, std::string("Number of morph targets: " + StringConverter::toString(mymorph->GetNumberOfMorphTargets())));
			}
		}
	}
	scn->ReleaseIGame();

i’m probably missing something… but i thought all that you need is to use

IGameMorpher (Modifier* mod, INode* node) 

you should really use the dynamic_cast on the IGameModifier* as IGameMorpher is derived from it.

I’m not sure about the latest comments, but it does work for me as-is, so I’ll just stick to it for now