RigsofRods
Soft-body Physics Simulation
MeshManager.cpp
Go to the documentation of this file.
1 /*
2 --------------------------------------------------------------------------------
3 This source file is part of SkyX.
4 Visit http://www.paradise-studios.net/products/skyx/
5 
6 Copyright (C) 2009-2012 Xavier Vergu�n Gonz�lez <xavyiy@gmail.com>
7 
8 This program is free software; you can redistribute it and/or modify it under
9 the terms of the GNU Lesser General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20 http://www.gnu.org/copyleft/lesser.txt.
21 --------------------------------------------------------------------------------
22 */
23 
24 #include "MeshManager.h"
25 
26 #include "SkyX.h"
27 
28 namespace SkyX
29 {
31  : mSkyX(s)
32  , mCreated(false)
33  , mMesh(static_cast<Ogre::Mesh*>(0))
34  , mSubMesh(0)
35  , mEntity(0)
36  , mVertexBuffer()
37  , mVertices(0)
38  , mIndexBuffer()
39  , mSceneNode(0)
40  , mSteps(70)
41  , mCircles(95)
42  , mUnderHorizonCircles(12)
43  , mUnderHorizonFading(true)
44  , mUnderHorizonFadingExponent(0.75)
45  , mUnderHorizonFadingMultiplier(2)
46  , mRadiusMultiplier(0.95f)
47  , mMaterialName("_NULL_")
48  {
49  }
50 
52  {
53  remove();
54  }
55 
57  {
58  if (!mCreated)
59  {
60  return;
61  }
62 
63  mSceneNode->detachAllObjects();
64  mSceneNode->getParentSceneNode()->removeAndDestroyChild(mSceneNode);
65  mSceneNode = 0;
66 
67  Ogre::MeshManager::getSingleton().remove("SkyXMesh");
68  mSkyX->getSceneManager()->destroyEntity(mEntity);
69 
70  mMesh.setNull();
71  mSubMesh = 0;
72  mEntity = 0;
73  mVertexBuffer.setNull();
74  mIndexBuffer.setNull();
75  mMaterialName = "_NULL_";
76 
77  delete [] mVertices;
78 
79  mCreated = false;
80  }
81 
83  {
84  if (mCreated)
85  {
86  return;
87  }
88 
89  // Create mesh and submesh
90  mMesh = Ogre::MeshManager::getSingleton().createManual("SkyXMesh",
91  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
92  mSubMesh = mMesh->createSubMesh();
93  mSubMesh->useSharedVertices = false;
94 
95  // Create mesh geometry
97 
98  // Build edge list
99  mMesh->buildEdgeList();
100 
101  // End mesh creation
102  mMesh->load();
103  mMesh->touch();
104 
105  mEntity = mSkyX->getSceneManager()->createEntity("SkyXMeshEnt", "SkyXMesh");
106  mEntity->setMaterialName(mMaterialName);
107  mEntity->setCastShadows(false);
108  mEntity->setRenderQueueGroup(mSkyX->getRenderQueueGroups().skydome);
109 
110  mSceneNode = mSkyX->getSceneManager()->getRootSceneNode()->createChildSceneNode();
111  mSceneNode->showBoundingBox(false);
112  mSceneNode->attachObject(mEntity);
113 
114  mCreated = true;
115  }
116 
117  void MeshManager::updateGeometry(Ogre::Camera* cam)
118  {
119  if (!mCreated)
120  {
121  return;
122  }
123 
124  float Radius = getSkydomeRadius(cam);
125 
126  mVertices[0].x = 0; mVertices[0].z = 0; mVertices[0].y = Radius;
127  mVertices[0].nx = 0; mVertices[0].nz = 0; mVertices[0].ny = 1;
128  mVertices[0].u = 4; mVertices[0].v = 4;
129  mVertices[0].o = 1;
130 
131  float AngleStep = (Ogre::Math::PI/2) / (mCircles-mUnderHorizonCircles);
132 
133  float r, uvr, c, s, h;
134  float currentPhiAngle, currentTethaAngle;
135  int x, y;
136 
137  // Above-horizon
138  for(y=0;y<mCircles-mUnderHorizonCircles;y++)
139  {
140  currentTethaAngle = Ogre::Math::PI/2 - AngleStep*(y+1);
141 
142  r = Ogre::Math::Cos(currentTethaAngle);
143  h = Ogre::Math::Sin(currentTethaAngle);
144 
145  uvr = static_cast<float>(y+1)/(mCircles-mUnderHorizonCircles);
146 
147  for(x=0;x<mSteps;x++)
148  {
149  currentPhiAngle = Ogre::Math::TWO_PI * x / mSteps;
150 
151  c = Ogre::Math::Cos(currentPhiAngle) * r;
152  s = Ogre::Math::Sin(currentPhiAngle) * r;
153 
154  mVertices[1+y*mSteps + x].x = c * Radius;
155  mVertices[1+y*mSteps + x].z = s * Radius;
156  mVertices[1+y*mSteps + x].y = h * Radius;
157 
158  mVertices[1+y*mSteps + x].nx = c;
159  mVertices[1+y*mSteps + x].nz = s;
160  mVertices[1+y*mSteps + x].ny = h;
161 
162  mVertices[1+y*mSteps + x].u = (1 + c*uvr/r)*4;
163  mVertices[1+y*mSteps + x].v = (1 + s*uvr/r)*4;
164 
165  mVertices[1+y*mSteps + x].o = 1;
166  }
167  }
168 
169  float op; // Opacity
170 
171  // Under-horizon
173  {
174  currentTethaAngle = Ogre::Math::PI/2 - AngleStep*(y+1);
175 
176  r = Ogre::Math::Cos(currentTethaAngle);
177  h = Ogre::Math::Sin(currentTethaAngle);
178 
179  uvr = static_cast<float>(y+1)/(mCircles-mUnderHorizonCircles);
180 
181  op = Ogre::Math::Clamp<Ogre::Real>(Ogre::Math::Pow(static_cast<Ogre::Real>(mCircles-y-1) / mUnderHorizonCircles, mUnderHorizonFadingExponent)*mUnderHorizonFadingMultiplier, 0, 1);
182 
183  for(x=0;x<mSteps;x++)
184  {
185  currentPhiAngle = Ogre::Math::TWO_PI * x / mSteps;
186 
187  c = Ogre::Math::Cos(currentPhiAngle) * r;
188  s = Ogre::Math::Sin(currentPhiAngle) * r;
189 
190  mVertices[1+y*mSteps + x].x = c * Radius;
191  mVertices[1+y*mSteps + x].z = s * Radius;
192  mVertices[1+y*mSteps + x].y = h * Radius;
193 
194  mVertices[1+y*mSteps + x].nx = c;
195  mVertices[1+y*mSteps + x].nz = s;
196  mVertices[1+y*mSteps + x].ny = h;
197 
198  mVertices[1+y*mSteps + x].u = (1 + c*uvr/r)*4;
199  mVertices[1+y*mSteps + x].v = (1 + s*uvr/r)*4;
200 
201  mVertices[1+y*mSteps + x].o = op;
202  }
203  }
204 
205  // Update data
206  mVertexBuffer->
207  writeData(0,
208  mVertexBuffer->getSizeInBytes(),
209  mVertices,
210  true);
211 
212  // Update bounds
213  Ogre::AxisAlignedBox meshBounds =
214  Ogre::AxisAlignedBox(-Radius, 0, -Radius,
215  Radius, Radius, Radius);
216 
217  mMesh->_setBounds(meshBounds);
218  mSceneNode->_updateBounds();
219  }
220 
222  {
223  int numVertices = mSteps * mCircles + 1;
224  int numEle = 6 * mSteps * (mCircles-1) + 3 * mSteps;
225 
226  // Vertex buffers
227  mSubMesh->vertexData = new Ogre::VertexData();
228  mSubMesh->vertexData->vertexStart = 0;
229  mSubMesh->vertexData->vertexCount = numVertices;
230 
231  Ogre::VertexDeclaration* vdecl = mSubMesh->vertexData->vertexDeclaration;
232  Ogre::VertexBufferBinding* vbind = mSubMesh->vertexData->vertexBufferBinding;
233 
234  size_t offset = 0;
235  vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
236  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
237  vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES, 0);
238  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
239  vdecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 1);
240  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
241  vdecl->addElement(0, offset, Ogre::VET_FLOAT1, Ogre::VES_TEXTURE_COORDINATES, 2);
242 
243  mVertexBuffer = Ogre::HardwareBufferManager::getSingleton().
244  createVertexBuffer(sizeof(VERTEX),
245  numVertices,
246  Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
247 
248  vbind->setBinding(0, mVertexBuffer);
249 
250  unsigned short *indexbuffer = new unsigned short[numEle];
251 
252  for (int k = 0; k < mSteps; k++)
253  {
254  indexbuffer[k*3] = 0;
255  indexbuffer[k*3+1] = k+1;
256 
257  if (k != mSteps-1)
258  {
259  indexbuffer[k*3+2] = k+2;
260  }
261  else
262  {
263  indexbuffer[k*3+2] = 1;
264  }
265  }
266 
267  unsigned short *twoface;
268 
269  for(int y=0; y<mCircles-1; y++)
270  {
271  for(int x=0; x<mSteps; x++)
272  {
273  twoface = indexbuffer + (y*mSteps+x)*6 + 3 * mSteps;
274 
275  int p0 = 1+y * mSteps + x ;
276  int p1 = 1+y * mSteps + x + 1 ;
277  int p2 = 1+(y+1)* mSteps + x ;
278  int p3 = 1+(y+1)* mSteps + x + 1 ;
279 
280  if (x == mSteps-1)
281  {
282  p1 -= x+1;
283  p3 -= x+1;
284  }
285 
286  // First triangle
287  twoface[2]=p0;
288  twoface[1]=p1;
289  twoface[0]=p2;
290 
291  // Second triangle
292  twoface[5]=p1;
293  twoface[4]=p3;
294  twoface[3]=p2;
295  }
296  }
297 
298  // Prepare buffer for indices
299  mIndexBuffer =
300  Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
301  Ogre::HardwareIndexBuffer::IT_16BIT,
302  numEle,
303  Ogre::HardwareBuffer::HBU_STATIC, true);
304 
305  mIndexBuffer->
306  writeData(0,
307  mIndexBuffer->getSizeInBytes(),
308  indexbuffer,
309  true);
310 
311  delete []indexbuffer;
312 
313  // Set index buffer for this submesh
314  mSubMesh->indexData->indexBuffer = mIndexBuffer;
315  mSubMesh->indexData->indexStart = 0;
316  mSubMesh->indexData->indexCount = numEle;
317 
318  // Create our internal buffer for manipulations
319  mVertices = new VERTEX[1+mSteps * mCircles];
320  }
321 
322  void MeshManager::setGeometryParameters(const int &Steps, const int &Circles)
323  {
324  mSteps = Steps;
325  mCircles = Circles;
326 
327  if (mCreated)
328  {
329  remove();
330  create();
331  }
332  }
333 
334  void MeshManager::setUnderHorizonParams(const int& UnderHorizonCircles, const bool& UnderHorizonFading, const Ogre::Real& UnderHorizonFadingExponent, const Ogre::Real& UnderHorizonFadingMultiplier)
335  {
336  bool needToRecreate = (mUnderHorizonCircles != UnderHorizonCircles);
337 
338  mUnderHorizonCircles = UnderHorizonCircles;
339  mUnderHorizonFading = UnderHorizonFading;
340  mUnderHorizonFadingExponent = UnderHorizonFadingExponent;
341  mUnderHorizonFadingMultiplier = UnderHorizonFadingMultiplier;
342 
343  if (needToRecreate)
344  {
345  remove();
346  create();
347  }
348  }
349 
350  void MeshManager::setMaterialName(const Ogre::String& MaterialName)
351  {
352  mMaterialName = MaterialName;
353 
354  if (mCreated)
355  {
356  mEntity->setMaterialName(MaterialName);
357  }
358  }
359 
360  const float MeshManager::getSkydomeRadius(Ogre::Camera* c) const
361  {
362  float cameraFarClipDistance = c->getFarClipDistance();
363 
364  if (!cameraFarClipDistance)
365  {
366  cameraFarClipDistance = mSkyX->getInfiniteCameraFarClipDistance();
367  }
368 
369  return cameraFarClipDistance*mRadiusMultiplier;
370  }
371 }
SkyX::MeshManager::setMaterialName
void setMaterialName(const Ogre::String &MaterialName)
Set mesh material.
Definition: MeshManager.cpp:350
SkyX::MeshManager::VERTEX::nx
float nx
Definition: MeshManager.h:43
SkyX::SkyX::getRenderQueueGroups
const RenderQueueGroups & getRenderQueueGroups() const
Get render queue groups.
Definition: SkyX.h:257
SkyX::MeshManager::_createGeometry
void _createGeometry()
Create geometry.
Definition: MeshManager.cpp:221
y
float y
Definition: (ValueTypes) quaternion.h:6
SkyX::MeshManager::setGeometryParameters
void setGeometryParameters(const int &Steps, const int &Circles)
Set geometry parameters.
Definition: MeshManager.cpp:322
SkyX::MeshManager::VERTEX::u
float u
Definition: MeshManager.h:45
SkyX::MeshManager::MeshManager
MeshManager(SkyX *s)
Constructor.
Definition: MeshManager.cpp:30
SkyX::MeshManager::VERTEX::nz
float nz
Definition: MeshManager.h:43
SkyX::MeshManager::VERTEX::z
float z
Definition: MeshManager.h:41
SkyX::MeshManager::mUnderHorizonCircles
int mUnderHorizonCircles
Under-horizon rendering.
Definition: MeshManager.h:254
SkyX::SkyX::getSceneManager
Ogre::SceneManager * getSceneManager()
Get scene manager.
Definition: SkyX.h:315
SkyX
Definition: AtmosphereManager.cpp:30
SkyX::MeshManager::mEntity
Ogre::Entity * mEntity
Ogre::Entity pointer.
Definition: MeshManager.h:238
SkyX::MeshManager::mMaterialName
Ogre::String mMaterialName
Material name.
Definition: MeshManager.h:269
SkyX::MeshManager::mVertices
VERTEX * mVertices
Vertices.
Definition: MeshManager.h:246
SkyX::MeshManager::getSkydomeRadius
const float getSkydomeRadius(Ogre::Camera *c) const
Get skydome radius.
Definition: MeshManager.cpp:360
SkyX::MeshManager::mRadiusMultiplier
Ogre::Real mRadiusMultiplier
Radius multiplier.
Definition: MeshManager.h:263
SkyX::MeshManager::VERTEX::ny
float ny
Definition: MeshManager.h:43
SkyX::SkyX::getInfiniteCameraFarClipDistance
const Ogre::Real & getInfiniteCameraFarClipDistance() const
Get infinite cmaera far clip distance.
Definition: SkyX.h:307
SkyX::MeshManager::mUnderHorizonFading
bool mUnderHorizonFading
Under-horizon fading.
Definition: MeshManager.h:256
SkyX::MeshManager::~MeshManager
~MeshManager()
Destructor.
Definition: MeshManager.cpp:51
SkyX::MeshManager::mUnderHorizonFadingExponent
Ogre::Real mUnderHorizonFadingExponent
Under-horizon exponent fading (1=linear fading)
Definition: MeshManager.h:258
SkyX.h
SkyX::MeshManager::VERTEX::v
float v
Definition: MeshManager.h:45
SkyX::MeshManager::mCircles
int mCircles
Circles.
Definition: MeshManager.h:249
SkyX::MeshManager::VERTEX::y
float y
Definition: MeshManager.h:41
SkyX::MeshManager::updateGeometry
void updateGeometry(Ogre::Camera *cam)
Update geometry.
Definition: MeshManager.cpp:117
SkyX::MeshManager::mSubMesh
Ogre::SubMesh * mSubMesh
Ogre::Submesh pointer.
Definition: MeshManager.h:236
SkyX::MeshManager::mSteps
int mSteps
Steps.
Definition: MeshManager.h:251
SkyX::MeshManager::VERTEX
Vertex struct.
Definition: MeshManager.h:38
SkyX::MeshManager::remove
void remove()
Remove all resources.
Definition: MeshManager.cpp:56
SkyX::MeshManager::setUnderHorizonParams
void setUnderHorizonParams(const int &UnderHorizonCircles=15, const bool &UnderHorizonFading=true, const Ogre::Real &UnderHorizonFadingExponent=1, const Ogre::Real &UnderHorizonFadingMultiplier=2)
Set under-horizon rendering params.
Definition: MeshManager.cpp:334
SkyX::MeshManager::mUnderHorizonFadingMultiplier
Ogre::Real mUnderHorizonFadingMultiplier
Under-horizon fading multiplier: opacity = saturate(pow(opacity,fading_exp)*fading_multiplier)
Definition: MeshManager.h:260
SkyX::MeshManager::mSceneNode
Ogre::SceneNode * mSceneNode
Ogre::SceneNode pointer.
Definition: MeshManager.h:266
SkyX::MeshManager::mVertexBuffer
Ogre::HardwareVertexBufferSharedPtr mVertexBuffer
Vertex buffer.
Definition: MeshManager.h:241
Ogre
Definition: ExtinguishableFireAffector.cpp:35
SkyX::SkyX::RenderQueueGroups::skydome
Ogre::uint8 skydome
Skydome render queue group (Note: Moon = skydome_render_queue+1)
Definition: SkyX.h:80
SkyX::MeshManager::mCreated
bool mCreated
Has been create() already called?
Definition: MeshManager.h:231
SkyX::MeshManager::mSkyX
SkyX * mSkyX
Main SkyX pointer.
Definition: MeshManager.h:272
SkyX::MeshManager::VERTEX::x
float x
Definition: MeshManager.h:41
MeshManager.h
SkyX::MeshManager::create
void create()
Create our water mesh, geometry, entity, etc...
Definition: MeshManager.cpp:82
x
float x
Definition: (ValueTypes) quaternion.h:5
SkyX::MeshManager::mMesh
Ogre::MeshPtr mMesh
Ogre::MeshPtr.
Definition: MeshManager.h:234
SkyX::MeshManager::mIndexBuffer
Ogre::HardwareIndexBufferSharedPtr mIndexBuffer
Index buffer.
Definition: MeshManager.h:243
SkyX::MeshManager::VERTEX::o
float o
Definition: MeshManager.h:47