Notifications
Clear all

[Closed] Set vertex keyframes with C++ SDK

Hi stigatle,

Attached is an example project showing how to do vertex animation from the SDK.

I figured out that after creating and adding subcontrollers to the Master Point Controller, those controllers then need to be added as subanimatables of the Master Point Controller Animatable. This is done with the IAnimatable::AssignController() method. Once this is done the controllers show up correctly in the track view, along with any keys that were created via the IKeyControl interface.

Sj

(Its for C# but the managed wrapper is very thin so all calls and types translate direct to C++)

deleted … wrong place for this post

sebjf , thank you very much for sharing that, I’ll sit down tonight and port it over to c++, once I have it working I’ll share the c++ code back in here, so that others can have a look at both.

Thats great Stigatle!

FYI the keyframe values in that example don’t have sensible values, so they deform the box in an odd way (it was late…). Just thought I’d say, as the comment in the code could suggest that it keeps a box shape, and I don’t want you wasting time thinking that the values are being corrupted, or behavior is changing in the port.

Thanks for the info.

What I need this for is to bake the softbody simulation in my plugin as you can see here:
http://bullet4max.com/?cat=2

I simulate a frame, get the simulated vertex positions from bullet, then apply them back on the 3dsmax object and so on.

So in that loop I’ll apply the vertex positions as keyframe as well, which then enables you to ‘scroll’ the softbody simulation in the timeline.

Looking forward to getting that done so that I can publish a new release of the plugin.

Bullet in Max, that is excellent! I look forward to seeing it when its done.

Sj

My code is basically this:
But i’m not able to ‘catch’ the

MASTERPOINTCONT_CLASS_ID

So I guess I’m iterating a bit wrong maybe?

The object I run this on has a modifier in it’s stack, and the masterpoint controller is on the ‘base’ object.


Object*	obj;
ObjectState os = currNode->EvalWorldState(GetCOREInterface()->GetTime());
obj = os.obj;

switch (os.obj->SuperClassID())
{
case GEOMOBJECT_CLASS_ID:
	TriObject *p_triobj = NULL;

	BOOL fConvertedToTriObject = obj->CanConvertToType(triObjectClassID) && (p_triobj = (TriObject*)obj->ConvertToType(0, triObjectClassID)) != NULL;
	if (!fConvertedToTriObject)
	{
		mprintf(L"Error: Could not triangulate object : %s
", currNode->GetName());
		return false;
	}
	Mesh *p_trimesh = &p_triobj->mesh;
	int faceCount = p_trimesh->getNumFaces();

	MasterPointControl *mControl = NULL;
   
	for (int s = 0; s < obj->NumSubs(); ++s)
	{
		Animatable *anim = obj->SubAnim(s);
		MSTR tmp = L"";
		anim->GetClassName(tmp);
	   
		mprintf(L"DEBUG: checking subanim : %s
", tmp);
		if (anim->SuperClassID() == MASTERPOINTCONT_CLASS_ID)	   
		{
			mControl->GetSubController(s);
			mControl->SetNumSubControllers(p_trimesh->getNumVerts(),false);
		}
	}
}

I then tried like this:

Object* objBeforeModifiers;
ObjectState osBeforeModifiers = currNode->GetObjectRef();
objBeforeModifiers = osBeforeModifiers.obj;

then I sent that obj in to the same code as above
it then finds other nodes (names of modifiers etc) in the track view.

I’m close, but no cigar yet

Hi Stigatle,

I’m no expert but I don’t see anything wrong (other than mControl is never assigned).

Maybe the default MasterPointControl is never being added? You could try getSubAnim/getSubAnimNames to explore the animatable hierarchy with MaxScript to make sure its present.

Also have a look in the SDK samples – a number use ReplaceReference() to replace (add?) the MasterPointController. Look for the references to *NewDefaultMasterPointController() in control.h. (C++ I’m talking about now)

Thanks sebjf, I have some time to sit with it again tonight, I’ll look at the things you mention.

I found a simple way of writing the pointcache files directly from maxscript.
I’ll use that and trigger it from c++ where I need it, that will work fine for what I need.

Code:

	fn writeptsfile obj startFrame endFrame =
	(
		f=fopen "c:\	mp\\vertexAnim.pts" "wb"
		 if (f != undefined) then
		  (
			-- version (number of points)
			WriteLong f (obj.verts.count)
			
			-- cache samples
			WriteLong f 1
			
			-- cache number of frames
			WriteLong f (endFrame - startFrame)
			count = obj.verts.count
			for i = startFrame to endFrame do
			at time i
			(
				for j = 1 to count do
				(
					WriteFloat f obj.verts[j].pos.x
					WriteFloat f obj.verts[j].pos.y
					WriteFloat f obj.verts[j].pos.z
				)
			)
			  fclose f
		)
	)

then to export selected object as pointcache file do this:

writeptsfile $ 0 100

and then simply load up the file in the pointcache modifier.

What I’ll do later is to just do the same straight from c++, but for now it does what I need.

Page 2 / 3