eugene.litvinov Posted December 13, 2010 Share Posted December 13, 2010 Hello, I use ObjectMeshSkinned object, that is always watch on player. Part of code of that I use from one of unigine examples: ObjectMeshSkinned meshSkinned; void update() { float time = engine.game.getTime(); int indexBoneHip = meshSkinned.findBone("hip"); int indexBoneChest = meshSkinned.findBone("chest"); int indexBoneHead = meshSkinned.findBone("head"); vec3 nodePosition = node.getWorldPosition(); vec3 targetPosition = target.getWorldPosition(); float x = nodePosition.x - targetPosition.x; float y = nodePosition.y - targetPosition.y; float angle = atan2(y, x) * RAD2DEG; mat4 boneChestTransform = meshSkinned.getFrameBoneTransform(indexBoneChest); vec3 boneChestPivot = boneChestTransform.m03m13m23; boneChestTransform = translate(boneChestPivot) * rotateX(angle); meshSkinned.setFrameBoneTransform( indexBoneChest, boneChestTransform ); } This is work good, but if I add an idle animation: meshSkinned.setAnimation("source/animation/robot_idle.smesh"); meshSkinned.setLoop(true); meshSkinned.play(); My object play only this animation. How may I blend an animation with script bone transformation? Thanks. Link to comment
ulf.schroeter Posted December 13, 2010 Share Posted December 13, 2010 Based on documentation for ObjectMeshSkinned I would guess that you have to use 2 animation layers, one for the idle animation and one for your procedural bone animation. Most probably you also have to use setBoneTransform() instead of setFrameBoneTransform() as documenation states void setFrameBoneTransform(int bone,mat4 transform) Description Sets a transformation matrix for a given bone. The difference from setBoneTransform() is that this method takes into account only the transformation in the current animation layer (no blending is done). Link to comment
eugene.litvinov Posted December 14, 2010 Author Share Posted December 14, 2010 I see. I load animation to layer 0 and add layer 1: meshSkinned.setLayer(0); meshSkinned.setWeight(0.5); meshSkinned.setAnimation("source/animation/robot_idle.smesh"); meshSkinned.setLoop(true); meshSkinned.play(); meshSkinned.addLayer(); meshSkinned.setLayer(1); meshSkinned.setWeight(0.5); In fact animation don't play and nothing change. If I add line meshSkinned.setLayer(0); then idle animation is playing. But my script works only if I comment line meshSkinned.play(); Link to comment
binstream Posted December 14, 2010 Share Posted December 14, 2010 Could you please attach the full script? Link to comment
eugene.litvinov Posted December 14, 2010 Author Share Posted December 14, 2010 #ifndef REVOLVABLE_H_ #define REVOLVABLE_H_ namespace Source { class Revolvable { private: Node node; Node target; float rotation = 0; //vec3 targetPosition; public: ObjectMeshSkinned meshSkinned; int active = 0; Revolvable(Node node) { this.node = node; meshSkinned = class_cast(node.getTypeName(), node); meshSkinned.setLayer(0); meshSkinned.setWeight(0.5); meshSkinned.setAnimation("source/animation/robot_idle.smesh"); meshSkinned.setLoop(true); //meshSkinned.play(); meshSkinned.addLayer(); meshSkinned.setLayer(1); meshSkinned.setWeight(0.5); //meshSkinned.setLayer(0); } void update() { // active and target I set outer from this class if (active == 1 && target != NULL) { float time = engine.game.getTime(); int indexBoneHip = meshSkinned.findBone("hip"); int indexBoneChest = meshSkinned.findBone("chest"); int indexBoneHead = meshSkinned.findBone("head"); vec3 nodePosition = node.getWorldPosition(); vec3 targetPosition = target.getWorldPosition(); float x = nodePosition.x - targetPosition.x; float y = nodePosition.y - targetPosition.y; float angle = atan2(y, x) * RAD2DEG; //mat4 transform = mesh.getWorldBoneTransform(indexBone) * rotateY(90.0); mat4 boneChestTransform = meshSkinned.getBoneTransform(indexBoneChest); vec3 boneChestPivot = boneChestTransform.m03m13m23; boneChestTransform = translate(boneChestPivot) * rotateX(angle); meshSkinned.setBoneTransform( indexBoneChest, boneChestTransform ); } } }; }; #endif In main class I do next: Node nodeWoman = engine.editor.getNodeByName("robot"); robot = new Revolvable(nodeWoman); In this way script transform is apply, if I uncomment play() then nothing doing. If I call setLayer(0) when idle animation is play, but script transformation not apply. Link to comment
eugene.litvinov Posted December 15, 2010 Author Share Posted December 15, 2010 I attach full source. source.zip Link to comment
eugene.litvinov Posted December 16, 2010 Author Share Posted December 16, 2010 In manual ObjectMeshSkinned Class include next: What a methods includes to this groups? Thanks. Link to comment
manguste Posted December 17, 2010 Share Posted December 17, 2010 Oops, my bad. 2. Methods that set a flag indicating that the update of animation data is required. These methods should be called before the methods from the 3rd group. addLayer() removeLayer() setNumLayers() setBuffer() in case bone transformations are applied to one specific layer setFrame() setFrameBoneTransform() 3. Methods that call for update. Animation data will be recalculated during the update only if the corresponding flag was previously set by a function from the 2nd group. getBuffer() in case bone transformations are grabbed from one specific layer setBoneTransform() setBoneChildsTransform() getBoneTransform() Link to comment
eugene.litvinov Posted February 8, 2011 Author Share Posted February 8, 2011 In manual addlayer() description is: ObjectMeshSkinned::addLayervoid addLayer() Description Adds an animation layer. But in animation_tree.h is: AnimationTree(ObjectMeshSkinned mesh_) { mesh = mesh_; layer = mesh.addLayer; mesh.setLayer(0); mesh.setWeight(0.0f); parameters = new ParameterManager(); } So addLayer() return an index of newest layer? Link to comment
manguste Posted February 8, 2011 Share Posted February 8, 2011 So addLayer() return an index of newest layer? yes, it does. will be fixed. Link to comment
frustum Posted February 12, 2011 Share Posted February 12, 2011 In case of complex animation schemes (layers or buffers) you shouldn't use play() function. play() function calls setFrame() every frame for active layer. Link to comment
eugene.litvinov Posted February 12, 2011 Author Share Posted February 12, 2011 For active layer? So I must use, for example void update() { meshSkinned.setFrame(time, 0, 20); } and it blend all layers, or I need use something like next: void update() { meshSkinned.setLayer(0); meshSkinned.setFrame(time, 0, 20); meshSkinned.setLayer(1); int indexBoneChest = meshSkinned.findBone("chest"); mat4 boneChestTransform = meshSkinned.getBoneTransform(indexBoneChest); vec3 boneChestPosition = Math::decomposePositionXYZ(boneChestTransform); vec3 boneChestRotation = Unigine::decomposeRotationYZX(boneChestTransform); boneChestRotation.x += 0.5; boneChestTransform = translate(boneChestPosition) * Unigine::composeRotationYZX(boneChestRotation); meshSkinned.setBoneChildsTransform( indexBoneChest, boneChestTransform ); meshSkinned.setFrame(time, 0, 20); } This code have no effect... If I use only layer with animation (meshSkinned.setAnimation("source/animation/robot_idle.sanim"):) and use meshSkinned.setFrame(time, 0, 20); in update function this is work (instead of play()), but with bone transform this is not work. Link to comment
frustum Posted February 12, 2011 Share Posted February 12, 2011 I think setFrame() function rewrites bone transformation from previous setBoneChildsTransform(): meshSkinned.setBoneChildsTransform( indexBoneChest, boneChestTransform ); meshSkinned.setFrame(time, 0, 20); MeshSkinned has single final array of bone transformation. Each layer has own bone transformation array and weight of whole layer. Final bone transformation array is updated on several functions like: * getBuffer() * setBoneTransform() * setBoneChildsTransform() * getBoneTransform() This behaviour is described in this documentation section: code/scripting/library/objects/class.objectmeshskinned If you should only change transformation of single bone you shouldn't use layers: void update() { mesh.setFrame(time); mat4 transform = mesh.getBoneTransform(bone); // update transformation mesh.setBoneChildsTransform(bone,transform); } Link to comment
scahp Posted October 10, 2011 Share Posted October 10, 2011 I was blended two or more animation. i want to help to your problem solved. this is my animation blending sample script. --- script ------------------------------------------------------------------------------------------------- ObjectMeshSkinned meshSkinned; meshSkinned.setLayer(0); // set layer meshSkinned.setAnimation("animation0.sanim"); meshSkinned.setFrame(1); // set animation0 frame meshSkinned.getBuffer(bufferindex0, 0); // capture current layer animation to bufferindex0 meshSkinned.setAnimation("animation1.sanim"); meshSkinned.setFrame(1); // set animation1 frame meshSkinned.getBuffer(bufferindex1, 0); // capture current layer animation to bufferindex1 meshSkinned.setAnimation("animation2.sanim"); meshSkinned.setFrame(1); // set animation2 frame meshSkinned.getBuffer(bufferindex2, 0); // capture current layer animation to bufferindex2 meshSkinned.lerpBuffer(bufferindex0, bufferindex0, bufferindex1, 0.5); meshSkinned.lerpBuffer(bufferindex0, bufferindex0, bufferindex2, 0.5); meshSkinned.lerpBuffer(bufferindex0, bufferindex0, bufferindex3, 0.5); meshSkinned.setBuffer(bufferindex0, 0); // lerped buffer data to rendering layer. Link to comment
Recommended Posts