source: osgVisual/trunk/src/object/visual_object.cpp @ 187

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

Moved memory leak detection from source file to headerfile. Its still in the class but at least not in the source file.

The leak detection works, but the false positives are not stopped.
Use Linux/Valgrind? to make your final leak detection beyond the easy first approach in MSVC

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