Hi Peter,

I have a fix, but it's not the ideal solution. The idea is to cull the
morph geometry but to update it. In order to do that you can add a cull
callback that does not traverse child.
I have updated your sample to demonstrate the technique. Note you have
to add group in your hierarchy in order the cull callback works, it's
because the cull visitor iterate on drawable geode even if there is a
cull callback that does not traverse. You can see why with more detail
in osgUtil/CullVisitor.cpp:712 but doing it for a group will do the
things and will filter the subgraph only on rednering part.

Another way would be to setup the cull mask traversal but I dont
remember where it must be set.

About the channel '0' it's because the channel is associated to the
index of shape, it has been done like that in the past, it can be a
problem if you have more than one morphGeometry instance on a subgraph
driven by an animation manager. For skinning bones are named so I guess
we would need the same things for morph geometry.

Cheers,
Cedric

On Sun, 2010-12-05 at 15:54 +0100, Peter Wrobrl wrote:
> Hi,
> 
> I'm feeding a MorphGeometry into RigGeometry, to achieve Character Animation 
> with Facial Morphing. The system works, but it is unclear where to attach the 
> osgAnimation::UpdateMorph.
> 
> Two cases ( Source Attached ) :
> 
> 1.) Animation for UpdateMorph does not work
> GroupRoot ( with BasicAnimtionManager and an animation )
> --Skeleton
> ----Geode ( with UpdateMorph )
> ------RigGeometry
> --------MorphGeometry ( Morph Base )
> ----------Geometry ( Morph Target )
> 
> 2.) Animation Works, but skinned and unskinned ( both morphing ) is Visible
> GroupRoot ( with BasicAnimtionManager and an animation )
> --Skeleton
> ----GeodeRig
> ------RigGeometry
> --------MorphGeometry ( Instanced bellow )
> --GeodeMorph ( with UpdateMorph )
> ----MorphGeometry ( Morph Base )
> ------Geometry ( Morph Target )
> 
> I cannot turn off the NodeMask for the GeodeMorph, as then the UpdateMorph 
> does not calculate.
> 
> So how can I attach the UpdateMorph so that the skin gets morphed ( before 
> Bone Influence ) and only one geometry been visible ?
> 
> Btw, Cedric, should a FloatLinearChannel not be rather named "morph" than "0" 
> ?
> Moreover, I'm writing out the file, there are issues in reading it back with 
> the osganimationviewer.
> I'm using SVN Version 2.9.10
> 
> 
> Thank you!
> 
> Cheers,
> ParticlePeter
> 
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=34536#34536
> 
> 
> 
> 
> Attachments: 
> http://forum.openscenegraph.org//files/osgmorphskin_102.zip
> 
> 
> _______________________________________________
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> 

-- 
Provide OpenGL, WebGL and OpenSceneGraph services
+33 659 598 614 Cedric Pinson mailto:cedric.pin...@plopbyte.net
http://www.plopbyte.net
/*	-*-c++-*- 
 *	Copyright (C) 2008 Cedric Pinson <morni...@plopbyte.net>
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.	The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
 */

#include <iostream>
#include <osg/Geometry>

#include <osg/MatrixTransform>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>
#include <osgUtil/SmoothingVisitor>
#include <osg/io_utils>

#include <osgAnimation/RigGeometry>
#include <osgAnimation/MorphGeometry>
#include <osgAnimation/BasicAnimationManager>

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>


struct FilterCullCallback : osg::NodeCallback
{
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        
        // do nothing and stop traverse
    }
};


bool validPointer( osg::Object * pointer , std::string error )  {
    if ( pointer ) return true ;
    else std::cout << error << std::endl << std::endl ;
    return false ;
}



class RigGeometryFinder : public osg::NodeVisitor
{
public :	
    RigGeometryFinder() : osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN )  {}

    void apply( osg::Geode & geode )  {
        if ( _rigGeometry.valid() )
            return ;

        for( unsigned int i = 0 ; i < geode.getNumDrawables() ; ++i )  {
            osgAnimation::RigGeometry * rigGeometry = dynamic_cast< osgAnimation::RigGeometry * >( geode.getDrawable( i ) ) ;
            if ( rigGeometry )  {
                _rigGeometry = rigGeometry ;
                return ;
            }
        }
    }

    osgAnimation::RigGeometry * getRigGeometry()  {
        return _rigGeometry.get() ;
    }

private :
    osg::ref_ptr< osgAnimation::RigGeometry > _rigGeometry ;
} ;



osgAnimation::RigGeometry * getRigShape( osg::Node * node )  {
    RigGeometryFinder rigGeometryFinder ;
    node -> accept( rigGeometryFinder ) ;
    return rigGeometryFinder.getRigGeometry() ;
}


int main( int argc , char * argv[] )  {
    osg::Group * grpMorphSkinBase = dynamic_cast< osg::Group * > ( osgDB::readNodeFile( "data/morphSkinBase.osg" ) ) ;
    if ( !validPointer( grpMorphSkinBase , "No file \"morphSkinBase.osg\" !" ) )  return 0 ;
    osgAnimation::BasicAnimationManager * animationManager = static_cast< osgAnimation::BasicAnimationManager * > ( grpMorphSkinBase -> getUpdateCallback() ) ;
    osgAnimation::Animation * animation = animationManager -> getAnimationList()[0] ;
    osgAnimation::FloatLinearChannel * channel = new osgAnimation::FloatLinearChannel ;
    channel -> getOrCreateSampler() -> getOrCreateKeyframeContainer() -> push_back( osgAnimation::FloatKeyframe( 0 , 0.0 ) ) ;
    channel -> getOrCreateSampler() -> getOrCreateKeyframeContainer() -> push_back( osgAnimation::FloatKeyframe( 1 , 1.0 ) ) ;
    channel -> getOrCreateSampler() -> getOrCreateKeyframeContainer() -> push_back( osgAnimation::FloatKeyframe( 2 , 0.0 ) ) ;
    channel -> setTargetName( "MorphNodeCallback" ) ;
    channel -> setName( "0" ) ;	// Why not "morph" ? Does not work with name "morph"
    animation -> addChannel( channel ) ;
    animationManager -> playAnimation( animation ) ;

    osgAnimation::RigGeometry * rigGeometryBase = getRigShape( grpMorphSkinBase ) ;

    osg::Geometry * geometryBase = dynamic_cast< osg::Geometry * >( rigGeometryBase -> getSourceGeometry() ) ;
    if ( !validPointer( geometryBase , "No Base Geometry in RigGeoemetry !" ) )  return 0 ;

    osg::Geode * geodeMorphTarget = dynamic_cast< osg::Geode * > ( osgDB::readNodeFile( "data/morphSkinTarget.osg" ) ) ;
    if ( !validPointer( grpMorphSkinBase , "No file \"morphSkinTarget.osg\" !" ) )  return 0 ;
    osg::Geometry * geometryTarget = dynamic_cast< osg::Geometry * > ( geodeMorphTarget -> getDrawable( 0 ) ) ;
    if ( !validPointer( geometryTarget , "No Target Geometry in file !" ) )  return 0 ;

    // initialize with the first shape
    osgAnimation::MorphGeometry * morphGeometry = new osgAnimation::MorphGeometry( * geometryBase ) ;
    morphGeometry -> addMorphTarget( geometryTarget , 0.0f ) ;
    rigGeometryBase -> setSourceGeometry( morphGeometry ) ;
    // not working, UpdateMorph does not calculate
//	rigGeometryBase -> getParent( 0 ) -> addUpdateCallback( new osgAnimation::UpdateMorph( "MorphNodeCallback" ) ) ;

    osg::Group* grp = new osg::Group();
    osg::Geode * geodeMorph = new osg::Geode ;
    geodeMorph -> addDrawable( morphGeometry ) ;
    geodeMorph -> addUpdateCallback( new osgAnimation::UpdateMorph( "MorphNodeCallback" ) ) ;
    grpMorphSkinBase -> addChild( grp ) ;
    grp->addChild(geodeMorph);
    // Not Working, UpdateMorph does not calculate when Geode is hidden
//	geodeMorph -> setNodeMask( 0 ) ;
    grp->setCullCallback(new FilterCullCallback());

    osg::ArgumentParser argumentParser( & argc , argv ) ;
    osgViewer::Viewer viewer( argumentParser ) ;
    viewer.setCameraManipulator( new osgGA::TrackballManipulator() ) ;
    viewer.addEventHandler( new osgViewer::StatsHandler() ) ;
    viewer.addEventHandler( new osgViewer::WindowSizeHandler() ) ;
    viewer.addEventHandler( new osgGA::StateSetManipulator( viewer.getCamera() -> getOrCreateStateSet() ) ) ;
    viewer.setSceneData( grpMorphSkinBase ) ;

    viewer.run() ;

    morphGeometry -> setWeight( 0 , 0.0f ) ;
    osgDB::writeNodeFile( * grpMorphSkinBase , "MorphSkin.osg" ) ;

    return 0 ;
}

Attachment: 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

Reply via email to