Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

advice on per-vertext animation #225

Closed
gwald opened this issue Jan 23, 2024 · 10 comments
Closed

advice on per-vertext animation #225

gwald opened this issue Jan 23, 2024 · 10 comments

Comments

@gwald
Copy link
Contributor

gwald commented Jan 23, 2024

Hello again

I want to do per vertex animation, but my models (.obj's) are individual models, same model data but the verts are in different positions... anyway, I don't know how to package these into collada format to get morph targets.

Would anyone have any tips on how to do this or what to words to search? I cant seem to find anything that can do it.

Or alternatively, can H3D load my individual model data and interpolate from one to another? I had a look at the API and forum, I couldn't find anything that suggest it can.

Thanks in advance.

@algts
Copy link
Collaborator

algts commented Jan 24, 2024

Hello.
I'll start with the second question. Horde is designed to use animation files, otherwise you would have to animate the models yourself. You can get the vertex positions of each model, animate them manually, then reupload new positions. Here is the example on how you can get vertex positions: https://github.com/algts/Horde3DPhysics/blob/master/src/Horde3DPhysics/egPhysics.cpp

Now, the first question. AFAIK morph targets will work until you have the same number of vertices. Therefore, if you have different models (like begin and end state of the animation, if I understood you correctly) you'll probably have to import both models into your DCC tool (Blender, 3d Max, Maya, etc.), make the two models on the polar ends of the animation track (for example, model 1 is on 0 keyframe, model 2 is on 100 keyframe) and create a transition effect. Basically, you would have to recreate the morph animation and then you would export the animation to Collada. You should consult the manual of your DCC tool on how to create transition/morph animation.

@gwald
Copy link
Contributor Author

gwald commented Jan 25, 2024

Thank you very much for the reply! It helped me out a lot!

My DCC is MarbleClay (http://escargot.la.coocan.jp/MCLFrm.html) a very simple 3D app, it doesn't have animation support, I just export individual poses :)

I looked at the code and saw h3dMapResStream & h3dUnmapResStream, I found someone asking the same question on the forum and this worked great:
http://horde3d.org/forums/viewtopic.php?p=5337&sid=9d997d42445994769ab88f36edb90416#p5337

Thank you 👍

@gwald gwald closed this as completed Jan 25, 2024
@gwald
Copy link
Contributor Author

gwald commented Jan 28, 2024

Some info regarding the DCC approach.

http://horde3d.org/forums/viewtopic.php?f=11&t=2330

I recently found a face animation software package, it mentioned the "Motion designer files .mdd" format, which I've never heard of before, but it's a way of packing and process morphing animation, it's a very simple format:

http://rodolphe-vaillant.fr/entry/134/mdd-file-exporter-importer-source-code-c-c

And probably widely supported, like blender:
https://blender.stackexchange.com/questions/45921/how-to-import-mdd-files

They might not even require the .mdd format, and might work with just individual files.

@gwald
Copy link
Contributor Author

gwald commented Jan 30, 2024

Sorry for reopening this, but I'm not sure how to proceed without doing a lot more trial and error and would like advice.
I can morph verts on a node with a resource.

I have a static pose frame saved as .dae and converted and I want to tween out to another static pose, repeat for a few frames. But I'm not sure how to best structure this for multiple 'resources', to get an animation.

I started creating individual resources, but it felt wrong and wondered if I could use clone and found an example of cloning materials inside a resource:
https://horde3d.org/forums/viewtopic.php?p=10364#p10364

Is this the correct the approach, cloning the mesh?
I have 4 keyframes and I want a one tween frame in between , I know how to interpolate them.

I would normally just do it, but this is pretty big for 'trial and error', and could do with advice.

I was thinking:
Load all the keyframes as normal resources
Create the animation resource using the first frame, create 7 clones of the mesh.
Then I "h3dMapResStream & h3dUnmapResStream" the mesh in the 7 clone meshes.

But I cant seem to set the new mesh:
h3dSetNodeParamI(scene_anim_ID, H3D_ResTypes_Geometry, keyframes_cloneID );
I've step through the engine, and it doesn't like my scene_anim_ID ("Models/t1.scene.xml"), even though it's fine (non zero).

Help please :/

@gwald gwald reopened this Jan 30, 2024
@algts
Copy link
Collaborator

algts commented Jan 30, 2024

Are you sure you want to go that way? To me it looks like you're reimplementing the whole engine animation system in your game.
AFAIK, currently Horde does not support generating animation files on the fly, you should look into converter code (search for function that generates animation file in converter.cpp).
If you are not using animation resources, but are changing geometry resources in models, you should probably:

  • load geometry resource once
  • clone it the required number of times (store ids of all geometry resources)
  • set new data for each geometry resource
  • change the geometry resource in the required model when needed. Make sure that you are changing geometry in the model node.

Make sure that you are setting geometry file and then call h3dUpdateModel with update geometry flag. Next update would not work unless you change geometry resource again.

Horde checks the following when updating geometry in model:

if( !_skinningDirty && !_morpherDirty ) return false;

	if( _baseGeoRes == 0x0 || _baseGeoRes->getVertPosData() == 0x0 ||
	    _baseGeoRes->getVertTanData() == 0x0 || _baseGeoRes->getVertStaticData() == 0x0 ) return false;
	if( _geometryRes == 0x0 || _geometryRes->getVertPosData() == 0x0 ||
		_geometryRes->getVertTanData() == 0x0 || _geometryRes->getVertStaticData() == 0x0 ) return false;

SkinningDirty is set when you set new geometry resource. If you do not set any morphers or software skinning parameter is not set (you should set it if you are not using animation files), baseGeoRes would be zero and therefore the checks would fail.

@algts
Copy link
Collaborator

algts commented Feb 5, 2024

@gwald Hello. Did it help you or you've encountered some issues?

@gwald
Copy link
Contributor Author

gwald commented Feb 6, 2024

Hi,
Yes, it was very helpful thank you! Thanks for asking :)

I figured the best way forward with least resistance is to modify the converter to create the anim file of the static dae files as morph targets, I started looking into this and I can roughly figure out where to make it read the dae files and change the XML objects to make it think it's one dae with morph targets.

So, I left that and now I'm trying to figure out how to load a morph animation using this one:
KhronosGroup/COLLADA2GLTF#166 (comment)

And I'm stuck getting it to morph (#226)

Or it could be an issue that I'm using groupnodes to keep track of my scene and deleting all the nodes at the start of each new frame? (I dont want child nodes automatically rendering,#224 (comment)).

@algts
Copy link
Collaborator

algts commented Feb 12, 2024

@gwald Is this issue still valid? Or should we close it?

@gwald
Copy link
Contributor Author

gwald commented Feb 12, 2024

I'm still looking into this, and I'll post my solution here and/or close this.
I'm testing the dev branch now, thanks again for your help with morphing! :)

@gwald
Copy link
Contributor Author

gwald commented Feb 16, 2024

I made a program that takes all the collada text files in a folder and mergers them into a single one as morph frames in alphabetical order... it doesn't keep the names (maybe that would have been better), it uses the first name and adds numbers.
It works with my simple collada files created with assimp.

The hacky source code and a win32 executable is included... If I change it regularly, I might maintain it on my github
src.zip

Thank you @algts for your patience and guidance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants