Re: [osg-users] osgAnimation skinning problem
Hello, i found the solution. If someone is intereseted: The result of setMatrixInSkeletonSpace will be periodically overriden by UpdateBone. To set this value doesn't make sense. setInvBindMatrixInSkeletonSpace is necessary instead. The parameter of this function is the transform from the bind pose of the current bone to the skeleton root, but without the translation of the current bone. The code of the osganimationskinning example is ok, but i followed at first the OpenSceneGraph Cookbook which explains to make use of setMatrixInSkeletonSpace (Skinning a customized mesh, Page 212, first code listening). Best regards, Stefan 2013/8/12 Stefan Frings stefan0fri...@gmail.com Hi, currently i'm writing an Ogre XML import plugin for OSG. Source will be available if it's working as expected. Import of meshes is working fine, but the skinning of skeleton animations in OSG drives me crazy. I created a demo model, skeleton and animation (quad with two bones) in Blender (2.49) and exported it with the OGRE mesh exporter. The Ogre tool CEGUI Mesh Viewer (http://www.ogre3d.org/tikiwiki/CEGUI+Mesh+Viewer) can display it correct. The model consists of 4 vertices and two triangles (face0: v0, v1, v3 and face1: v1, v2, v3). The bone Bone influences the vertices v0, v1 and v2 and the child bone Bone.001 influences the vertex v3. The image below shows the quad with the two bones. Both bones are laying in the same level (XY-plane) as the quad. http://lib-dev.com/osganim_skinning/blender.png See below for the generated Ogre XML mesh and skeleton file. For testing and demonstration purposes i hard coded the model with OSG (see below), based on the data given by the files. The result looks like like this. http://lib-dev.com/osganim_skinning/osg_result.png The quad isn't any longer a quad, even if no animation to the the bones is applied. And the origin of the second bone Bone.001 is at y=1. It should be located at y=-1, because of the rotation of the previos bone, but it isn't. However the second bone is relative to the first one. Result screenshot is taken during a rotation of Bone about the X-axis. The big coordinate axes marks the origin and the small ones show the position of the bones. I think i did a mistake at the creation of the bones, but i can't figure it out. Is the setMatrixInSkeletonSpace(...) call correct, or did i forget something? The source is adapted from the osganimationskinning example. I already spent days to find and fix it without any success. Thanks for advices or ideas! I'm using OSG 3.0.1 on Linux. Kindly regards, Stefan Frings Code: #include osg/Geometry #include osgAnimation/Bone #include osgAnimation/Skeleton #include osgAnimation/UpdateBone #include osgAnimation/RigGeometry #include osgAnimation/StackedTranslateElement #include osgAnimation/StackedQuaternionElement #include osgAnimation/StackedRotateAxisElement #include osgAnimation/BasicAnimationManager #include osgDB/ReadFile #include osgViewer/Viewer osgAnimation::RigGeometry* createRigGeo() { osg::Geometry* geo = new osg::Geometry; osg::ref_ptrosg::Vec3Array vertices(new osg::Vec3Array(4)); osg::ref_ptrosg::Vec3Array colors(new osg::Vec3Array(4)); geo-setVertexArray(vertices.get()); geo-setColorArray(colors.get()); geo-setColorBinding(osg::Geometry::BIND_PER_VERTEX); (*vertices)[0].set(1, 1, 0); (*colors)[0].set(1, 0, 0); (*vertices)[1].set(-1, 1, 0); (*colors)[1].set(0, 1, 0); (*vertices)[2].set(-1, -1, 0); (*colors)[2].set(0, 0, 1); (*vertices)[3].set(1, -1, 0); (*colors)[3].set(1, 1, 1); osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 2 * 3); geo-addPrimitiveSet(triangles); (*triangles)[0] = 0; (*triangles)[1] = 1; (*triangles)[2] = 3; (*triangles)[3] = 1; (*triangles)[4] = 2; (*triangles)[5] = 3; geo-getOrCreateStateSet()-setMode(GL_LIGHTING, false); geo-setDataVariance(osg::Object::DYNAMIC); geo-setUseDisplayList(false); osgAnimation::RigGeometry* rigGeo = new osgAnimation::RigGeometry; rigGeo-setSourceGeometry(geo); return rigGeo; } osgAnimation::VertexInfluenceMap* initVertexMap() { osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap; (*vim)[bone0].setName(bone0); (*vim)[bone0].push_back(osgAnimation::VertexIndexWeight(0, 1.0f)); (*vim)[bone0].push_back(osgAnimation::VertexIndexWeight(1, 1.0f)); (*vim)[bone0].push_back(osgAnimation::VertexIndexWeight(2, 1.0f)); (*vim)[bone1].setName(bone1); (*vim)[bone1].push_back(osgAnimation::VertexIndexWeight(3, 1.0f)); return vim; } int main(int argc, char* argv[]) { /// here i expect the mistake /// // create root bone (bone0, called Bone in blender) osg::ref_ptrosgAnimation::Bone bone0 = new osgAnimation::Bone; bone0-setMatrixInSkeletonSpace( osg::Matrix::rotate(M_PI, osg::Vec3(1, 0, 0)) *
[osg-users] osgAnimation skinning problem
Hi, currently i'm writing an Ogre XML import plugin for OSG. Source will be available if it's working as expected. Import of meshes is working fine, but the skinning of skeleton animations in OSG drives me crazy. I created a demo model, skeleton and animation (quad with two bones) in Blender (2.49) and exported it with the OGRE mesh exporter. The Ogre tool CEGUI Mesh Viewer (http://www.ogre3d.org/tikiwiki/CEGUI+Mesh+Viewer) can display it correct. The model consists of 4 vertices and two triangles (face0: v0, v1, v3 and face1: v1, v2, v3). The bone Bone influences the vertices v0, v1 and v2 and the child bone Bone.001 influences the vertex v3. The image below shows the quad with the two bones. Both bones are laying in the same level (XY-plane) as the quad. http://lib-dev.com/osganim_skinning/blender.png See below for the generated Ogre XML mesh and skeleton file. For testing and demonstration purposes i hard coded the model with OSG (see below), based on the data given by the files. The result looks like like this. http://lib-dev.com/osganim_skinning/osg_result.png The quad isn't any longer a quad, even if no animation to the the bones is applied. And the origin of the second bone Bone.001 is at y=1. It should be located at y=-1, because of the rotation of the previos bone, but it isn't. However the second bone is relative to the first one. Result screenshot is taken during a rotation of Bone about the X-axis. The big coordinate axes marks the origin and the small ones show the position of the bones. I think i did a mistake at the creation of the bones, but i can't figure it out. Is the setMatrixInSkeletonSpace(...) call correct, or did i forget something? The source is adapted from the osganimationskinning example. I already spent days to find and fix it without any success. Thanks for advices or ideas! I'm using OSG 3.0.1 on Linux. Kindly regards, Stefan Frings Code: #include osg/Geometry #include osgAnimation/Bone #include osgAnimation/Skeleton #include osgAnimation/UpdateBone #include osgAnimation/RigGeometry #include osgAnimation/StackedTranslateElement #include osgAnimation/StackedQuaternionElement #include osgAnimation/StackedRotateAxisElement #include osgAnimation/BasicAnimationManager #include osgDB/ReadFile #include osgViewer/Viewer osgAnimation::RigGeometry* createRigGeo() { osg::Geometry* geo = new osg::Geometry; osg::ref_ptrosg::Vec3Array vertices(new osg::Vec3Array(4)); osg::ref_ptrosg::Vec3Array colors(new osg::Vec3Array(4)); geo-setVertexArray(vertices.get()); geo-setColorArray(colors.get()); geo-setColorBinding(osg::Geometry::BIND_PER_VERTEX); (*vertices)[0].set(1, 1, 0); (*colors)[0].set(1, 0, 0); (*vertices)[1].set(-1, 1, 0); (*colors)[1].set(0, 1, 0); (*vertices)[2].set(-1, -1, 0); (*colors)[2].set(0, 0, 1); (*vertices)[3].set(1, -1, 0); (*colors)[3].set(1, 1, 1); osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 2 * 3); geo-addPrimitiveSet(triangles); (*triangles)[0] = 0; (*triangles)[1] = 1; (*triangles)[2] = 3; (*triangles)[3] = 1; (*triangles)[4] = 2; (*triangles)[5] = 3; geo-getOrCreateStateSet()-setMode(GL_LIGHTING, false); geo-setDataVariance(osg::Object::DYNAMIC); geo-setUseDisplayList(false); osgAnimation::RigGeometry* rigGeo = new osgAnimation::RigGeometry; rigGeo-setSourceGeometry(geo); return rigGeo; } osgAnimation::VertexInfluenceMap* initVertexMap() { osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap; (*vim)[bone0].setName(bone0); (*vim)[bone0].push_back(osgAnimation::VertexIndexWeight(0, 1.0f)); (*vim)[bone0].push_back(osgAnimation::VertexIndexWeight(1, 1.0f)); (*vim)[bone0].push_back(osgAnimation::VertexIndexWeight(2, 1.0f)); (*vim)[bone1].setName(bone1); (*vim)[bone1].push_back(osgAnimation::VertexIndexWeight(3, 1.0f)); return vim; } int main(int argc, char* argv[]) { /// here i expect the mistake /// // create root bone (bone0, called Bone in blender) osg::ref_ptrosgAnimation::Bone bone0 = new osgAnimation::Bone; bone0-setMatrixInSkeletonSpace( osg::Matrix::rotate(M_PI, osg::Vec3(1, 0, 0)) * osg::Matrix::translate(0.0,0.0,0.0) * bone0-getMatrixInSkeletonSpace() ); bone0-setName(bone0); bone0-setDataVariance(osg::Object::DYNAMIC); osgAnimation::UpdateBone* bone0Update = new osgAnimation::UpdateBone(bone0); bone0Update-getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement(translate,osg::Vec3(0, 0, 0))); bone0Update-getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement(rotate, osg::Vec3(1, 0, 0), M_PI)); bone0-setUpdateCallback(bone0Update); // create child bone (bone1, called Bone.001 in blender) osg::ref_ptrosgAnimation::Bone bone1 = new osgAnimation::Bone; bone1-setMatrixInSkeletonSpace( osg::Matrix::rotate(0.f, osg::Vec3(0, 0, 1))
Re: [osg-users] osganimation skinning
Hi, Thanks for your answer ! Yes I had already read this paper, it helps a lot. :) For Dual Quaternion skinning, I did pretty much what you said. My solution: I made a new class which inherits from RigTransform, and modify the calculation and what it's need. For the rest it is pretty much like RigTransformSoftware. It works well, but I'm not sure how clean my solution is. You are talking about hardware skinning, but I haven't look it a lot. Maybe you could help me found out the difference between rigTransformSoftware and rigTransformHardware ? And also why you think using hardware is a better start than software. Thank you! Cheers, Emilie -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=29013#29013 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] osganimation skinning
Hi, Emy wrote: And also why you think using hardware is a better start than software. Well, you'll find the skinning shader under osgAnimation. You should be able to tweak it, the input for linear palette blending should be the same as for dq. So there is no need to extend or derive from any osgAnimation class. Cheers, ParticlePeter -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=29016#29016 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
[osg-users] osganimation skinning
Hi, I have a question about skinning in osg; I am looking at the skinning exemple, and it is pretty simple : you have bones and their Inverse Bind Matrix (in skeleton space), a mesh ( TesselatedBox ) and an InfluenceMap to bind the mesh on the skeleton (with weights). Then, when an animation is launched, the mesh moves depending on bones' animation. I have made some research about linear blend skinning, and there is a formula used to calculate the new position of each vertex depending on bones. This formula implies the bindmatrix, the influence of bones (depending on their weight), etc. In the exemple (skinning), we specifies parameters (weight map, bind matrix) and the mesh position is calculated automaticaly ( I suppose the LBS formula is implemented somewhere, but I haven't seen it). My problem is that I want to implement dual quaternion skinning instead of linear blend skinning (i.e. : calculate the positions of vertex depending on bones with a different formula, but with (pretty much) the same parameters). Is there a way to do this ? At first I thought of using custom callback instead of updateBone, but I don't think this is a solution since the problem is not the update of the bone but the update of the mesh attached to it. Thanks a lot for taking the time to help me ! Emilie -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=27987#27987 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
[osg-users] osgAnimation/Skinning Header
Hi here, I'm currently trying to get OpenSceneGraph and osgswig to work together on Mac OS X Snow Leopard through MacPorts (I'm a maintainer there). It seems the latest developer release (2.9.6) does not install osgAnimation/Skinning header, which is used by osgswig. Is it a bug, or should osgswig not use it? Regards. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] osgAnimation/Skinning Header
Hi, Skinning header is not used anymore, it has been replaced with RigTransformSoftware. Cheers, Cedric -- Provide OpenGL services around OpenSceneGraph and more +33 659 598 614 Cedric Pinson mailto:cedric.pin...@plopbyte.net http://www.plopbyte.net On Tue, 2009-12-22 at 14:57 +0100, nox wrote: Hi here, I'm currently trying to get OpenSceneGraph and osgswig to work together on Mac OS X Snow Leopard through MacPorts (I'm a maintainer there). It seems the latest developer release (2.9.6) does not install osgAnimation/Skinning header, which is used by osgswig. Is it a bug, or should osgswig not use it? Regards. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org signature.asc Description: This is a digitally signed message part ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org