| 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. |
| 24 | | using namespace osgdae; |
| | 25 | using namespace osgDAE; |
| | 26 | |
| | 27 | |
| | 28 | void 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 | } |
| 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 | } |
| 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 | } |
| 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 | } |
| 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 | } |