RigsofRods
Soft-body Physics Simulation
GeometryManager.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 "GeometryManager.h"
25 
26 #include "VClouds.h"
27 
28 namespace SkyX { namespace VClouds
29 {
30 
32  : mVClouds(vc)
33  , mCreated(false)
34  , mHeight(Ogre::Vector2())
35  , mRadius(0)
36  , mAlpha(0)
37  , mBeta(0)
38  , mPhi(0)
39  , mNumberOfBlocks(0)
40  , mNa(0), mNb(0), mNc(0)
41  , mA(0), mB(0), mC(0)
42  , mWorldOffset(Ogre::Vector2(0,0))
43  , mCurrentDistance(Ogre::Vector3(0,0,0))
44  {
45  }
46 
48  {
49  remove();
50  }
51 
52  void GeometryManager::create(const Ogre::Vector2& Height, const float& Radius,
53  const Ogre::Radian& Alpha, const Ogre::Radian& Beta,
54  const int& NumberOfBlocks, const int& Na, const int& Nb, const int& Nc)
55  {
56  remove();
57 
58  mHeight = Height;
59  mRadius = Radius;
60  mAlpha = Alpha;
61  mBeta = Beta;
62  mPhi = Ogre::Math::TWO_PI / NumberOfBlocks;
63  mNumberOfBlocks = NumberOfBlocks;
64  mNa = Na; mNb = Nb; mNc = Nc;
65 
66  mSceneNode = mVClouds->getSceneManager()->getRootSceneNode()->createChildSceneNode();
68 
69  mCreated = true;
70  }
71 
73  {
74  if (!mCreated)
75  {
76  return;
77  }
78 
79  mSceneNode->detachAllObjects();
80  mSceneNode->getParentSceneNode()->removeAndDestroyChild(mSceneNode);
81  mSceneNode = 0;
82 
83  for (int k = 0; k < mNumberOfBlocks; k++)
84  {
85  delete mGeometryBlocks.at(k);
86  mGeometryBlocks.at(k) = 0;
87  }
88 
89  mGeometryBlocks.clear();
90 
91  mCreated = false;
92  }
93 
94  void GeometryManager::update(const Ogre::Real& timeSinceLastFrame)
95  {
96  if (!mCreated)
97  {
98  return;
99  }
100 
101  mWorldOffset += mVClouds->getWindDirectionV2() * mVClouds->getWindSpeed() * timeSinceLastFrame;
102  }
103 
104  void GeometryManager::updateGeometry(Ogre::Camera* c, const Ogre::Real& timeSinceLastCameraFrame)
105  {
106  if (!mCreated)
107  {
108  return;
109  }
110 
111  mSceneNode->setPosition(mVClouds->getCamera()->getDerivedPosition().x, mHeight.x, mVClouds->getCamera()->getDerivedPosition().z);
112  mSceneNode->_update(false, false);
113 
114  _updateGeometry(c, timeSinceLastCameraFrame);
115  }
116 
117  void GeometryManager::_setMaterialName(const Ogre::String& mn)
118  {
119  for(Ogre::uint32 k = 0; k < mGeometryBlocks.size(); k++)
120  {
121  mGeometryBlocks.at(k)->getEntity()->setMaterialName(mn);
122  }
123  }
124 
125  void GeometryManager::_updateRenderQueueGroup(const Ogre::uint8& rqg)
126  {
127  for(Ogre::uint32 k = 0; k < mGeometryBlocks.size(); k++)
128  {
129  mGeometryBlocks.at(k)->getEntity()->setRenderQueueGroup(rqg);
130  }
131  }
132 
134  {
135  mA = mHeight.y / Ogre::Math::Cos(Ogre::Math::PI/2-mBeta.valueRadians());
136  mB = mHeight.y / Ogre::Math::Cos(Ogre::Math::PI/2-mAlpha.valueRadians());
137  mC = mRadius;
138 
139  for (int k = 0; k < mNumberOfBlocks; k++)
140  {
142  mGeometryBlocks.at(k)->create();
143  // Each geometry block must be in a different scene node, See: GeometryBlock::isInFrustum(Ogre::Camera *c)
144  Ogre::SceneNode *sn = mSceneNode->createChildSceneNode();
145  sn->attachObject(mGeometryBlocks.at(k)->getEntity());
146  }
147  }
148 
149  void GeometryManager::_updateGeometry(Ogre::Camera* c, const Ogre::Real& timeSinceLastFrame)
150  {
151  // Look for current camera data
152  std::vector<VClouds::CameraData>& camerasData = mVClouds->_getCamerasData();
153  std::vector<VClouds::CameraData>::iterator currentCameraDataIt;
154 
155  for (currentCameraDataIt = camerasData.begin(); currentCameraDataIt != camerasData.end(); currentCameraDataIt++)
156  {
157  if ((*currentCameraDataIt).camera == c)
158  {
159  break;
160  }
161  }
162 
163  std::vector<VClouds::CameraData>::reference currentCameraData = (*currentCameraDataIt);
164 
165  // Calculate wind offset
166  Ogre::Vector2 CameraDirection = Ogre::Vector2(c->getDerivedDirection().x, c->getDerivedDirection().z);
167  float offset = - CameraDirection.dotProduct(mVClouds->getWindDirectionV2()) * mVClouds->getWindSpeed() * timeSinceLastFrame;
168 
169  // Calculate camera offset
170  Ogre::Vector2 CameraOffset = Ogre::Vector2(c->getDerivedPosition().x - currentCameraData.lastPosition.x, c->getDerivedPosition().z - currentCameraData.lastPosition.z);
171  offset -= CameraOffset.dotProduct(CameraDirection);
172 
173  // Update camera data
174  currentCameraData.cameraOffset += CameraOffset;
175  currentCameraData.lastPosition = c->getDerivedPosition();
176 
177  // Update geometry displacement
178  currentCameraData.geometryDisplacement += Ogre::Vector3(offset);
179 
180  if (currentCameraData.geometryDisplacement.z < 0 || currentCameraData.geometryDisplacement.z > (mC-mB)/mNc)
181  {
182  currentCameraData.geometryDisplacement.z -= ((mC-mB)/mNc)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.z)/((mC-mB)/mNc));
183  }
184 
185  if (currentCameraData.geometryDisplacement.y < 0 || currentCameraData.geometryDisplacement.y > (mB-mA)/mNb)
186  {
187  currentCameraData.geometryDisplacement.y -= ((mB-mA)/mNb)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.y)/((mB-mA)/mNb));
188  }
189 
190  if (currentCameraData.geometryDisplacement.x < 0 || currentCameraData.geometryDisplacement.x > mA/mNa)
191  {
192  currentCameraData.geometryDisplacement.x -= (mA/mNa)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.x)/(mA/mNa));
193  }
194 
195  // Check under/over cloud rendering
196  mCurrentDistance = c->getDerivedPosition()-mSceneNode->_getDerivedPosition();
197 
198  for (int k = 0; k < mNumberOfBlocks; k++)
199  {
200  mGeometryBlocks.at(k)->setWorldOffset(mWorldOffset + currentCameraData.cameraOffset);
201  mGeometryBlocks.at(k)->updateGeometry(c, currentCameraData.geometryDisplacement, mCurrentDistance);
202  }
203  }
204 }}
SkyX::VClouds::GeometryManager::mB
float mB
Definition: GeometryManager.h:148
VClouds.h
SkyX::VClouds::GeometryManager::mAlpha
Ogre::Radian mAlpha
Angles.
Definition: GeometryManager.h:138
SkyX::VClouds::GeometryManager::_updateRenderQueueGroup
void _updateRenderQueueGroup(const Ogre::uint8 &rqg)
Update render queue group.
Definition: GeometryManager.cpp:125
SkyX::VClouds::GeometryManager::mCurrentDistance
Ogre::Vector3 mCurrentDistance
Current camera-clouds distance.
Definition: GeometryManager.h:160
GeometryManager.h
SkyX::VClouds::GeometryManager::mGeometryBlocks
std::vector< GeometryBlock * > mGeometryBlocks
Geometry blocks.
Definition: GeometryManager.h:154
SkyX::VClouds::VClouds::_getCamerasData
std::vector< CameraData > & _getCamerasData()
Get cameras data.
Definition: VClouds.h:500
SkyX::VClouds::GeometryManager::mHeight
Ogre::Vector2 mHeight
Height: x = Altitude over the camera, y: Field height (both in world coordinates)
Definition: GeometryManager.h:136
SkyX
Definition: AtmosphereManager.cpp:30
SkyX::VClouds::GeometryManager::create
void create(const Ogre::Vector2 &Height, const float &Radius, const Ogre::Radian &Alpha, const Ogre::Radian &Beta, const int &NumberOfBlocks, const int &Na, const int &Nb, const int &Nc)
Create.
Definition: GeometryManager.cpp:52
SkyX::VClouds::GeometryManager::GeometryManager
GeometryManager(VClouds *vc)
Constructor.
Definition: GeometryManager.cpp:31
SkyX::VClouds::GeometryManager::mNb
int mNb
Definition: GeometryManager.h:146
SkyX::VClouds::GeometryManager::mA
float mA
A, B and C radius.
Definition: GeometryManager.h:148
SkyX::VClouds::GeometryManager::~GeometryManager
~GeometryManager()
Destructor.
Definition: GeometryManager.cpp:47
SkyX::VClouds::GeometryManager::mNa
int mNa
Number of slices per geometry zone.
Definition: GeometryManager.h:146
SkyX::VClouds::GeometryManager::update
void update(const Ogre::Real &timeSinceLastFrame)
Update, to be invoked per frame.
Definition: GeometryManager.cpp:94
SkyX::VClouds::GeometryManager::mSceneNode
Ogre::SceneNode * mSceneNode
Scene node.
Definition: GeometryManager.h:157
SkyX::VClouds::GeometryManager::mNc
int mNc
Definition: GeometryManager.h:146
SkyX::VClouds::GeometryManager::_createGeometry
void _createGeometry()
Create geometry.
Definition: GeometryManager.cpp:133
SkyX::VClouds::GeometryManager::mBeta
Ogre::Radian mBeta
Definition: GeometryManager.h:138
SkyX::VClouds::VClouds
Definition: VClouds.h:35
SkyX::VClouds::GeometryManager::remove
void remove()
Remove.
Definition: GeometryManager.cpp:72
SkyX::VClouds::GeometryManager::mCreated
bool mCreated
Has been create() already called?
Definition: GeometryManager.h:133
SkyX::VClouds::GeometryManager::mNumberOfBlocks
int mNumberOfBlocks
Number of blocks.
Definition: GeometryManager.h:144
SkyX::VClouds::GeometryManager::mC
float mC
Definition: GeometryManager.h:148
SkyX::VClouds::GeometryManager::mVClouds
VClouds * mVClouds
VClouds pointer.
Definition: GeometryManager.h:163
SkyX::VClouds::VClouds::getCamera
Ogre::Camera * getCamera()
Get current rendering camera.
Definition: VClouds.h:467
SkyX::VClouds::GeometryManager::mWorldOffset
Ogre::Vector2 mWorldOffset
World coords offset.
Definition: GeometryManager.h:151
Ogre
Definition: ExtinguishableFireAffector.cpp:35
SkyX::VClouds::GeometryManager::updateGeometry
void updateGeometry(Ogre::Camera *c, const Ogre::Real &timeSinceLastCameraFrame)
Update geoemtry.
Definition: GeometryManager.cpp:104
SkyX::VClouds::GeometryBlock
Definition: GeometryBlock.h:33
SkyX::VClouds::VClouds::getWindSpeed
const float & getWindSpeed() const
Get wind speed.
Definition: VClouds.h:300
SkyX::VClouds::GeometryManager::mRadius
float mRadius
Radius.
Definition: GeometryManager.h:140
SkyX::VClouds::VClouds::getWindDirectionV2
const Ogre::Vector2 getWindDirectionV2() const
Get wind direction as a Vector2.
Definition: VClouds.h:284
SkyX::VClouds::GeometryManager::mPhi
Ogre::Radian mPhi
Azimutal angle per block.
Definition: GeometryManager.h:142
SkyX::VClouds::VClouds::getSceneManager
Ogre::SceneManager * getSceneManager()
Get scene manager.
Definition: VClouds.h:459
SkyX::VClouds::GeometryManager::_setMaterialName
void _setMaterialName(const Ogre::String &mn)
Set material name.
Definition: GeometryManager.cpp:117
SkyX::VClouds::GeometryManager::_updateGeometry
void _updateGeometry(Ogre::Camera *c, const Ogre::Real &timeSinceLastFrame)
Update geometry.
Definition: GeometryManager.cpp:149