[2221] | 1 | |
---|
| 2 | /////////////////////////////////////////////////////////////////////////// |
---|
| 3 | // |
---|
| 4 | // Realistic rain real-time simulation program |
---|
| 5 | // |
---|
| 6 | // Pierre Rousseau |
---|
| 7 | // |
---|
| 8 | /////////////////////////////////////////////////////////////////////////// |
---|
| 9 | // |
---|
| 10 | // Light Handling |
---|
| 11 | // |
---|
| 12 | /////////////////////////////////////////////////////////////////////////// |
---|
| 13 | |
---|
| 14 | |
---|
| 15 | #include "RainLight.h" |
---|
| 16 | |
---|
| 17 | |
---|
| 18 | |
---|
| 19 | |
---|
| 20 | |
---|
| 21 | |
---|
| 22 | |
---|
| 23 | |
---|
| 24 | |
---|
| 25 | |
---|
| 26 | RainLight::RainLight(SceneManager *sceneMgr, int lightNumber, ColourValue col, Vector3 LightPos, float LightAttenuation) |
---|
| 27 | {String name; |
---|
| 28 | |
---|
| 29 | mSceneMgr = sceneMgr; |
---|
| 30 | |
---|
| 31 | Vector3 decalage_ampoule(-5.5, 38, 0); |
---|
| 32 | |
---|
| 33 | Entity *mStreetLight = mSceneMgr->createEntity("Street_light_" + StringConverter::toString(lightNumber), "lampadaire.mesh"); |
---|
| 34 | mStreetLight->setMaterialName("lampMat"); |
---|
| 35 | |
---|
| 36 | mConeNode = NULL; |
---|
| 37 | SceneNode *mStreetLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); |
---|
| 38 | mStreetLightNode->setPosition(LightPos); |
---|
| 39 | mStreetLightNode->setScale(0.8, 0.8, 0.8); |
---|
| 40 | mStreetLightNode->attachObject(mStreetLight); |
---|
| 41 | |
---|
| 42 | mLightNode = mStreetLightNode->createChildSceneNode(decalage_ampoule); |
---|
| 43 | |
---|
| 44 | name = "billboardSet_for_light" + StringConverter::toString(lightNumber); |
---|
| 45 | mBillboardSet = sceneMgr->createBillboardSet(name); |
---|
| 46 | mLightNode->attachObject(mBillboardSet); |
---|
| 47 | mBillboardSet->setMaterialName("Examples/Flare"); |
---|
| 48 | |
---|
| 49 | mBillboard = mBillboardSet->createBillboard(Vector3(0, 0, 0)); |
---|
| 50 | mBillboard->setDimensions(8, 8); |
---|
| 51 | mBillboard->setColour(col); |
---|
| 52 | |
---|
| 53 | mColour = col; |
---|
| 54 | mLightPos = mLightNode->getWorldPosition(); |
---|
| 55 | mLightDir = Vector3(-0.2, -1, 0).normalisedCopy(); |
---|
| 56 | mLightCutoff = 35; |
---|
| 57 | mLightAttenuation = LightAttenuation; |
---|
| 58 | } |
---|
| 59 | |
---|
| 60 | |
---|
| 61 | |
---|
| 62 | |
---|
| 63 | |
---|
| 64 | |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | void RainLight::animate() |
---|
| 68 | { |
---|
| 69 | static Vector3 pos; |
---|
| 70 | static Vector3 dir; |
---|
| 71 | |
---|
| 72 | if (isAnimated) |
---|
| 73 | { |
---|
| 74 | h1 += stepH1 / 10.0; |
---|
| 75 | h2 += stepH2 / 10.0; |
---|
| 76 | h3 += stepH3 / 10.0; |
---|
| 77 | v1 += stepV1 / 10.0; |
---|
| 78 | v2 += stepV2 / 10.0; |
---|
| 79 | /* |
---|
| 80 | pos = Vector3(sin(h1) * sin(h2) * 10.0, sin(v1) * sin(v2) * 3.0, (cos(h1) - 1.0) * (cos(h3) - 1.0) * 10.0); |
---|
| 81 | mLightPos = mLightInitialPos + pos; |
---|
| 82 | mLightNode->setPosition(mLightPos); |
---|
| 83 | |
---|
| 84 | mLightCutoff = sin(h3) * 60.0 + 30; |
---|
| 85 | |
---|
| 86 | if (mLightCutoff < 45) |
---|
| 87 | { |
---|
| 88 | //the cone is narrow, we scale over x and z |
---|
| 89 | mConeNode->setScale(tan(mLightCutoff * _PI / 180.0) * 2.0, 1.0, tan(mLightCutoff * _PI / 180.0) * 2.0); |
---|
| 90 | } |
---|
| 91 | else |
---|
| 92 | { |
---|
| 93 | mConeNode->setScale(1.0, 1.0 / (tan(mLightCutoff * _PI / 180.0) * 2.0), 1.0); |
---|
| 94 | } |
---|
| 95 | */ |
---|
| 96 | |
---|
| 97 | dir = Vector3(sin(h1) * sin(h2), cos(h1), sin(h1) * cos(h2)).normalisedCopy(); |
---|
| 98 | if (mConeNode) |
---|
| 99 | { |
---|
| 100 | mConeNode->resetOrientation(); |
---|
| 101 | mConeNode->rotate(Vector3(0, 1, 0).getRotationTo(dir)); |
---|
| 102 | mLightDir = dir; |
---|
| 103 | } |
---|
| 104 | } |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | |
---|
| 108 | |
---|
| 109 | |
---|
| 110 | |
---|
| 111 | |
---|
| 112 | |
---|
| 113 | ////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 114 | ////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 115 | ////////// |
---|
| 116 | ////////// RainLightManager class |
---|
| 117 | ////////// |
---|
| 118 | ////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 119 | ////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 120 | |
---|
| 121 | |
---|
| 122 | RainLightManager::RainLightManager(SceneManager *sceneMgr) |
---|
| 123 | { |
---|
| 124 | mSceneMgr = sceneMgr; |
---|
| 125 | lightCount = 0; |
---|
| 126 | lightVector.clear(); |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | |
---|
| 130 | |
---|
| 131 | RainLightManager::~RainLightManager() |
---|
| 132 | {} |
---|
| 133 | |
---|
| 134 | |
---|
| 135 | |
---|
| 136 | |
---|
| 137 | void RainLightManager::addStreetLight(ColourValue col, Vector3 LightPos, float LightAttenuation) |
---|
| 138 | { |
---|
| 139 | lightVector.push_back(new RainLight(mSceneMgr, lightCount, col, LightPos, LightAttenuation)); |
---|
| 140 | |
---|
| 141 | ++lightCount; |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | |
---|
| 145 | /* |
---|
| 146 | light info texture will contain information about a light source : |
---|
| 147 | - first pixel : color |
---|
| 148 | - second pixel : position |
---|
| 149 | - third pixel : direction (if spot) |
---|
| 150 | - fourth pixel : spot cutoff angle (180 for omnidirectional), distance attenuation (% / m) |
---|
| 151 | */ |
---|
| 152 | |
---|
| 153 | //void RainLightManager::createLightInfoTexture(int lightIndex, ColourValue col, Vector3 lightPosition, Vector3 lightDirection) |
---|
| 154 | void RainLightManager::createLightInfoTexture() |
---|
| 155 | { |
---|
| 156 | std::cout << std::endl << " Creating light information texture " << std::endl << std::endl; |
---|
| 157 | |
---|
| 158 | |
---|
| 159 | TexturePtr DynamicLightInfoTexture = TextureManager::getSingleton().createManual( |
---|
| 160 | LIGHT_INFO_TEXTURE_NAME, // name |
---|
| 161 | ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, |
---|
| 162 | TEX_TYPE_2D, // type |
---|
| 163 | 4, lightCount, // width & height |
---|
| 164 | 0, // number of mipmaps |
---|
| 165 | PF_FLOAT32_RGBA, // pixel format |
---|
| 166 | TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); |
---|
| 167 | |
---|
| 168 | // Get the pixel buffer |
---|
| 169 | HardwarePixelBufferSharedPtr pixelBuffer = DynamicLightInfoTexture->getBuffer(); |
---|
| 170 | |
---|
| 171 | // Lock the pixel buffer and get a pixel box |
---|
| 172 | pixelBuffer->lock(HardwareBuffer::HBL_DISCARD); |
---|
| 173 | const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); |
---|
| 174 | |
---|
| 175 | float* pDest = static_cast<float*>(pixelBox.data); |
---|
| 176 | |
---|
| 177 | // Fill in some pixel data. |
---|
| 178 | |
---|
| 179 | for (int i = 0 ; i < lightCount ; i++ ) |
---|
| 180 | { |
---|
| 181 | // we search for the data of each light |
---|
| 182 | ColourValue col = lightVector[i]->getColour(); |
---|
| 183 | Vector3 pos = lightVector[i]->getPosition(); |
---|
| 184 | Vector3 dir = lightVector[i]->getDirection(); |
---|
| 185 | float cutoff = lightVector[i]->getCutoff(); |
---|
| 186 | float att = lightVector[i]->getAttenuation(); |
---|
| 187 | |
---|
| 188 | // first pixel : light color |
---|
| 189 | *pDest++ = col.r; |
---|
| 190 | *pDest++ = col.g; |
---|
| 191 | *pDest++ = col.b; |
---|
| 192 | *pDest++ = 1.0; |
---|
| 193 | // second pixel : light position |
---|
| 194 | *pDest++ = pos.x; |
---|
| 195 | *pDest++ = pos.y; |
---|
| 196 | *pDest++ = pos.z; |
---|
| 197 | *pDest++ = 1.0; |
---|
| 198 | // third pixel : light direction |
---|
| 199 | *pDest++ = dir.x; |
---|
| 200 | *pDest++ = dir.y; |
---|
| 201 | *pDest++ = dir.z; |
---|
| 202 | *pDest++ = 1.0; |
---|
| 203 | // fourth pixel : cutoff and attenuation |
---|
| 204 | *pDest++ = cutoff; |
---|
| 205 | *pDest++ = att; |
---|
| 206 | *pDest++ = 1.0; |
---|
| 207 | *pDest++ = 1.0; |
---|
| 208 | } |
---|
| 209 | // Unlock the pixel buffer |
---|
| 210 | pixelBuffer->unlock(); |
---|
| 211 | |
---|
| 212 | DynamicLightInfoTexture->load(); |
---|
| 213 | } |
---|
| 214 | |
---|
| 215 | |
---|
| 216 | |
---|
| 217 | |
---|
| 218 | void RainLightManager::updateLightInfoTexture() |
---|
| 219 | { |
---|
| 220 | TexturePtr DynamicLightInfoTexture = TextureManager::getSingleton().getByName(LIGHT_INFO_TEXTURE_NAME); |
---|
| 221 | |
---|
| 222 | // Get the pixel buffer |
---|
| 223 | HardwarePixelBufferSharedPtr pixelBuffer = DynamicLightInfoTexture->getBuffer(); |
---|
| 224 | |
---|
| 225 | // Lock the pixel buffer and get a pixel box |
---|
| 226 | pixelBuffer->lock(HardwareBuffer::HBL_DISCARD); |
---|
| 227 | const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); |
---|
| 228 | |
---|
| 229 | float* pDest = static_cast<float*>(pixelBox.data); |
---|
| 230 | |
---|
| 231 | // Fill in some pixel data. |
---|
| 232 | for (int i = 0 ; i < lightCount ; i++ ) |
---|
| 233 | { |
---|
| 234 | // we search for the data of each light |
---|
| 235 | ColourValue col = lightVector[i]->getColour(); |
---|
| 236 | Vector3 pos = lightVector[i]->getPosition(); |
---|
| 237 | Vector3 dir = lightVector[i]->getDirection(); |
---|
| 238 | float cutoff = lightVector[i]->getCutoff(); |
---|
| 239 | float att = lightVector[i]->getAttenuation(); |
---|
| 240 | |
---|
| 241 | // first pixel : light color |
---|
| 242 | *pDest++ = col.r; |
---|
| 243 | *pDest++ = col.g; |
---|
| 244 | *pDest++ = col.b; |
---|
| 245 | *pDest++ = 1.0; |
---|
| 246 | // second pixel : light position |
---|
| 247 | *pDest++ = pos.x; |
---|
| 248 | *pDest++ = pos.y; |
---|
| 249 | *pDest++ = pos.z; |
---|
| 250 | *pDest++ = 1.0; |
---|
| 251 | // third pixel : light direction |
---|
| 252 | *pDest++ = dir.x; |
---|
| 253 | *pDest++ = dir.y; |
---|
| 254 | *pDest++ = dir.z; |
---|
| 255 | *pDest++ = 1.0; |
---|
| 256 | // fourth pixel : cutoff and attenuation |
---|
| 257 | *pDest++ = cutoff; |
---|
| 258 | *pDest++ = att; |
---|
| 259 | *pDest++ = 1.0; |
---|
| 260 | *pDest++ = 1.0; |
---|
| 261 | } |
---|
| 262 | |
---|
| 263 | // Unlock the pixel buffer |
---|
| 264 | pixelBuffer->unlock(); |
---|
| 265 | |
---|
| 266 | DynamicLightInfoTexture->load(); |
---|
| 267 | } |
---|
| 268 | |
---|
| 269 | |
---|
| 270 | |
---|
| 271 | void RainLightManager::updateLights() |
---|
| 272 | { |
---|
| 273 | for (int i = 0 ; i < lightCount ; i++ ) |
---|
| 274 | { |
---|
| 275 | if (lightVector[i]->getIsAnimated()) |
---|
| 276 | { |
---|
| 277 | lightVector[i]->animate(); |
---|
| 278 | } |
---|
| 279 | } |
---|
| 280 | |
---|
| 281 | updateLightInfoTexture(); |
---|
| 282 | } |
---|
| 283 | |
---|
| 284 | |
---|
| 285 | |
---|
| 286 | |
---|
| 287 | void RainLightManager::finalizeLights() |
---|
| 288 | { |
---|
| 289 | createLightInfoTexture(); |
---|
| 290 | } |
---|
| 291 | |
---|
| 292 | |
---|
| 293 | |
---|
| 294 | |
---|