Show
Ignore:
Timestamp:
02/26/10 15:41:50 (2 years ago)
Author:
robert
Message:

From Michael Platings, "Here's the all-new, all-dancing DAE plugin, with support for reading
osgAnimation. It's been tested with the majority of the samples in the
COLLADA test repository and works with all of them either as well as, or
better than, the version of the plugin currently in SVN.

Known issue: vertex animation (AKA morphing) doesn't work at present,
but that's a relatively unpopular method of animating so it's not high
on my priority list."

Follow up email:
"I've been informed that the previous DAE submission didn't build on
unix, so here's the submission again with the fixes. Thanks to Gregory Potdevin and Benjamin Bozou.
Also, my apologies to Roland for not crediting his part in making DAE
animation happen, my work was indeed built on top of his work. Thanks
also to Marius Heise and of course Cedric Pinson."

Changes by Robert Osfield, fixed compile issues when compile without C* automatic conversion enabled in ref_ptr<>
and constructor initialization fixes to address some warnings under gcc.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWTransforms.cpp

    r9476 r11129  
    22 * Copyright 2006 Sony Computer Entertainment Inc. 
    33 * 
    4  * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this  
     4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 
    55 * file except in compliance with the License. You may obtain a copy of the License at: 
    66 * http://research.scea.com/scea_shared_source_license.html 
    77 * 
    8  * Unless required by applicable law or agreed to in writing, software distributed under the License  
    9  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
    10  * implied. See the License for the specific language governing permissions and limitations under the  
    11  * License.  
     8 * Unless required by applicable law or agreed to in writing, software distributed under the License 
     9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
     10 * implied. See the License for the specific language governing permissions and limitations under the 
     11 * License. 
    1212 */ 
    1313 
     
    2020#include <dae/domAny.h> 
    2121 
     22#include <osgAnimation/Bone> 
    2223#include <osgSim/DOFTransform> 
    2324 
    24 using namespace osgdae; 
     25using namespace osgDAE; 
     26 
     27 
     28void daeWriter::writeUpdateTransformElements(const osg::Vec3 &pos, const osg::Quat &q,    const osg::Vec3 &s) 
     29{ 
     30    // Make a scale place element 
     31    domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) ); 
     32    scale->setSid("scale"); 
     33    scale->getValue().append3( s.x(), s.y(), s.z() ); 
     34 
     35    // Make a three rotate place elements for the euler angles 
     36    // TODO decompose quaternion into three euler angles 
     37    double angle; 
     38    osg::Vec3 axis; 
     39    q.getRotate( angle, axis ); 
     40 
     41    domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 
     42    rot->setSid("rotateZ"); 
     43    rot->getValue().append4( 0, 0, 1, osg::RadiansToDegrees(angle) ); 
     44 
     45    rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 
     46    rot->setSid("rotateY"); 
     47    rot->getValue().append4( 0, 1, 0, osg::RadiansToDegrees(angle) ); 
     48 
     49    rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 
     50    rot->setSid("rotateX"); 
     51    rot->getValue().append4( 1, 0, 0, osg::RadiansToDegrees(angle) ); 
     52 
     53    // Make a translate place element 
     54    domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) ); 
     55    trans->setSid("translate"); 
     56    trans->getValue().append3( pos.x(), pos.y(), pos.z() ); 
     57} 
    2558 
    2659//MATRIX 
     
    3972 
    4073    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) ); 
    41     currentNode->setId(getNodeName(node,"matrixTransform").c_str()); 
    42      
    43     domMatrix *mat = daeSafeCast< domMatrix >(currentNode->add( COLLADA_ELEMENT_MATRIX ) ); 
    44     const osg::Matrix::value_type *mat_vals = node.getMatrix().ptr(); 
    45     //for ( int i = 0; i < 16; i++ ) 
    46     //{ 
    47     //  mat->getValue().append( mat_vals[i] ); 
    48     //} 
    49     mat->getValue().append( mat_vals[0] ); 
    50     mat->getValue().append( mat_vals[4] ); 
    51     mat->getValue().append( mat_vals[8] ); 
    52     mat->getValue().append( mat_vals[12] ); 
    53     mat->getValue().append( mat_vals[1] ); 
    54     mat->getValue().append( mat_vals[5] ); 
    55     mat->getValue().append( mat_vals[9] ); 
    56     mat->getValue().append( mat_vals[13] ); 
    57     mat->getValue().append( mat_vals[2] ); 
    58     mat->getValue().append( mat_vals[6] ); 
    59     mat->getValue().append( mat_vals[10] ); 
    60     mat->getValue().append( mat_vals[14] ); 
    61     mat->getValue().append( mat_vals[3] ); 
    62     mat->getValue().append( mat_vals[7] ); 
    63     mat->getValue().append( mat_vals[11] ); 
    64     mat->getValue().append( mat_vals[15] ); 
     74    std::string nodeName = getNodeName(node,"matrixTransform"); 
     75    currentNode->setId(nodeName.c_str()); 
     76 
     77    osg::NodeCallback* ncb = node.getUpdateCallback(); 
     78    bool handled = false; 
     79    if (ncb) 
     80    { 
     81        osgAnimation::UpdateMatrixTransform* ut = dynamic_cast<osgAnimation::UpdateMatrixTransform*>(ncb); 
     82        // If targeted by an animation we split up the matrix into multiple place element so they can be targeted individually 
     83        if (ut) 
     84        { 
     85            handled = true; 
     86 
     87            const osg::Matrix &mat = node.getMatrix(); 
     88 
     89            // Note: though this is a generic matrix, based on the fact that it will be animated by and UpdateMatrixTransform, 
     90            // we assume the initial matrix can be decomposed into translation, rotation and scale elements 
     91            writeUpdateTransformElements(mat.getTrans(), mat.getRotate(), mat.getScale()); 
     92        } 
     93    } 
     94 
     95    // If not targeted by an animation simply write a single matrix place element 
     96    if (!handled) 
     97    { 
     98        domMatrix *mat = daeSafeCast< domMatrix >(currentNode->add( COLLADA_ELEMENT_MATRIX ) ); 
     99        nodeName += "_matrix"; 
     100        mat->setSid(nodeName.c_str()); 
     101 
     102        const osg::Matrix::value_type *mat_vals = node.getMatrix().ptr(); 
     103        for ( int i = 0; i < 4; i++ ) 
     104        { 
     105            for ( int j = 0; j < 4; j++ ) 
     106            { 
     107                mat->getValue().append( mat_vals[i + j*4] ); 
     108            } 
     109        } 
     110    } 
    65111 
    66112    lastDepth = _nodePath.size(); 
     
    85131    } 
    86132    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) ); 
    87     currentNode->setId(getNodeName(node,"positionAttitudeTransform").c_str()); 
    88      
     133    std::string nodeName = getNodeName(node,"positionAttitudeTransform"); 
     134    currentNode->setId(nodeName.c_str()); 
     135 
    89136    const osg::Vec3 &pos = node.getPosition(); 
    90137    const osg::Quat &q = node.getAttitude(); 
    91138    const osg::Vec3 &s = node.getScale(); 
    92139 
    93     if ( pos.x() != 0 || pos.y() != 0 || pos.z() != 0 ) 
    94     { 
    95         //make a translate 
    96         domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) ); 
    97         trans->getValue().append( pos.x() ); 
    98         trans->getValue().append( pos.y() ); 
    99         trans->getValue().append( pos.z() ); 
    100     } 
    101  
    102     double angle; 
    103     osg::Vec3 axis; 
    104     q.getRotate( angle, axis ); 
    105     if ( angle != 0 ) 
    106     { 
    107         //make a rotate 
    108         domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 
    109         rot->getValue().append( axis.x() ); 
    110         rot->getValue().append( axis.y() ); 
    111         rot->getValue().append( axis.z() ); 
    112         rot->getValue().append( osg::RadiansToDegrees(angle) ); 
    113     } 
     140    osg::NodeCallback* ncb = node.getUpdateCallback(); 
     141    bool handled = false; 
     142    if (ncb) 
     143    { 
     144        osgAnimation::UpdateMatrixTransform* ut = dynamic_cast<osgAnimation::UpdateMatrixTransform*>(ncb); 
     145        // If targeted by an animation we split up the matrix into multiple place element so they can be targeted individually 
     146        if (ut) 
     147        { 
     148            handled = true; 
     149 
     150            writeUpdateTransformElements(pos, q, s); 
     151        } 
     152    } 
     153 
     154    // If not targeted by an animation simply add the elements that actually contribute to placement 
     155    if (!handled) 
     156    { 
     157        if ( s.x() != 1 || s.y() != 1 || s.z() != 1 ) 
     158        { 
     159            // Make a scale place element 
     160            domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) ); 
     161            scale->setSid("scale"); 
     162            scale->getValue().append3( s.x(), s.y(), s.z() ); 
     163        } 
     164 
     165        double angle; 
     166        osg::Vec3 axis; 
     167        q.getRotate( angle, axis ); 
     168        if ( angle != 0 ) 
     169        { 
     170            // Make a rotate place element 
     171            domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 
     172            rot->setSid("rotate"); 
     173            rot->getValue().append4( axis.x(), axis.y(), axis.z(), osg::RadiansToDegrees(angle) ); 
     174        } 
    114175 
    115176    if ( s.x() != 1 || s.y() != 1 || s.z() != 1 ) 
    116     { 
    117         //make a scale 
    118         domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) ); 
    119         scale->getValue().append( s.x() ); 
    120         scale->getValue().append( s.y() ); 
    121         scale->getValue().append( s.z() ); 
     177        { 
     178            // Make a translate place element 
     179            domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) ); 
     180            trans->setSid("translate"); 
     181            trans->getValue().append3( pos.x(), pos.y(), pos.z() ); 
     182        } 
    122183    } 
    123184 
     
    129190} 
    130191 
    131 void daeWriter::apply( osg::Transform &node )  
     192void daeWriter::apply( osg::Transform &node ) 
    132193{ 
    133194    debugPrint( node ); 
     
    140201    } 
    141202    currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) ); 
    142      
     203 
    143204    // If a DOFTransform node store it's data as extra "DOFTransform" data in the "OpenSceneGraph" technique 
    144205    osgSim::DOFTransform* dof = dynamic_cast<osgSim::DOFTransform*>(&node); 
     
    224285 
    225286        domAny *putMatrix = (domAny*)teq->add("PutMatrix" ); 
    226         putMatrix->setValue(toString(dof->getPutMatrix()).c_str());         
     287        putMatrix->setValue(toString(dof->getPutMatrix()).c_str()); 
    227288 
    228289        currentNode->setId(getNodeName(node, "doftransform").c_str()); 
     
    230291    else 
    231292    { 
    232         currentNode->setId(getNodeName(node, "transform").c_str()); 
    233         osg::notify( osg::WARN ) << "some other transform type. Missing " << node.getNumChildren() << " children" << std::endl; 
     293        osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node); 
     294        if (bone) 
     295        { 
     296            domNode *pDomNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE )); 
     297            pDomNode->setType(NODETYPE_JOINT); 
     298            pDomNode->setId(getNodeName(node, "bone").c_str()); 
     299        } 
     300        else 
     301        { 
     302            currentNode->setId(getNodeName(node, "transform").c_str()); 
     303            osg::notify( osg::WARN ) << "some other transform type. Missing " << node.getNumChildren() << " children" << std::endl; 
     304        } 
    234305    } 
    235306 
     
    241312} 
    242313 
    243 void daeWriter::apply( osg::CoordinateSystemNode &node )  
     314void daeWriter::apply( osg::CoordinateSystemNode &node ) 
    244315{ 
    245316    osg::notify( osg::WARN ) << "CoordinateSystemNode. Missing " << node.getNumChildren() << " children" << std::endl; 
    246317} 
     318 
     319