Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
MeshObject.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5
6 For more information, see http://www.rigsofrods.org/
7
8 Rigs of Rods is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 3, as
10 published by the Free Software Foundation.
11
12 Rigs of Rods 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 Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
19*/
20
24
25#include "MeshObject.h"
26
27#include "Actor.h"
28#include "Application.h"
29#include "GfxScene.h"
30#include "Terrain.h"
31
32#include <OgreMeshLodGenerator.h>
33#include <OgreLodConfig.h>
34
35using namespace Ogre;
36using namespace RoR;
37
38MeshObject::MeshObject(Ogre::String meshName, Ogre::String entityRG, Ogre::String entityName, Ogre::SceneNode *m_scene_node)
39 : m_scene_node(m_scene_node), m_entity(nullptr), m_cast_shadows(true)
40{
41 this->createEntity(meshName, entityRG, entityName);
42}
43
44void MeshObject::setMaterialName(Ogre::String m)
45{
46 if (m_entity)
47 {
48 m_entity->setMaterialName(m);
49 }
50}
51
53{
55 if (m_scene_node && m_scene_node->numAttachedObjects())
56 {
57 m_scene_node->getAttachedObject(0)->setCastShadows(b);
58 }
59}
60
62{
63 // Workaround: if the scenenode is not used (entity not attached) for some reason, try hiding the entity directly.
64 if (m_scene_node && m_scene_node->getAttachedObjects().size() > 0)
65 m_scene_node->setVisible(b);
66 else if (m_entity)
67 m_entity->setVisible(b);
68}
69
70void MeshObject::createEntity(Ogre::String meshName, Ogre::String entityRG, Ogre::String entityName)
71{
72 if (!m_scene_node)
73 return;
74
75 try
76 {
77 m_mesh = Ogre::MeshManager::getSingleton().getByName(meshName, entityRG);
78
79 // Mesh hasn't been loaded yet
80 if (m_mesh == nullptr)
81 {
82 m_mesh = Ogre::MeshManager::getSingleton().load(meshName, entityRG);
83
84 // important: you need to add the LODs before creating the entity
85 // now find possible LODs, needs to be done before calling createEntity()
86 String basename, ext;
87 StringUtil::splitBaseFilename(meshName, basename, ext);
88
89 bool lod_available = false;
90 Ogre::LodConfig config(m_mesh);
91
92 // the classic LODs
93 FileInfoListPtr files = ResourceGroupManager::getSingleton().findResourceFileInfo(entityRG, basename + "_lod*.mesh");
94 for (FileInfoList::iterator iterFiles = files->begin(); iterFiles != files->end(); ++iterFiles)
95 {
96 String format = basename + "_lod%d.mesh";
97 int i = -1;
98 int r = sscanf(iterFiles->filename.c_str(), format.c_str(), &i);
99
100 if (r <= 0 || i < 0)
101 continue;
102
103 float distance = 3;
104
105 // we need to tune this according to our sightrange
107 {
108 // unlimited
109 if (i == 1)
110 distance = 200;
111 else if (i == 2)
112 distance = 600;
113 else if (i == 3)
114 distance = 2000;
115 else if (i == 4)
116 distance = 5000;
117 }
118 else
119 {
120 // limited
121 int sightrange = App::gfx_sight_range->getInt();
122 if (i == 1)
123 distance = std::max(20.0f, sightrange * 0.1f);
124 else if (i == 2)
125 distance = std::max(20.0f, sightrange * 0.2f);
126 else if (i == 3)
127 distance = std::max(20.0f, sightrange * 0.3f);
128 else if (i == 4)
129 distance = std::max(20.0f, sightrange * 0.4f);
130 }
131 config.createManualLodLevel(distance, iterFiles->filename);
132 lod_available = true;
133 }
134
135 // the custom LODs
136 FileInfoListPtr files2 = ResourceGroupManager::getSingleton().findResourceFileInfo(entityRG, basename + "_clod_*.mesh");
137 for (FileInfoList::iterator iterFiles = files2->begin(); iterFiles != files2->end(); ++iterFiles)
138 {
139 // and custom LODs
140 String format = basename + "_clod_%d.mesh";
141 int i = -1;
142 int r = sscanf(iterFiles->filename.c_str(), format.c_str(), &i);
143 if (r <= 0 || i < 0)
144 continue;
145
146 config.createManualLodLevel(i, iterFiles->filename);
147 lod_available = true;
148 }
149
150 if (lod_available)
151 Ogre::MeshLodGenerator::getSingleton().generateLodLevels(config);
152 else if (App::gfx_auto_lod->getBool())
153 Ogre::MeshLodGenerator::getSingleton().generateAutoconfiguredLodLevels(m_mesh);
154 }
155
156 // now create an entity around the mesh and attach it to the scene graph
157 m_entity = App::GetGfxScene()->GetSceneManager()->createEntity(entityName, meshName, entityRG);
158 m_entity->setCastShadows(m_cast_shadows);
159
160 m_scene_node->attachObject(m_entity);
161 m_scene_node->setVisible(true);
162 }
163 catch (Ogre::Exception &e)
164 {
165 RoR::LogFormat("[RoR] Error creating entity of mesh '%s' (group: '%s'), message: %s",
166 meshName.c_str(), entityRG.c_str(), e.getFullDescription().c_str());
167 return;
168 }
169}
Central state/object manager and communications hub.
Ogre::Entity * m_entity
Definition MeshObject.h:49
void setVisible(bool b)
void setCastShadows(bool b)
Ogre::SceneNode * m_scene_node
Definition MeshObject.h:48
MeshObject(Ogre::String meshName, Ogre::String entityRG, Ogre::String entityName, Ogre::SceneNode *sceneNode)
Ogre::MeshPtr m_mesh
Definition MeshObject.h:50
bool m_cast_shadows
Definition MeshObject.h:51
void createEntity(Ogre::String meshName, Ogre::String entityRG, Ogre::String entityName)
void setMaterialName(Ogre::String m)
int getInt() const
Definition CVar.h:97
Ogre::SceneManager * GetSceneManager()
Definition GfxScene.h:83
static const int UNLIMITED_SIGHTRANGE
Definition Terrain.h:44
CVar * gfx_sight_range
CVar * gfx_auto_lod
GfxScene * GetGfxScene()
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.