Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/graphics/Model.cc @ 9799

Last change on this file since 9799 was 9675, checked in by landauf, 11 years ago

merged branch 'libs' back to trunk. orxonox now compiles and runs with ogre 1.8 and it compiles (but doesn't run) with cegui 0.8

  • Property svn:eol-style set to native
File size: 7.5 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#include <OgreProgressiveMesh.h>
33
34#include "core/CoreIncludes.h"
35#include "core/config/ConfigValueIncludes.h"
36#include "core/GameMode.h"
37#include "core/XMLPort.h"
38#include "Scene.h"
39#include "graphics/MeshLodInformation.h"
40#include "Level.h"
41
42namespace orxonox
43{
44    RegisterClass(Model);
45
46    Model::Model(Context* context) :
47        StaticEntity(context), bCastShadows_(true), lodLevel_(5), bLodEnabled_(true), numLodLevels_(10), lodReductionRate_(.15f)
48    {
49        RegisterObject(Model);
50
51        this->setConfigValues();
52        this->registerVariables();
53    }
54
55    Model::~Model()
56    {
57        if (this->isInitialized() && this->mesh_.getEntity())
58            this->detachOgreObject(this->mesh_.getEntity());
59    }
60
61    void Model::setConfigValues()
62    {
63        SetConfigValueExternal(bGlobalEnableLod_, "GraphicsSettings", "enableMeshLoD", true)
64            .description("Enable level of detail for models");
65    }
66
67    void Model::XMLPort(Element& xmlelement, XMLPort::Mode mode)
68    {
69        SUPER(Model, XMLPort, xmlelement, mode);
70
71        XMLPortParam(Model, "lodLevel", setLodLevel, getLodLevel, xmlelement, mode);
72
73        XMLPortParam(Model, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
74        XMLPortParam(Model, "shadow", setCastShadows, getCastShadows, xmlelement, mode).defaultValues(true);
75    }
76
77    void Model::registerVariables()
78    {
79        registerVariable(this->meshSrc_,    VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedMesh));
80        registerVariable(this->bCastShadows_, VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedShadows));
81    }
82
83    float Model::getBiggestScale(Vector3 scale3d)
84    {
85        float scaleFactor = scale3d.x;
86        if(scale3d.y>scaleFactor)
87            scaleFactor = scale3d.y;
88        if(scale3d.z>scaleFactor)
89            scaleFactor = scale3d.z;
90        return scaleFactor;
91    }
92
93    void Model::changedMesh()
94    {
95        if (GameMode::showsGraphics())
96        {
97            if (this->mesh_.getEntity())
98                this->detachOgreObject(this->mesh_.getEntity());
99
100            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
101
102            if (this->mesh_.getEntity())
103            {
104                this->attachOgreObject(this->mesh_.getEntity());
105                this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
106                this->mesh_.setVisible(this->isVisible());
107
108                if (this->bGlobalEnableLod_)
109                    this->enableLod();
110            }
111        }
112    }
113
114    void Model::changedShadows()
115    {
116        this->mesh_.setCastShadows(this->bCastShadows_);
117    }
118
119    void Model::changedVisibility()
120    {
121        SUPER(Model, changedVisibility);
122
123        this->mesh_.setVisible(this->isVisible());
124    }
125
126    void Model::enableLod()
127    {
128        //LOD
129        if( this->mesh_.getEntity()->getMesh()->getNumLodLevels()==1 )
130        {
131            Level* level = this->getLevel();
132
133            assert( level != 0 );
134
135            MeshLodInformation* lodInfo = level->getLodInfo(this->meshSrc_);
136            if( lodInfo )
137            {
138                setLodLevel(lodInfo->getLodLevel());
139                this->bLodEnabled_ = lodInfo->getEnabled();
140                this->numLodLevels_ = lodInfo->getNumLevels();
141                this->lodReductionRate_ = lodInfo->getReductionRate();
142            }
143            if( this->numLodLevels_>10 )
144            {
145                orxout(internal_warning, context::lod) << "More than 10 LoD levels requested. Creating only 10." << endl;
146                this->numLodLevels_ = 10;
147            }
148            if( this->bLodEnabled_ )
149            {
150                float volume = this->mesh_.getEntity()->getBoundingBox().volume();
151/*
152                float scaleFactor = 1;
153
154                BaseObject* creatorPtr = this;
155
156                while(creatorPtr!=NULL&&orxonox_cast<WorldEntity*>(creatorPtr))
157                {
158                    scaleFactor *= getBiggestScale(((WorldEntity*) creatorPtr)->getScale3D());
159                    creatorPtr = creatorPtr->getCreator();
160                }
161                orxout() << "name: " << this->meshSrc_ << "scaleFactor: " << scaleFactor << ", volume: " << volume << endl;
162*/
163                orxout(verbose, context::lod) << "Setting lodLevel for " << this->meshSrc_<< " with lodLevel_: " << this->lodLevel_ <<" and volume: "<< volume << ":" << endl;
164
165#if OGRE_VERSION >= 0x010800
166                Ogre::ProgressiveMesh::LodValueList distList;
167#elif OGRE_VERSION >= 0x010700
168                Ogre::Mesh::LodValueList distList;
169#else
170                Ogre::Mesh::LodDistanceList distList;
171#endif
172
173                if( lodLevel_>0 )
174                {
175//                    float factor = scaleFactor*5/lodLevel_;
176                    float factor = pow(volume, 2.0f / 3.0f) * 15.0f / lodLevel_;
177
178                    orxout(verbose, context::lod) << "LodLevel set with factor: " << factor << endl;
179
180                    distList.push_back(70.0f*factor);
181                    distList.push_back(140.0f*factor);
182                    distList.push_back(170.0f*factor);
183                    distList.push_back(200.0f*factor);
184                    distList.push_back(230.0f*factor);
185                    distList.push_back(250.0f*factor);
186                    distList.push_back(270.0f*factor);
187                    distList.push_back(290.0f*factor);
188                    distList.push_back(310.0f*factor);
189                    distList.push_back(330.0f*factor);
190                    while(distList.size()>this->numLodLevels_)
191                        distList.pop_back();
192
193
194                    //Generiert LOD-Levels
195#if OGRE_VERSION >= 0x010800
196                    Ogre::ProgressiveMesh::generateLodLevels(this->mesh_.getEntity()->getMesh().get(), distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL,
197                        this->lodReductionRate_);
198#else
199                    this->mesh_.getEntity()->getMesh()->generateLodLevels(distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, this->lodReductionRate_);
200#endif
201                }
202                else
203                {
204                    std::string what;
205                    if(lodLevel_>5)
206                        what = ">5";
207                    else
208                        what = "<0";
209
210                    orxout(verbose, context::lod) << "LodLevel not set because lodLevel(" << lodLevel_ << ") was " << what << "." << endl;
211                }
212            }
213            else
214                orxout(verbose, context::lod) << "LodLevel for " << this->meshSrc_ << " not set because is disabled." << endl;
215        }
216    }
217}
Note: See TracBrowser for help on using the repository browser.