File: OrientationConverter.cpp

package info (click to toggle)
openscenegraph 3.0.1-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 30,940 kB
  • sloc: cpp: 352,623; ansic: 9,043; java: 1,020; yacc: 548; objc: 417; makefile: 285; xml: 155; lex: 151
file content (93 lines) | stat: -rw-r--r-- 2,361 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <stdio.h>

#include <osg/MatrixTransform>
#include <osgUtil/Optimizer>

#include "OrientationConverter.h"

using namespace osg;

OrientationConverter::OrientationConverter( void )
{
   R.makeIdentity();
   T.makeIdentity();
   _trans_set = false;
   _use_world_frame = false;
   S.makeIdentity();
}

void OrientationConverter::setRotation( const Vec3 &from, const Vec3 &to )
{
    R = Matrix::rotate( from, to );
}

void OrientationConverter::setRotation( float degrees, const Vec3 &axis )
{
    R = Matrix::rotate( osg::DegreesToRadians(degrees), axis );
}

void OrientationConverter::setTranslation( const Vec3 &trans )
{
    T = Matrix::translate(trans);
    _trans_set = true;
}

void OrientationConverter::setScale( const Vec3 &scale )
{
    S = Matrix::scale(scale);
}

void OrientationConverter::useWorldFrame( bool worldFrame )
{
   _use_world_frame = worldFrame;
}

Node* OrientationConverter::convert( Node *node )
{
    // Order of operations here is :
    // 1. If world frame option not set, translate to world origin (0,0,0)
    // 2. Rotate to new orientation
    // 3. Scale in new orientation coordinates
    // 4. If an absolute translation was specified then
    //        - translate to absolute translation in world coordinates
    //    else if world frame option not set,
    //        - translate back to model's original origin.
    BoundingSphere bs = node->getBound();
    Matrix C;

    if (_use_world_frame)
    {
        C.makeIdentity();
    }
    else
    {
        C = Matrix::translate( -bs.center() );
        
        if (_trans_set == false)
            T = Matrix::translate( bs.center() );
    }


    osg::Group* root = new osg::Group;
    osg::MatrixTransform* transform = new osg::MatrixTransform;

    transform->setDataVariance(osg::Object::STATIC);
    transform->setMatrix( C * R * S * T );
    
    if (!S.isIdentity())
    {
        #if !defined(OSG_GLES2_AVAILABLE)
            // Add a normalize state. This will be removed if the FlattenStaticTransformsVisitor works
            transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
        #endif
    }

    root->addChild(transform);
    transform->addChild(node);

    osgUtil::Optimizer::FlattenStaticTransformsVisitor fstv;
    root->accept(fstv);
    fstv.removeTransforms(root);
    
    return root->getChild(0);
}