Klimczak.Jan Posted September 10, 2019 Share Posted September 10, 2019 (edited) Hi, I observed in 2.9 that morph targets not works. The shape is not changing. I attach you a file to figure it out. void MorphTest::init() { mesh = ObjectMeshSkinned::cast(Editor::get()->getNodeByName("pCube2")); mesh->setNumTargets(2, 0); } void MorphTest::update() { float time = Game::get()->getTime() * 2.0f; float k0 = sin(time * 3.0f) + 0.75f; float k1 = cos(time * 3.0f) + 0.75f; mesh->setTarget(0, 1, 0, k0, 0); mesh->setTarget(1, 1, 0, k1, 0); } edit: - In Deformed Models tab I checked Deformed Models and Blend Shapes (in export options) - Also I checked Input Connections in Connections tab (in export options) - In Unigine I selected Import Morph Targets (in import options) - As well I verified such exporeted file in other 3D software/engine where morphs works - the file is correct and Morphing works (except Unigine) - I attach fbx file where is just one morph shape added to base shape (it's just change the position of vertices for one edge of the box) blend_selection_bin_ic.fbx Edited September 10, 2019 by Klimczak.Jan Additional information Link to comment
morbid Posted September 11, 2019 Share Posted September 11, 2019 Hello Jan, It worked with your code and model for me. Check the attached video. morph_target.mp4 AppWorldLogic.cpp 1 How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Klimczak.Jan Posted September 11, 2019 Author Share Posted September 11, 2019 Hello @morbid, that's strength behaviour, it's scale my object instead blending it (I have the same issue). The valid shapes are (from .fbx file): morphing should morph box to triangle based box withoud changing it's size. Link to comment
morbid Posted September 11, 2019 Share Posted September 11, 2019 Okay, I thought that shape changing you mentioned is what I saw. We'll investigate this further. 1 How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
morbid Posted September 18, 2019 Share Posted September 18, 2019 Hi Jan, We've found a mistake in your code. For correct behavior you should compensate each target with negative coefficient, like here: void MorphTest::init() { mesh = ObjectMeshSkinned::cast(Editor::get()->getNodeByName("pCube2")); mesh->setNumTargets(3, 0); } void MorphTest::update() { float time = Game::get()->getTime() * 2.0f; float k0 = sin(time * 3.0f) * 0.5f + 0.5f; mesh->setTarget(0, 1, 0, 1.0f, 0); mesh->setTarget(1, 1, 0, -k0, 0); mesh->setTarget(2, 1, 0, k0, 0); } Check our article and samples on morph targets, this approach with negative coefficient is used in every case: https://developer.unigine.com/en/docs/2.9/content/tutorials/morph/ Thanks! 1 How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Klimczak.Jan Posted September 18, 2019 Author Share Posted September 18, 2019 Hi @morbid, Do you try it with the file which I attach to the post? Unfortunatelly it not working for me even with negative coeficient. For my, only provided by unigine samples works correct (but I cant analize it becasuse they are not the fbx files). Also I have a little problem to understand how internally morphing works in unigine sdk? If I have one mesh with just one blend target then why I have to setup 3 target for it? And why I have to use negative coeficient? I think that such knowledge will help me to work with that. Thanks Link to comment
thomalex Posted September 19, 2019 Share Posted September 19, 2019 Hello @Klimczak.Jan, We are sorry about the typo we made in the snippet above, it should be as follows: void MorphTest::init() { mesh = ObjectMeshSkinned::cast(Editor::get()->getNodeByName("pCube2")); mesh->setNumTargets(3, 0); } void MorphTest::update() { float time = Game::get()->getTime() * 2.0f; float k0 = sin(time * 3.0f) * 0.5f + 0.5f; mesh->setTarget(0, 1, 0, 1.0f, 0); mesh->setTarget(1, 1, 0, -k0, 0); mesh->setTarget(2, 1, 1, k0, 0); // here the target index must be 1 } As it is told in the Adding Morph Targets article, all enabled targets are multiplied by their weights and added up according to the formula: final_xyz = target_0_xyz * weight_0 + target_1_xyz * weight_1 + ... Using a negative compensatory coefficient is just a handy workaround preventing the model from inflating (since the final position of each point is the sum of the target ones), it's pretty useful when using multiple targets. You can blend two shapes in a more natural way: void MorphTest::init() { mesh = ObjectMeshSkinned::cast(Editor::get()->getNodeByName("pCube2")); mesh->setNumTargets(2, 0); } void MorphTest::update() { float time = Game::get()->getTime() * 2.0f; float k0 = sin(time * 3.0f) * 0.5f + 0.5f; mesh->setTarget(0, 1, 0, k0, 0); mesh->setTarget(1, 1, 1, 1 - k0, 0); // we just subtract the weight of the first target from the maximum } You can set up as many morph targets as you need, but each target should be associated with one of blend shapes from the model. Check this out: void MorphTest::init() { mesh = ObjectMeshSkinned::cast(Editor::get()->getNodeByName("pCube2")); mesh->setNumTargets(mesh->getNumSurfaceTargets(0) + 1, 0); // set up as many targets as the 0 surface has plus 1 // enable each target and associate it with the corresponding blend shape mesh->setTargetEnabled(0, 1, 0); // straight box mesh->setTargetIndex(0, 0, 0); mesh->setTargetEnabled(1, 1, 0); // an auxiliary compensatory target mesh->setTargetIndex(1, 0, 0); mesh->setTargetEnabled(2, 1, 0); // skewed box mesh->setTargetIndex(2, 1, 0); } void MorphTest::update() { float time = Game::get()->getTime() * 2.0f; float k0 = sin(time * 3.0f) * 0.5f + 0.5f; mesh->setTargetWeight(0, 1.0f, 0); // and then simply adjust the weights mesh->setTargetWeight(1, -k0, 0); // using a negative weight here is the same as setting 1-k0 value mesh->setTargetWeight(1, k0, 0); } So the setTarget function just gathers all target parameters together for convenience. All the samples above were checked with your fbx in 2.9 SDK. Hope this helps! Thank you. 2 Link to comment
Klimczak.Jan Posted September 19, 2019 Author Share Posted September 19, 2019 Hello @thomalex and @morbid, Thank you for very good and detailed explaination and for solve my problem. Now everyhing work as expecten and I understand why it is working like that. I thing such additional examples you could add to documentation. It explain why to use negative coeficient, which is a good idea to use :) Thank You Link to comment
SWang133 Posted February 21 Share Posted February 21 By the way, what does the `surface` attribute actually refers to in the function `setTarget`? I found all demos setting it to zero without any necessary description so I can't quite understand what it controls. Link to comment
silent Posted February 21 Share Posted February 21 That's may be useful when mesh have multiple surfaces. By setting target explicitly to zero you tell engine which surface to modify in runtime. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
Recommended Posts