Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/hud/RadarOverlayElement.cc @ 1392

Last change on this file since 1392 was 1392, checked in by FelixSchulthess, 16 years ago

moved #includes to .cc from .h where possible

File size: 7.8 KB
Line 
1/*
2*   ORXONOX - the hottest 3D action shooter ever to exist
3*
4*
5*   License notice:
6*
7*   This program is free software; you can redistribute it and/or
8*   modify it under the terms of the GNU General Public License
9*   as published by the Free Software Foundation; either version 2
10*   of the License, or (at your option) any later version.
11*
12*   This program is distributed in the hope that it will be useful,
13*   but WITHOUT ANY WARRANTY; without even the implied warranty of
14*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*   GNU General Public License for more details.
16*
17*   You should have received a copy of the GNU General Public License
18*   along with this program; if not, write to the Free Software
19*   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20*
21*   Author:
22*      Yuning Chai
23*   Co-authors:
24*      ...
25*
26*/
27#include <string.h>
28
29
30#include <string.h>
31#include <OgreOverlayManager.h>
32#include <OgreStringConverter.h>
33#include <OgrePanelOverlayElement.h>
34
35#include "GraphicsEngine.h"
36#include "core/Tickable.h"
37#include "core/ConsoleCommand.h"
38#include "objects/SpaceShip.h"
39#include "RadarOverlayElement.h"
40
41namespace orxonox
42{
43
44    using namespace Ogre;
45
46    RadarOverlayElement::RadarOverlayElement(const String& name):PanelOverlayElement(name){
47    }
48
49    RadarOverlayElement::~RadarOverlayElement(){
50    }
51
52    void RadarOverlayElement::init(Real leftRel, Real topRel, Real dimRel, OverlayContainer* container){
53        // some initial data
54                om = &OverlayManager::getSingleton();
55        dimRel_ = dimRel;
56        leftRel_ = leftRel;
57        topRel_ = topRel;
58        container_ = container;
59        firstRadarObject_ = NULL;
60        lastRadarObject_ = NULL;
61        focus_ = NULL;
62
63        // create nav marker ...
64        navMarker_ = static_cast<PanelOverlayElement*>(om->createOverlayElement("Panel", "NavMarker"));
65        navMarker_->setMetricsMode(GMM_PIXELS);
66        navMarker_->setMaterialName("Orxonox/NavMarker");
67        navMarker_->setDimensions(16,16);
68        navMarker_->setPosition(0,386);
69        navMarker_->hide();
70        container_->addChild(navMarker_);
71
72        // these have to fit the data in the level
73        shipPos_ = Vector3(0.0, 0.0, 0.0);
74        initialDir_ = Vector3(1.0, 0.0, 0.0);
75        currentDir_ = initialDir_;
76        initialOrth_ = Vector3(0.0, 0.0, 1.0);
77        currentOrth_ = initialOrth_;
78        plane = Plane(currentDir_, shipPos_);
79
80        setMetricsMode(GMM_PIXELS);
81        setMaterialName("Orxonox/Radar");
82        resize();
83
84        container_->addChild(this);
85    }
86
87    void RadarOverlayElement::resize() {
88        // if window is resized, we must adapt these...
89        windowW_ = GraphicsEngine::getSingleton().getWindowWidth();
90        windowH_ = GraphicsEngine::getSingleton().getWindowHeight();
91        dim_ = (int) (dimRel_*windowH_);
92        left_ = (int) (leftRel_*windowW_-dim_/2);
93        top_ = (int) (topRel_*windowH_-dim_/2);
94        setPosition(left_, top_);
95        setDimensions(dim_,dim_);
96    }
97
98    void RadarOverlayElement::update() {
99        shipPos_ = SpaceShip::instance_s->getPosition();
100        currentDir_ = SpaceShip::instance_s->getOrientation()*initialDir_;              // according to beni....
101                currentOrth_ = SpaceShip::instance_s->getOrientation()*initialOrth_;
102        plane = Plane(currentDir_, shipPos_);
103
104        RadarObject* ro = firstRadarObject_;
105        // iterate through all RadarObjects
106                while(ro != NULL){
107                    // calc position on radar...
108            ro->radius_ = calcRadius(ro);
109            ro->phi_ = calcPhi(ro);
110            ro->right_ = calcRight(ro);
111
112            // set size to fit distance...
113            float d = (ro->pos_-shipPos_).length();
114            if(d<4000) ro->panel_->setDimensions(4,4);
115            else if(d<8000) ro->panel_->setDimensions(3,3);
116            else if(d<16000) ro->panel_->setDimensions(2,2);
117            else ro->panel_->setDimensions(1,1);
118
119            if (ro->right_){
120                ro->panel_->setPosition(sin(ro->phi_)*ro->radius_/
121                    3.5*dim_/2+dim_/2+left_-2,-cos(ro->phi_)*ro->radius_/3.5*dim_/2+dim_/2+top_-2);
122            }
123            else {
124                ro->panel_->setPosition(-sin(ro->phi_)*ro->radius_/
125                    3.5*dim_/2+dim_/2+left_-2,-cos(ro->phi_)*ro->radius_/3.5*dim_/2+dim_/2+top_-2);
126            }
127            ro = ro->next;
128                }
129                updateNavMarker();
130    }
131
132    void RadarOverlayElement::updateNavMarker(){
133        if(focus_ == NULL) return;
134        // from the angle we find out where to draw the marker
135        // and which of the four arrows to take
136        float r1 = atan((float)(windowW_)/(float)(windowH_));
137        float phi = focus_->phi_;
138        if(focus_->right_){
139            if(phi<r1){
140                navMarker_->setPosition(tan(phi)*windowH_/2+windowW_/2, 0);
141                navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
142            }
143            else if(phi>3.14-r1){
144                navMarker_->setPosition(-tan(phi)*windowH_/2+windowW_/2, windowH_-16);
145                navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
146            }
147            else {
148                navMarker_->setPosition(windowW_-16, -tan((3.14-2*phi)/2)*windowW_/2+windowH_/2);
149                navMarker_->setUV(0.5, 0.5, 1.0, 1.0);
150            }
151        }
152        else{
153            if(phi<r1) {
154                navMarker_->setPosition(-tan(phi)*windowH_/2+windowW_/2, 0);
155                navMarker_->setUV(0.5, 0.0, 1.0, 0.5);
156            }
157            else if(phi>3.14-r1) {
158                navMarker_->setPosition(tan(phi)*windowH_/2+windowW_/2, windowH_-16);
159                navMarker_->setUV(0.0, 0.5, 0.5, 1.0);
160            }
161            else {
162                navMarker_->setPosition(0, -tan((3.14-2*phi)/2)*windowW_/2+windowH_/2);
163                navMarker_->setUV(0.0, 0.0, 0.5, 0.5);
164            }
165        }
166    }
167
168    void RadarOverlayElement::addObject(Vector3 pos){
169        if(firstRadarObject_ == NULL){
170            firstRadarObject_ = new RadarObject(container_, pos);
171            lastRadarObject_ = firstRadarObject_;
172        }
173        else{
174            lastRadarObject_->next = new RadarObject(container_, pos);
175            lastRadarObject_ = lastRadarObject_->next;
176        }
177        }
178
179        void RadarOverlayElement::listObjects(){
180            int i = 0;
181            RadarObject* ro = firstRadarObject_;
182            COUT(3) << "List of RadarObjects:\n";
183            // iterate through all Radar Objects
184            while(ro != NULL) {
185                COUT(3) << i++ << ": " << ro->pos_ << std::endl;
186                ro = ro->next;
187            }
188        }
189
190        float RadarOverlayElement::getDist2Focus(){
191            if(focus_ == NULL) return(0.0);
192            return((focus_->pos_-shipPos_).length());
193        }
194
195        float RadarOverlayElement::calcRadius(RadarObject* obj){
196            return(acos((currentDir_.dotProduct(obj->pos_ - shipPos_))/
197                        ((obj->pos_ - shipPos_).length()*currentDir_.length())));
198        }
199
200        float RadarOverlayElement::calcPhi(RadarObject* obj){
201            // project difference vector on our plane...
202            Vector3 proj = plane.projectVector(obj->pos_ - shipPos_);
203            // ...and find out the angle
204            return(acos((currentOrth_.dotProduct(proj))/
205            (currentOrth_.length()*proj.length())));
206        }
207
208        bool RadarOverlayElement::calcRight(RadarObject* obj){
209            if((currentDir_.crossProduct(currentOrth_)).dotProduct(obj->pos_ - shipPos_) > 0)
210                return true;
211        else return false;
212        }
213
214        void RadarOverlayElement::cycleFocus(){
215            if(focus_ == NULL){
216            focus_ = firstRadarObject_;
217            }
218        else{
219            focus_->panel_->setMaterialName("Orxonox/RedDot");
220            focus_ = focus_->next;
221        }
222
223        if(focus_ == NULL){
224            navMarker_->hide();
225        }
226        else{
227            navMarker_->show();
228            focus_->panel_->setMaterialName("Orxonox/WhiteDot");
229        }
230        }
231}
232
233/* my local clipboard...
234COUT(3) << "WWWWWWWWWWWWWWWWWWWWWWWWWWWW\n";
235COUT(3) << firstRadarObject_->radius_ << "  " << firstRadarObject_->phi_ << std::endl;
236COUT(3) << "WWWWWWWWWWWWWWWWWWWWWWWWWWWW\n";
237*/
Note: See TracBrowser for help on using the repository browser.