Hello,

We are using Open Scene Graph for an application and we need COLLADA
support. While testing the pluggin we found a small bug and we are
submitting a patch.

The first attachment is a small program that creates a scene with two
pyramids, transformed by two instances of
osg::PositionAttitudeTransform. One of them is rotated 90 degrees in
the X axis, and the scene is exported both in the native OSG (.osg)
and COLLADA (.dae)  formats. In the first case the rotated pyramid is
displayed correctly whereas in the second the pyramid seems not to be
rotated.

In the COLLADA 1.4.1 specification (found at
http://www.khronos.org/collada/) it is specified that
"The <rotate> element contains a list of four floating-point values
[...] followed by an angle in degrees" but the plugin seems to write
the value in radians.

The problem seems to be in the method daeWriter::apply() that seems to
be writing the angle value in radians to the COLLADA file. The patch
can be found in the second attachment and is simply a call to
RadiansToDegrees wrapped around the angle.

We are not really familiar with the code and so the patch might be
wrong, but it seems to work for us.

Thank you,

Loic Simon,
Panagiotis Koutsourakis,
Olivier Teboul.
#include <cmath>

#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Transform>
#include <osg/PositionAttitudeTransform>
#include <osg/Group>
#include <osg/Vec3d>
#include <osg/Quat>
#include <osgDB/WriteFile>

osg::Geode* createPyramid();



int main(int argc, char** argv)
{
    osg::ref_ptr<osg::Group> root = new osg::Group;
    osg::ref_ptr<osg::Geode> geode1 = createPyramid();
    osg::ref_ptr<osg::Geode> geode2 = createPyramid();
    osg::ref_ptr<osg::PositionAttitudeTransform> tf1 = new osg::PositionAttitudeTransform;
    osg::ref_ptr<osg::PositionAttitudeTransform> tf2 = new osg::PositionAttitudeTransform;

    //Move the first pyramid
    tf1->setPosition(osg::Vec3(3, 0, 0));
    
    //Rotate the second pyramid.
    tf2->setAttitude(osg::Quat(M_PI/2.0,osg::Vec3d(1.0,0.0,0.0)));

    //Add the nodes to the scene.
    root->addChild(tf1.get());
    root->addChild(tf2.get());
    tf1->addChild(geode1.get());
    tf2->addChild(geode2.get());

    //Export to OSG
    osgDB::writeNodeFile(*root,std::string("test.osg"));
    //Export to COLLADA
    osgDB::writeNodeFile(*root,std::string("test.dae"));
    


    return 0;
}


osg::Geode* createPyramid()
{
   osg::Geode* pyramidGeode = new osg::Geode();
   osg::Geometry* pyramidGeometry = new osg::Geometry();
   pyramidGeode->addDrawable(pyramidGeometry); 

   // Specify the vertices:
   osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
   pyramidVertices->push_back( osg::Vec3(0, 0, 0) ); // front left 
   pyramidVertices->push_back( osg::Vec3(2, 0, 0) ); // front right 
   pyramidVertices->push_back( osg::Vec3(2, 2, 0) ); // back right 
   pyramidVertices->push_back( osg::Vec3( 0,2, 0) ); // back left 
   pyramidVertices->push_back( osg::Vec3( 1, 1,2) ); // peak

   // Associate this set of vertices with the geometry associated with the 
   // geode we added to the scene.
   pyramidGeometry->setVertexArray( pyramidVertices );

   // Create a QUAD primitive for the base by specifying the 
   // vertices from our vertex list that make up this QUAD:
   osg::DrawElementsUInt* pyramidBase = 
      new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
   pyramidBase->push_back(3);
   pyramidBase->push_back(2);
   pyramidBase->push_back(1);
   pyramidBase->push_back(0);

   // Add this primitive to the geometry:
   pyramidGeometry->addPrimitiveSet(pyramidBase);
   // code to create other faces goes here!
   osg::DrawElementsUInt* pyramidFaceOne = 
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceOne->push_back(0);
   pyramidFaceOne->push_back(1);
   pyramidFaceOne->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceOne);

   osg::DrawElementsUInt* pyramidFaceTwo = 
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceTwo->push_back(1);
   pyramidFaceTwo->push_back(2);
   pyramidFaceTwo->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);

   osg::DrawElementsUInt* pyramidFaceThree = 
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceThree->push_back(2);
   pyramidFaceThree->push_back(3);
   pyramidFaceThree->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceThree);

   osg::DrawElementsUInt* pyramidFaceFour = 
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceFour->push_back(3);
   pyramidFaceFour->push_back(0);
   pyramidFaceFour->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceFour);


   osg::Vec4Array* colors = new osg::Vec4Array;
   colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 red
   colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 green
   colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 blue
   colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white
   colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 4 red

   pyramidGeometry->setColorArray(colors);
   pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

   // Since the mapping from vertices to texture coordinates is 1:1, 
   // we don't need to use an index array to map vertices to texture
   // coordinates. We can do it directly with the 'setTexCoordArray' 
   // method of the Geometry class. 
   // This method takes a variable that is an array of two dimensional
   // vectors (osg::Vec2). This variable needs to have the same
   // number of elements as our Geometry has vertices. Each array element
   // defines the texture coordinate for the cooresponding vertex in the
   // vertex array.
   osg::Vec2Array* texcoords = new osg::Vec2Array(5);
   (*texcoords)[0].set(0.00f,0.0f); // tex coord for vertex 0 
   (*texcoords)[1].set(0.25f,0.0f); // tex coord for vertex 1 
   (*texcoords)[2].set(0.50f,0.0f); // ""
   (*texcoords)[3].set(0.75f,0.0f); // "" 
   (*texcoords)[4].set(0.50f,1.0f); // ""
   pyramidGeometry->setTexCoordArray(0,texcoords);

   return pyramidGeode;
}
Index: src/osgPlugins/dae/daeWTransforms.cpp
===================================================================
--- src/osgPlugins/dae/daeWTransforms.cpp	(revision 9034)
+++ src/osgPlugins/dae/daeWTransforms.cpp	(working copy)
@@ -105,7 +105,7 @@
         rot->getValue().append( axis.x() );
         rot->getValue().append( axis.y() );
         rot->getValue().append( axis.z() );
-        rot->getValue().append( angle );
+        rot->getValue().append( osg::RadiansToDegrees(angle) );
     }
 
     if ( pos.x() != 0 || pos.y() != 0 || pos.z() != 0 )
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to