Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/src/orxonox/graphics/Model.cc @ 8974

Last change on this file since 8974 was 8034, checked in by landauf, 14 years ago

renamed enableModelLoD config value as enableMeshLoD (also renamed it in the graphics menu) because thats technically more accurate (thanks to Oli for pointing this out)

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "Model.h"
30
31#include <OgreEntity.h>
32
33#include "core/CoreIncludes.h"
34#include "core/ConfigValueIncludes.h"
35#include "core/GameMode.h"
36#include "core/XMLPort.h"
37#include "Scene.h"
38#include "graphics/MeshLodInformation.h"
39#include "Level.h"
40
41namespace orxonox
42{
43    CreateFactory(Model);
44
45    Model::Model(BaseObject* creator) :
46        StaticEntity(creator), bCastShadows_(true), lodLevel_(5), bLodEnabled_(true), numLodLevels_(10), lodReductionRate_(.15f)
47    {
48        RegisterObject(Model);
49
50        this->setConfigValues();
51        this->registerVariables();
52    }
53
54    Model::~Model()
55    {
56        if (this->isInitialized() && this->mesh_.getEntity())
57            this->detachOgreObject(this->mesh_.getEntity());
58    }
59
60    void Model::setConfigValues()
61    {
62        SetConfigValueExternal(bGlobalEnableLod_, "GraphicsSettings", "enableMeshLoD", true)
63            .description("Enable level of detail for models");
64    }
65
66    void Model::XMLPort(Element& xmlelement, XMLPort::Mode mode)
67    {
68        SUPER(Model, XMLPort, xmlelement, mode);
69
70        XMLPortParam(Model, "lodLevel", setLodLevel, getLodLevel, xmlelement, mode);
71
72        XMLPortParam(Model, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
73        XMLPortParam(Model, "shadow", setCastShadows, getCastShadows, xmlelement, mode).defaultValues(true);
74    }
75
76    void Model::registerVariables()
77    {
78        registerVariable(this->meshSrc_,    VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedMesh));
79        registerVariable(this->bCastShadows_, VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedShadows));
80    }
81
82    float Model::getBiggestScale(Vector3 scale3d)
83    {
84        float scaleFactor = scale3d.x;
85        if(scale3d.y>scaleFactor)
86            scaleFactor = scale3d.y;
87        if(scale3d.z>scaleFactor)
88            scaleFactor = scale3d.z;
89        return scaleFactor;
90    }
91
92    void Model::changedMesh()
93    {
94        if (GameMode::showsGraphics())
95        {
96            if (this->mesh_.getEntity())
97                this->detachOgreObject(this->mesh_.getEntity());
98
99            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
100
101            if (this->mesh_.getEntity())
102            {
103                this->attachOgreObject(this->mesh_.getEntity());
104                this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
105                this->mesh_.setVisible(this->isVisible());
106
107                if (this->bGlobalEnableLod_)
108                    this->enableLod();
109            }
110        }
111    }
112
113    void Model::changedShadows()
114    {
115        this->mesh_.setCastShadows(this->bCastShadows_);
116    }
117
118    void Model::changedVisibility()
119    {
120        SUPER(Model, changedVisibility);
121
122        this->mesh_.setVisible(this->isVisible());
123    }
124
125    void Model::enableLod()
126    {
127        //LOD
128        if( this->mesh_.getEntity()->getMesh()->getNumLodLevels()==1 )
129        {
130            Level* level = this->getLevel();
131
132            assert( level != 0 );
133
134            MeshLodInformation* lodInfo = level->getLodInfo(this->meshSrc_);
135            if( lodInfo )
136            {
137                setLodLevel(lodInfo->getLodLevel());
138                this->bLodEnabled_ = lodInfo->getEnabled();
139                this->numLodLevels_ = lodInfo->getNumLevels();
140                this->lodReductionRate_ = lodInfo->getReductionRate();
141            }
142            if( this->numLodLevels_>10 )
143            {
144                CCOUT(2) << "More than 10 LoD levels requested. Creating only 10." << endl;
145                this->numLodLevels_ = 10;
146            }
147            if( this->bLodEnabled_ )
148            {
149                float volume = this->mesh_.getEntity()->getBoundingBox().volume();
150/*
151                float scaleFactor = 1;
152
153                BaseObject* creatorPtr = this;
154
155                while(creatorPtr!=NULL&&orxonox_cast<WorldEntity*>(creatorPtr))
156                {
157                    scaleFactor *= getBiggestScale(((WorldEntity*) creatorPtr)->getScale3D());
158                    creatorPtr = creatorPtr->getCreator();
159                }
160                COUT(0) << "name: " << this->meshSrc_ << "scaleFactor: " << scaleFactor << ", volume: " << volume << endl;
161*/
162                COUT(4) << "Setting lodLevel for " << this->meshSrc_<< " with lodLevel_: " << this->lodLevel_ <<" and volume: "<< volume << ":" << std::endl;
163
164#if OGRE_VERSION >= 0x010700
165                Ogre::Mesh::LodValueList distList;
166#else
167                Ogre::Mesh::LodDistanceList distList;
168#endif
169
170                if( lodLevel_>0 )
171                {
172//                    float factor = scaleFactor*5/lodLevel_;
173                    float factor = pow(volume, 2.0f / 3.0f) * 15.0f / lodLevel_;
174
175                    COUT(4) << "LodLevel set with factor: " << factor << endl;
176
177                    distList.push_back(70.0f*factor);
178                    distList.push_back(140.0f*factor);
179                    distList.push_back(170.0f*factor);
180                    distList.push_back(200.0f*factor);
181                    distList.push_back(230.0f*factor);
182                    distList.push_back(250.0f*factor);
183                    distList.push_back(270.0f*factor);
184                    distList.push_back(290.0f*factor);
185                    distList.push_back(310.0f*factor);
186                    distList.push_back(330.0f*factor);
187                    while(distList.size()>this->numLodLevels_)
188                        distList.pop_back();
189
190
191                    //Generiert LOD-Levels
192                    this->mesh_.getEntity()->getMesh()->generateLodLevels(distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, this->lodReductionRate_);
193                }
194                else
195                {
196                    std::string what;
197                    if(lodLevel_>5)
198                        what = ">5";
199                    else
200                        what = "<0";
201
202                    COUT(4)<<"LodLevel not set because lodLevel("<<lodLevel_<<") was "<<what<<"." << endl;
203                }
204            }
205            else
206                COUT(4) << "LodLevel for " << this->meshSrc_ << " not set because is disabled." << endl;
207        }
208    }
209}
Note: See TracBrowser for help on using the repository browser.