source: osgVisual/src/object/visual_object.cpp @ 87

Last change on this file since 87 was 87, checked in by Torben Dannhauer, 14 years ago

Introductes VS 2008 Memory Leak Debugging.
Todo: Compile on Linux and compare with Valgrind, VS 2008 seems to be awkward in leak debugging

File size: 12.2 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <visual_object.h>
18
19using namespace osgVisual;
20
21visual_object::visual_object( osg::CoordinateSystemNode* sceneRoot_, std::string nodeName_)
22{
23        #include <leakDetection.h>
24
25        // Add this node to Scenegraph
26        sceneRoot_->addChild( this );
27
28        // Set Nodename for further identification
29        this->setName( nodeName_ );
30
31        // Set callback.
32        /** \todo: welcher update ist der richtige? voraussichtlich event.) */
33        //this->setUpdateCallback( new visual_objectPositionCallback() );
34        this->setEventCallback( new visual_objectPositionCallback() );
35
36        // Init Position and Attitude
37        lat = 0;
38        lon = 0;
39        alt = 0;
40
41        azimuthAngle_psi = 0;
42        pitchAngle_theta = 0;
43        bankAngle_phi = 0;
44
45        geometry_offset_rotation.makeRotate( 0.0, 1.0, 1.0, 1.0 );
46
47        // Init Scale
48        scaleX = 1.0;
49        scaleY = 1.0;
50        scaleZ = 1.0;
51
52        // Init cameraOffset
53        cameraTranslationOffset.makeTranslate( osg::Vec3d(0.0, 0.0, 0.0) );     // Trans: (y, x, -z_down)
54        cameraRotationOffset.makeRotate( osg::DegreesToRadians( 90.0 ), osg::Vec3(1, 0, 0) );   // Rot: (-y, +x , -z)
55
56        // Geometrynode hinzufügen
57        geometry = new osg::Group();
58        this->addChild( geometry );
59
60        // Labelnode hinzufügen
61        labels = new osg::Geode();
62        this->addChild( labels ); 
63}
64
65visual_object::~visual_object()
66{
67
68}
69
70void visual_object::setNewPositionAttitude( double lat_, double lon_, double alt_, double azimuthAngle_psi_, double pitchAngle_theta_, double bankAngle_phi_ )
71{
72        lat = lat_;
73        lon = lon_;
74        alt = alt_;
75
76        azimuthAngle_psi = azimuthAngle_psi_;
77        pitchAngle_theta = pitchAngle_theta_;
78        bankAngle_phi = bankAngle_phi_;
79}
80
81void visual_object::setNewPosition( double lat_, double lon_, double alt_ )
82{
83        lat = lat_;
84        lon = lon_;
85        alt = alt_;
86}
87
88void visual_object::setNewAttitude( double azimuthAngle_psi_, double pitchAngle_theta_, double bankAngle_phi_ )
89{
90        azimuthAngle_psi = azimuthAngle_psi_;
91        pitchAngle_theta = pitchAngle_theta_;
92        bankAngle_phi = bankAngle_phi_;
93}
94
95void visual_object::setGeometryOffset( double rotX_, double rotY_, double rotZ_ )
96{
97        geometry_offset_rotation.makeRotate( rotX_, osg::Vec3f(1.0, 0.0, 0.0), 
98                                                rotY_, osg::Vec3f(0.0, 1.0, 0.0),
99                                                rotZ_, osg::Vec3f(0.0, 0.0, 1.0) );
100}
101
102void visual_object::setScale( double scale_ )
103{
104        scaleX = scale_;
105        scaleY = scale_;
106        scaleZ = scale_;
107}
108
109void visual_object::setScale( double scaleX_, double scaleY_, double scaleZ_ )
110{
111        scaleX = scaleX_;
112        scaleY = scaleY_;
113        scaleZ = scaleZ_;
114}
115
116bool visual_object::loadGeometry(std::string filename_)
117{
118        // Check if file exists
119        if( !osgDB::fileExists(filename_) )
120        {
121                OSG_NOTIFY(osg::FATAL) << "Error: Model not loaded. File '" << filename_ << "' does not exist." << std::endl;
122        }
123
124        osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename_ );
125       
126        if( tmpModel.valid() )
127        {
128                // remove old geometry
129                geometry->removeChildren(0, geometry->getNumChildren());
130
131                // add new geometry
132                geometry->addChild( tmpModel.get() );
133                return true;
134        }
135        else
136        {
137                std::cout <<": No model loaded: " << filename_ << std::endl;
138        return false;
139    }
140}
141
142bool visual_object::setGeometry(osg::Node* geometry_)
143{
144        // remove old geometry
145        geometry->removeChildren(0, geometry->getNumChildren());
146
147        // add new geometry
148        geometry->addChild( geometry_ );
149
150        return true;
151}
152
153void visual_object::unsetGeometry()
154{
155        // remove old geometry
156        geometry->removeChildren(0, geometry->getNumChildren());
157}
158
159void visual_object::addUpdater( object_updater* updater_ )
160{
161        if ( updater.valid() )
162                updater->addUpdater( updater_ );
163        else
164                updater = updater_;
165}
166
167void visual_object::clearAllUpdater()
168{
169        // release only first updater. Because smartpointer: Will be deleted if not referenced.
170        if ( updater.valid() )
171                updater = NULL;
172}
173
174std::vector<object_updater*> visual_object::getUpdaterList()
175{
176        // iterate through updater and add all pointer.
177        std::vector<object_updater*> updaterList;
178        osg::ref_ptr<object_updater> tmpUpdater = updater;
179
180        while (tmpUpdater.valid())
181        {
182                updaterList.push_back( tmpUpdater );
183                tmpUpdater = tmpUpdater->getPointer();
184        }
185
186        // return list
187        return updaterList;
188}
189
190void visual_object::visual_objectPositionCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
191{
192        visual_object* object = dynamic_cast<visual_object*>(node);
193        if ( !object )
194        {
195                OSG_NOTIFY(osg::FATAL) << "ERROR : No object found. Unable to apply this callback!" << std::endl;
196                return;
197        }
198
199        // execute preUpdater to get new data of this object.
200        if ( object->updater.valid() )
201                object->updater->preUpdate(object);
202   
203        // Nodepath from this node to absolute parent (if no endnode specified)
204        osg::NodePath nodePath = nv->getNodePath();
205
206        // If Nodepath != empty, then mt = last element of node path
207        osg::MatrixTransform* mt = nodePath.empty() ? 0 : dynamic_cast<osg::MatrixTransform*>(nodePath.back());
208        if (mt)
209        {
210                osg::CoordinateSystemNode* csn = 0;
211
212                // find coordinate system node from our parental chain: traverse chain and try to convert every node to a csn.
213                unsigned int i;
214                for(i=0; i<nodePath.size() && csn==0; ++i)      // "&& csn" means: exit loop if csn found
215                {
216                        csn = dynamic_cast<osg::CoordinateSystemNode*>(nodePath[i]);    // dynamic_cast returns 0 if dynamic_cast fails.
217                }
218       
219                // Wenn csn gefunden:
220                if (csn)
221                {
222                        // Ellipsoidmodel erfragen
223                        osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
224                        if (ellipsoid)
225                        {
226                                osg::Matrix inheritedMatrix;
227
228                                // durch den _restlichen_ Nodepath durchgehen und alle anfallenden Transformationen durchführen.
229                                for(i+=1; i<nodePath.size()-1; ++i)
230                                {
231                                        osg::Transform* transform = nodePath[i]->asTransform(); // Versuchen, den Node zu einer Transformation zu konvertieren
232                   
233                                        // wenn Node wirklich Trafo, dann die Tranformationsmatrix von Nodekoordinaten nach Global auf inheritedMatrix draufschlagen.
234                                        if (transform) transform->computeLocalToWorldMatrix(inheritedMatrix, nv);
235                                }
236               
237                                osg::Matrixd matrix(inheritedMatrix);
238
239                                // Set position
240                                ellipsoid->computeLocalToWorldTransformFromLatLongHeight(object->lat, object->lon, object->alt, matrix);
241
242                                // Set Upvector for position
243                                double X,Y,Z;
244                                util::calculateXYZAtWGS84Coordinate(object->lat, object->lon, object->alt, csn, X, Y, Z );
245                                object->upVector = ellipsoid->computeLocalUpVector(X,Y,Z);
246
247                                // Set scale
248                                osg::Matrixd scaleMatrix;
249                                scaleMatrix.makeScale( object->scaleX, object->scaleY, object->scaleZ );
250                                matrix.preMult( scaleMatrix );
251
252                                // Set rotation
253                                // rotation von links ranmultiplizieren, entspricht: matrix = rotation * matrix. Da rotation ein Quat ist, wäre die direkte Multiplikation nur über Umwege machbar.
254                                // Rotate Object to Attitude.
255                                osg::Matrixd rotationMatrix;
256                                // Move Model by Azimuth
257                                rotationMatrix.makeRotate( -object->azimuthAngle_psi, osg::Vec3d(0.0, 0.0, 1.0) );
258                                matrix.preMult(rotationMatrix); 
259                                // Move Model by Pitch
260                                rotationMatrix.makeRotate( object->pitchAngle_theta, osg::Vec3d(1.0, 0.0, 0.0) );
261                                matrix.preMult(rotationMatrix);
262                                // Move Model by Bank
263                                rotationMatrix.makeRotate( object->bankAngle_phi, osg::Vec3d(0.0, 1.0, 0.0) );
264                                matrix.preMult(rotationMatrix);
265
266                                // Also update camera matrix (without geometry offset, because camera is interested in the objects matrix, not in the model's matrix.)
267                                object->cameraMatrix = matrix;
268                                /** \todo : Clean up camera matrix management: try to solve it with a single matrix. (each frame two matrix mults less) */
269                                // dont know, why this rotation is necessary - maybe manipulator and node MatrixTransform interpret a matrix in different way?
270                                object->cameraMatrix.preMult( object->cameraTranslationOffset );
271                                object->cameraMatrix.preMult( object->cameraRotationOffset );
272                                                       
273
274                                // Set geometry correction
275                                matrix.preMultRotate( object->geometry_offset_rotation );
276
277                                // Set cumulated object matrix as the matrix of this matrix transform
278                                mt->setMatrix(matrix);
279                        }
280                }       
281        }
282     
283        // Call any nested callbacks.
284        traverse(node,nv);
285
286        // If SLAVE: execute postUpdater to pass new data of this object to dataIO.
287        if( visual_dataIO::getInstance()->isSlave() )
288        {
289                if ( object->updater.valid() )
290                        object->updater->postUpdate(object);
291        }
292
293}   // Callbackfunction [ Operater() ] END
294
295void visual_object::setCameraOffsetTranslation( double x_, double y_, double z_)
296{
297        cameraTranslationOffset.makeTranslate( osg::Vec3d(x_, y_, z_) );        // Trans: (rechts davon, longitudinal, vertikal)
298}
299
300void visual_object::setCameraOffset(double x_, double y_, double z_, double rotX_, double rotY_, double rotZ_)
301{
302        setCameraOffsetTranslation( x_, y_, z_);
303        setCameraOffsetRotation( rotX_, rotY_, rotZ_);
304}
305
306void visual_object::setCameraOffsetRotation(double rotX_, double rotY_, double rotZ_)
307{
308        osg::Matrix tmp;
309        cameraRotationOffset.makeRotate( osg::DegreesToRadians( 90.0 ), osg::Vec3(1, 0, 0) );
310        tmp.makeRotate( -rotZ_, osg::Vec3d(0.0, 1.0, 0.0) );
311        cameraRotationOffset.preMult(tmp);
312        tmp.makeRotate( rotY_, osg::Vec3d(1.0, 0.0, 0.0) );     
313        cameraRotationOffset.preMult(tmp);
314        tmp.makeRotate( -rotX_, osg::Vec3d(0.0, 0.0, 1.0) );   
315        cameraRotationOffset.preMult(tmp);
316}
317
318void visual_object::clearLabels()
319{
320        labels->removeDrawables(0, labels->getNumDrawables());
321}
322
323void visual_object::addLabel(std::string idString_, std::string label_, osg::Vec4 color_, osg::Vec3 offset_)
324{
325        osg::ref_ptr<osgText::Text> text = new osgText::Text();
326
327        text->setName(idString_);
328        text->setText(label_);
329        text->setColor(color_);
330        text->setFont("fonts/arial.ttf");
331        text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
332        text->setAutoRotateToScreen(true);
333        text->setPosition(offset_);
334
335        text->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
336        labels->addDrawable( text );
337}
338
339bool visual_object::removeLabel(std::string idString_)
340{
341        osg::Node* labelToRemove = util::findNamedNode(idString_, this);
342
343        if(labelToRemove)
344        {
345                removeChild( labelToRemove );
346                return true;
347        }
348        else
349                return false;
350}
351
352bool visual_object::updateLabelText(std::string idString_, std::string label_)
353{
354        osg::Node* labelToUpdate = util::findNamedNode(idString_, this);
355
356        if(labelToUpdate)
357        {
358                osgText::Text* text = dynamic_cast<osgText::Text*>(labelToUpdate);
359                if(text)
360                {
361                        text->setText(label_);
362                        return true;
363                }
364                return false;
365        }
366        return false;
367}
368
369osgText::Text* visual_object::getLabel(std::string idString_)
370{
371        osg::Node* labelToFind = util::findNamedNode(idString_, this);
372
373        if(labelToFind)
374        {
375                osgText::Text* text = dynamic_cast<osgText::Text*>(labelToFind);
376                if(text)
377                        return text;
378        }
379        return NULL;
380
381}
382
383bool visual_object::setDrawLabelAsOverlay(std::string idString_, bool drawAsOverlay)
384{
385        osg::Node* labelToFind = util::findNamedNode(idString_, this);
386
387        if(labelToFind)
388        {
389                if (drawAsOverlay)
390                        labelToFind->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
391                else
392                        labelToFind->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::ON);
393                return true;
394        }
395        else 
396                return false;
397}
398
399bool visual_object::getDrawLabelAsOverlay(std::string idString_)
400{
401        osg::Node* labelToFind = util::findNamedNode(idString_, this);
402
403        if(labelToFind)
404        {
405                if(labelToFind->getOrCreateStateSet()->getMode(GL_DEPTH_TEST) == osg::StateAttribute::OFF)
406                        return false;
407                else 
408                        return true;
409        }
410        return false;
411}
Note: See TracBrowser for help on using the repository browser.