| 1 | /* | 
|---|
| 2 |   orxonox - the future of 3D-vertical-scrollers | 
|---|
| 3 |  | 
|---|
| 4 |   Copyright (C) 2004 orx | 
|---|
| 5 |  | 
|---|
| 6 |   This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |   it under the terms of the GNU General Public License as published by | 
|---|
| 8 |   the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 9 |   any later version. | 
|---|
| 10 |  | 
|---|
| 11 | ### File Specific: | 
|---|
| 12 |   main-programmer: hdavid, amaechler | 
|---|
| 13 |  | 
|---|
| 14 |   INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader | 
|---|
| 15 | */ | 
|---|
| 16 |  | 
|---|
| 17 | #include "cloud_effect.h" | 
|---|
| 18 |  | 
|---|
| 19 | #include "util/loading/load_param.h" | 
|---|
| 20 | #include "util/loading/factory.h" | 
|---|
| 21 |  | 
|---|
| 22 | #include "material.h" | 
|---|
| 23 | #include "state.h" | 
|---|
| 24 | #include "p_node.h" | 
|---|
| 25 | #include "shader.h" | 
|---|
| 26 | #include "shell_command.h" | 
|---|
| 27 | #include "t_animation.h" | 
|---|
| 28 | #include "script_class.h" | 
|---|
| 29 |  | 
|---|
| 30 | #include "resource_shader.h" | 
|---|
| 31 |  | 
|---|
| 32 |  | 
|---|
| 33 |  | 
|---|
| 34 | Vector    CloudEffect::cloudColor; | 
|---|
| 35 | Vector    CloudEffect::skyColor; | 
|---|
| 36 | Vector    CloudEffect::newCloudColor; | 
|---|
| 37 | Vector    CloudEffect::newSkyColor; | 
|---|
| 38 |  | 
|---|
| 39 | bool      CloudEffect::fadeSky; | 
|---|
| 40 | bool      CloudEffect::fadeCloud; | 
|---|
| 41 | float     CloudEffect::fadeTime; | 
|---|
| 42 |  | 
|---|
| 43 | ObjectListDefinition(CloudEffect); | 
|---|
| 44 |  | 
|---|
| 45 |  | 
|---|
| 46 | SHELL_COMMAND(activate, CloudEffect, activateCloud); | 
|---|
| 47 | SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud); | 
|---|
| 48 | SHELL_COMMAND(skyColor, CloudEffect, shellSkyColor); | 
|---|
| 49 | SHELL_COMMAND(cloudColor, CloudEffect, shellCloudColor); | 
|---|
| 50 |  | 
|---|
| 51 |  | 
|---|
| 52 | CREATE_SCRIPTABLE_CLASS(CloudEffect, | 
|---|
| 53 |                         addMethod("skyColor", Executor4<CloudEffect, lua_State*,float,float,float,float>(&CloudEffect::shellSkyColor)) | 
|---|
| 54 |                         ->addMethod("cloudColor", Executor4<CloudEffect, lua_State*,float,float,float,float>(&CloudEffect::shellCloudColor)) | 
|---|
| 55 |                         ->addMethod("activate", Executor0<CloudEffect, lua_State*>(&CloudEffect::activate)) | 
|---|
| 56 |                         ->addMethod("deactivate", Executor0<CloudEffect, lua_State*>(&CloudEffect::deactivate)) | 
|---|
| 57 |                        ); | 
|---|
| 58 |  | 
|---|
| 59 |  | 
|---|
| 60 | CREATE_FACTORY(CloudEffect); | 
|---|
| 61 |  | 
|---|
| 62 | CloudEffect::CloudEffect(const TiXmlElement* root) { | 
|---|
| 63 |   this->registerObject(this, CloudEffect::_objectList); | 
|---|
| 64 |  | 
|---|
| 65 |     this->init(); | 
|---|
| 66 |  | 
|---|
| 67 |     if (root != NULL) | 
|---|
| 68 |         this->loadParams(root); | 
|---|
| 69 |  | 
|---|
| 70 |     if(cloudActivate) | 
|---|
| 71 |         this->activate(); | 
|---|
| 72 | } | 
|---|
| 73 |  | 
|---|
| 74 | CloudEffect::~CloudEffect() { | 
|---|
| 75 |     this->deactivate(); | 
|---|
| 76 |  | 
|---|
| 77 |     if (glIsTexture(noise3DTexName)) | 
|---|
| 78 |         glDeleteTextures(1, &noise3DTexName); | 
|---|
| 79 | } | 
|---|
| 80 |  | 
|---|
| 81 |  | 
|---|
| 82 | void CloudEffect::init() { | 
|---|
| 83 |     PRINTF(4)("Initializing CloudEffect\n"); | 
|---|
| 84 |  | 
|---|
| 85 |     // default values | 
|---|
| 86 |     this->offsetZ = 0; | 
|---|
| 87 |     this->animationSpeed = 2; | 
|---|
| 88 |     this->scale = 0.0004f; | 
|---|
| 89 |     this->atmosphericRadius = 4000; | 
|---|
| 90 |     this->planetRadius = 1500; | 
|---|
| 91 |     this->divs = 15; | 
|---|
| 92 |     this->cloudActivate = false; | 
|---|
| 93 |     fadeSky = false; | 
|---|
| 94 |     fadeCloud = false; | 
|---|
| 95 |  | 
|---|
| 96 |  | 
|---|
| 97 |     skyColor = Vector(0.0f, 0.0f, 0.8f); | 
|---|
| 98 |     cloudColor = Vector(0.8f, 0.8f, 0.8f); | 
|---|
| 99 |     newSkyColor = skyColor; | 
|---|
| 100 |     newCloudColor = cloudColor; | 
|---|
| 101 |  | 
|---|
| 102 |     this->noise3DTexSize = 128; | 
|---|
| 103 |     this->noise3DTexName = 0; | 
|---|
| 104 |  | 
|---|
| 105 |     this->make3DNoiseTexture(); | 
|---|
| 106 |  | 
|---|
| 107 |     glGenTextures(1, &noise3DTexName); | 
|---|
| 108 |     glBindTexture(GL_TEXTURE_3D, noise3DTexName); | 
|---|
| 109 |  | 
|---|
| 110 |     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); | 
|---|
| 111 |     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); | 
|---|
| 112 |     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); | 
|---|
| 113 |     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
|---|
| 114 |     glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
|---|
| 115 |  | 
|---|
| 116 |     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, | 
|---|
| 117 |                  noise3DTexSize, noise3DTexSize, noise3DTexSize, | 
|---|
| 118 |                  0, GL_RGBA, GL_UNSIGNED_BYTE, noise3DTexPtr); | 
|---|
| 119 |  | 
|---|
| 120 |     this->skydome = new Skydome(); | 
|---|
| 121 |     this->skydome->setTexture(noise3DTexName); | 
|---|
| 122 |  | 
|---|
| 123 |     if ( Shader::isSupported() ) | 
|---|
| 124 |     { | 
|---|
| 125 |       this->shader = ResourceShader("/shaders/cloud.vert", "/shaders/cloud.frag"); | 
|---|
| 126 |        | 
|---|
| 127 |       this->shader.activateShader(); | 
|---|
| 128 |        | 
|---|
| 129 |       Shader::Uniform(shader, "Noise").set(0); | 
|---|
| 130 |        | 
|---|
| 131 |       this->offset = new Shader::Uniform(shader, "Offset"); | 
|---|
| 132 |       this->skycolor = new Shader::Uniform(shader, "SkyColor"); | 
|---|
| 133 |       this->cloudcolor = new Shader::Uniform(shader, "CloudColor"); | 
|---|
| 134 |        | 
|---|
| 135 |       this->shader.deactivateShader(); | 
|---|
| 136 |        | 
|---|
| 137 |       this->skydome->setShader(&shader); | 
|---|
| 138 |     } | 
|---|
| 139 | } | 
|---|
| 140 |  | 
|---|
| 141 |  | 
|---|
| 142 | void CloudEffect::loadParams(const TiXmlElement* root) { | 
|---|
| 143 |     WeatherEffect::loadParams(root); | 
|---|
| 144 |  | 
|---|
| 145 |     LoadParam(root, "speed", this, CloudEffect, setAnimationSpeed); | 
|---|
| 146 |     LoadParam(root, "scale", this, CloudEffect, setCloudScale); | 
|---|
| 147 |     LoadParam(root, "cloudcolor", this, CloudEffect, setCloudColor); | 
|---|
| 148 |     LoadParam(root, "skycolor", this, CloudEffect, setSkyColor); | 
|---|
| 149 |  | 
|---|
| 150 |     LoadParam(root, "planetRadius", this, CloudEffect, setPlanetRadius); | 
|---|
| 151 |     LoadParam(root, "atmosphericRadius", this, CloudEffect, setAtmosphericRadius); | 
|---|
| 152 |     LoadParam(root, "divisions", this, CloudEffect, setDivisions); | 
|---|
| 153 |  | 
|---|
| 154 |     LOAD_PARAM_START_CYCLE(root, element); | 
|---|
| 155 |     { | 
|---|
| 156 |         LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption); | 
|---|
| 157 |     } | 
|---|
| 158 |     LOAD_PARAM_END_CYCLE(element); | 
|---|
| 159 | } | 
|---|
| 160 |  | 
|---|
| 161 |  | 
|---|
| 162 | void CloudEffect::activate() { | 
|---|
| 163 |     PRINTF(0)( "Activating\n"); | 
|---|
| 164 |  | 
|---|
| 165 |     // Can only be set after the loadParams call | 
|---|
| 166 |     this->shader.activateShader(); | 
|---|
| 167 |     Shader::Uniform(shader, "Scale").set(this->scale); | 
|---|
| 168 |     this->skycolor->set | 
|---|
| 169 |     (skyColor.x, skyColor.y, skyColor.z); | 
|---|
| 170 |     this->cloudcolor->set | 
|---|
| 171 |     (cloudColor.x, cloudColor.y, cloudColor.z); | 
|---|
| 172 |     this->shader.deactivateShader(); | 
|---|
| 173 |  | 
|---|
| 174 |     this->skydome->generateSkyPlane(this->divs, this->planetRadius, this->atmosphericRadius, 1, 1); | 
|---|
| 175 |     this->skydome->activate(); | 
|---|
| 176 |  | 
|---|
| 177 |     this->cloudActivate = true; | 
|---|
| 178 | } | 
|---|
| 179 |  | 
|---|
| 180 | void CloudEffect::deactivate() { | 
|---|
| 181 |     PRINTF(4)("Deactivating CloudEffect\n"); | 
|---|
| 182 |  | 
|---|
| 183 |     this->skydome->deactivate(); | 
|---|
| 184 |     this->cloudActivate = false; | 
|---|
| 185 | } | 
|---|
| 186 |  | 
|---|
| 187 | void CloudEffect::draw() const {} | 
|---|
| 188 |  | 
|---|
| 189 | void CloudEffect::tick (float dt) { | 
|---|
| 190 |  | 
|---|
| 191 |     if ( this->cloudActivate && Shader::isSupported() ) { | 
|---|
| 192 |  | 
|---|
| 193 |         this->offsetZ += 0.05 * dt * this->animationSpeed; | 
|---|
| 194 |  | 
|---|
| 195 |         this->shader.activateShader(); | 
|---|
| 196 |         this->offset->set | 
|---|
| 197 |         (0.0f, 0.0f, offsetZ); | 
|---|
| 198 |  | 
|---|
| 199 |         if(cloudColor != newCloudColor) { | 
|---|
| 200 |  | 
|---|
| 201 |             if(fadeCloud) { | 
|---|
| 202 |  | 
|---|
| 203 |                 this->cloudColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudX); | 
|---|
| 204 |                 this->cloudColorFadeX->setInfinity(ANIM_INF_CONSTANT); | 
|---|
| 205 |                 this->cloudColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudY); | 
|---|
| 206 |                 this->cloudColorFadeY->setInfinity(ANIM_INF_CONSTANT); | 
|---|
| 207 |                 this->cloudColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudZ); | 
|---|
| 208 |                 this->cloudColorFadeZ->setInfinity(ANIM_INF_CONSTANT); | 
|---|
| 209 |  | 
|---|
| 210 |                 this->cloudColorFadeX->addKeyFrame(cloudColor.x, fadeTime, ANIM_LINEAR); | 
|---|
| 211 |                 this->cloudColorFadeX->addKeyFrame(newCloudColor.x, 0, ANIM_LINEAR); | 
|---|
| 212 |  | 
|---|
| 213 |                 this->cloudColorFadeY->addKeyFrame(cloudColor.y, fadeTime, ANIM_LINEAR); | 
|---|
| 214 |                 this->cloudColorFadeY->addKeyFrame(newCloudColor.y, 0, ANIM_LINEAR); | 
|---|
| 215 |  | 
|---|
| 216 |                 this->cloudColorFadeZ->addKeyFrame(cloudColor.z, fadeTime, ANIM_LINEAR); | 
|---|
| 217 |                 this->cloudColorFadeZ->addKeyFrame(newCloudColor.z, 0, ANIM_LINEAR); | 
|---|
| 218 |  | 
|---|
| 219 |                 fadeCloud = false; | 
|---|
| 220 |  | 
|---|
| 221 |                 this->cloudColorFadeX->replay(); | 
|---|
| 222 |                 this->cloudColorFadeY->replay(); | 
|---|
| 223 |                 this->cloudColorFadeZ->replay(); | 
|---|
| 224 |             } | 
|---|
| 225 |  | 
|---|
| 226 |             this->cloudcolor->set | 
|---|
| 227 |             (this->cloudColor.x, this->cloudColor.y, this->cloudColor.z); | 
|---|
| 228 |         } | 
|---|
| 229 |  | 
|---|
| 230 |         if(skyColor != newSkyColor) { | 
|---|
| 231 |  | 
|---|
| 232 |             if(fadeSky) { | 
|---|
| 233 |  | 
|---|
| 234 |                 this->skyColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyX); | 
|---|
| 235 |                 this->skyColorFadeX->setInfinity(ANIM_INF_CONSTANT); | 
|---|
| 236 |                 this->skyColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyY); | 
|---|
| 237 |                 this->skyColorFadeY->setInfinity(ANIM_INF_CONSTANT); | 
|---|
| 238 |                 this->skyColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyZ); | 
|---|
| 239 |                 this->skyColorFadeZ->setInfinity(ANIM_INF_CONSTANT); | 
|---|
| 240 |  | 
|---|
| 241 |                 this->skyColorFadeX->addKeyFrame(skyColor.x, fadeTime, ANIM_LINEAR); | 
|---|
| 242 |                 this->skyColorFadeX->addKeyFrame(newSkyColor.x, 0, ANIM_LINEAR); | 
|---|
| 243 |  | 
|---|
| 244 |                 this->skyColorFadeY->addKeyFrame(skyColor.y, fadeTime, ANIM_LINEAR); | 
|---|
| 245 |                 this->skyColorFadeY->addKeyFrame(newSkyColor.y, 0, ANIM_LINEAR); | 
|---|
| 246 |  | 
|---|
| 247 |                 this->skyColorFadeZ->addKeyFrame(skyColor.z, fadeTime, ANIM_LINEAR); | 
|---|
| 248 |                 this->skyColorFadeZ->addKeyFrame(newSkyColor.z, 0, ANIM_LINEAR); | 
|---|
| 249 |  | 
|---|
| 250 |                 fadeSky = false; | 
|---|
| 251 |  | 
|---|
| 252 |                 this->skyColorFadeX->replay(); | 
|---|
| 253 |                 this->skyColorFadeY->replay(); | 
|---|
| 254 |                 this->skyColorFadeZ->replay(); | 
|---|
| 255 |             } | 
|---|
| 256 |  | 
|---|
| 257 |             this->skycolor->set | 
|---|
| 258 |             (this->skyColor.x, this->skyColor.y, this->skyColor.z); | 
|---|
| 259 |         } | 
|---|
| 260 |  | 
|---|
| 261 |         this->shader.deactivateShader(); | 
|---|
| 262 |     } | 
|---|
| 263 | } | 
|---|
| 264 |  | 
|---|
| 265 |  | 
|---|
| 266 | void CloudEffect::setColorSkyX(float color) { | 
|---|
| 267 |     skyColor.x = color; | 
|---|
| 268 | } | 
|---|
| 269 | void CloudEffect::setColorSkyY(float color) { | 
|---|
| 270 |     skyColor.y = color; | 
|---|
| 271 | } | 
|---|
| 272 | void CloudEffect::setColorSkyZ(float color) { | 
|---|
| 273 |     skyColor.z = color; | 
|---|
| 274 | } | 
|---|
| 275 | void CloudEffect::setColorCloudX(float color) { | 
|---|
| 276 |     cloudColor.x = color; | 
|---|
| 277 | } | 
|---|
| 278 | void CloudEffect::setColorCloudY(float color) { | 
|---|
| 279 |     cloudColor.y = color; | 
|---|
| 280 | } | 
|---|
| 281 | void CloudEffect::setColorCloudZ(float color) { | 
|---|
| 282 |     cloudColor.z = color; | 
|---|
| 283 | } | 
|---|
| 284 |  | 
|---|
| 285 | void CloudEffect::changeSkyColor(Vector color, float time) { | 
|---|
| 286 |     newSkyColor = color; | 
|---|
| 287 |     fadeSky = true; | 
|---|
| 288 |     fadeTime = time; | 
|---|
| 289 | } | 
|---|
| 290 |  | 
|---|
| 291 |  | 
|---|
| 292 | void CloudEffect::changeCloudColor(Vector color, float time) { | 
|---|
| 293 |     newCloudColor = color; | 
|---|
| 294 |     fadeCloud = true; | 
|---|
| 295 |     fadeTime = time; | 
|---|
| 296 | } | 
|---|
| 297 |  | 
|---|
| 298 | void CloudEffect::shellSkyColor(float colorX, float colorY, float colorZ, float time) { | 
|---|
| 299 |     changeSkyColor( Vector(colorX, colorY, colorZ), time); | 
|---|
| 300 | } | 
|---|
| 301 |  | 
|---|
| 302 | void CloudEffect::shellCloudColor(float colorX, float colorY, float colorZ, float time) { | 
|---|
| 303 |     changeCloudColor( Vector(colorX, colorY, colorZ), time); | 
|---|
| 304 | } | 
|---|
| 305 |  | 
|---|
| 306 |  | 
|---|
| 307 |  | 
|---|
| 308 | void CloudEffect::make3DNoiseTexture() { | 
|---|
| 309 |     int f, i, j, k, inc; | 
|---|
| 310 |     int startFrequency = 4; | 
|---|
| 311 |     int numOctaves = 4; | 
|---|
| 312 |     double ni[3]; | 
|---|
| 313 |     double inci, incj, inck; | 
|---|
| 314 |     int frequency = startFrequency; | 
|---|
| 315 |     GLubyte *ptr; | 
|---|
| 316 |     double amp = 0.5; | 
|---|
| 317 |  | 
|---|
| 318 |     if ((noise3DTexPtr = (GLubyte *) malloc(noise3DTexSize * | 
|---|
| 319 |                                             noise3DTexSize * | 
|---|
| 320 |                                             noise3DTexSize * 4)) == NULL) | 
|---|
| 321 |         PRINTF(0)("ERROR: Could not allocate 3D noise texture\n"); | 
|---|
| 322 |  | 
|---|
| 323 |     for (f=0, inc=0; f < numOctaves; | 
|---|
| 324 |             ++f, frequency *= 2, ++inc, amp *= 0.5) { | 
|---|
| 325 |         SetNoiseFrequency(frequency); | 
|---|
| 326 |         ptr = noise3DTexPtr; | 
|---|
| 327 |         ni[0] = ni[1] = ni[2] = 0; | 
|---|
| 328 |  | 
|---|
| 329 |         inci = 1.0 / (noise3DTexSize / frequency); | 
|---|
| 330 |         for (i=0; i<noise3DTexSize; ++i, ni[0] += inci) { | 
|---|
| 331 |             incj = 1.0 / (noise3DTexSize / frequency); | 
|---|
| 332 |             for (j=0; j<noise3DTexSize; ++j, ni[1] += incj) { | 
|---|
| 333 |                 inck = 1.0 / (noise3DTexSize / frequency); | 
|---|
| 334 |                 for (k=0; k<noise3DTexSize; ++k, ni[2] += inck, ptr+= 4) { | 
|---|
| 335 |                     *(ptr+inc) = (GLubyte) (((noise3(ni)+1.0) * amp)*128.0); | 
|---|
| 336 |                 } | 
|---|
| 337 |             } | 
|---|
| 338 |         } | 
|---|
| 339 |     } | 
|---|
| 340 | } | 
|---|
| 341 |  | 
|---|
| 342 | void CloudEffect::initNoise() { | 
|---|
| 343 |     int i, j, k; | 
|---|
| 344 |  | 
|---|
| 345 |     srand(30757); | 
|---|
| 346 |     for (i = 0 ; i < B ; i++) { | 
|---|
| 347 |         p[i] = i; | 
|---|
| 348 |         g1[i] = (double)((rand() % (B + B)) - B) / B; | 
|---|
| 349 |  | 
|---|
| 350 |         for (j = 0 ; j < 2 ; j++) | 
|---|
| 351 |             g2[i][j] = (double)((rand() % (B + B)) - B) / B; | 
|---|
| 352 |         normalize2(g2[i]); | 
|---|
| 353 |  | 
|---|
| 354 |         for (j = 0 ; j < 3 ; j++) | 
|---|
| 355 |             g3[i][j] = (double)((rand() % (B + B)) - B) / B; | 
|---|
| 356 |         normalize3(g3[i]); | 
|---|
| 357 |     } | 
|---|
| 358 |  | 
|---|
| 359 |     while (--i) { | 
|---|
| 360 |         k = p[i]; | 
|---|
| 361 |         p[i] = p[j = rand() % B]; | 
|---|
| 362 |         p[j] = k; | 
|---|
| 363 |     } | 
|---|
| 364 |  | 
|---|
| 365 |     for (i = 0 ; i < B + 2 ; i++) { | 
|---|
| 366 |         p[B + i] = p[i]; | 
|---|
| 367 |         g1[B + i] = g1[i]; | 
|---|
| 368 |         for (j = 0 ; j < 2 ; j++) | 
|---|
| 369 |             g2[B + i][j] = g2[i][j]; | 
|---|
| 370 |         for (j = 0 ; j < 3 ; j++) | 
|---|
| 371 |             g3[B + i][j] = g3[i][j]; | 
|---|
| 372 |     } | 
|---|
| 373 | } | 
|---|
| 374 |  | 
|---|
| 375 | void CloudEffect::SetNoiseFrequency( int frequency) { | 
|---|
| 376 |     start = 1; | 
|---|
| 377 |     B = frequency; | 
|---|
| 378 |     BM = B-1; | 
|---|
| 379 | } | 
|---|
| 380 |  | 
|---|
| 381 | double CloudEffect::noise3( double vec[3]) { | 
|---|
| 382 |     int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; | 
|---|
| 383 |     double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; | 
|---|
| 384 |     int i, j; | 
|---|
| 385 |  | 
|---|
| 386 |     if (start) { | 
|---|
| 387 |         start = 0; | 
|---|
| 388 |         initNoise(); | 
|---|
| 389 |     } | 
|---|
| 390 |  | 
|---|
| 391 |     setup(0, bx0,bx1, rx0,rx1); | 
|---|
| 392 |     setup(1, by0,by1, ry0,ry1); | 
|---|
| 393 |     setup(2, bz0,bz1, rz0,rz1); | 
|---|
| 394 |  | 
|---|
| 395 |     i = p[ bx0 ]; | 
|---|
| 396 |     j = p[ bx1 ]; | 
|---|
| 397 |  | 
|---|
| 398 |     b00 = p[ i + by0 ]; | 
|---|
| 399 |     b10 = p[ j + by0 ]; | 
|---|
| 400 |     b01 = p[ i + by1 ]; | 
|---|
| 401 |     b11 = p[ j + by1 ]; | 
|---|
| 402 |  | 
|---|
| 403 |     t  = s_curve(rx0); | 
|---|
| 404 |     sy = s_curve(ry0); | 
|---|
| 405 |     sz = s_curve(rz0); | 
|---|
| 406 |  | 
|---|
| 407 |     q = g3[ b00 + bz0 ] ; | 
|---|
| 408 |     u = at3(rx0,ry0,rz0); | 
|---|
| 409 |     q = g3[ b10 + bz0 ] ; | 
|---|
| 410 |     v = at3(rx1,ry0,rz0); | 
|---|
| 411 |     a = lerp(t, u, v); | 
|---|
| 412 |  | 
|---|
| 413 |     q = g3[ b01 + bz0 ] ; | 
|---|
| 414 |     u = at3(rx0,ry1,rz0); | 
|---|
| 415 |     q = g3[ b11 + bz0 ] ; | 
|---|
| 416 |     v = at3(rx1,ry1,rz0); | 
|---|
| 417 |     b = lerp(t, u, v); | 
|---|
| 418 |  | 
|---|
| 419 |     c = lerp(sy, a, b); | 
|---|
| 420 |  | 
|---|
| 421 |     q = g3[ b00 + bz1 ] ; | 
|---|
| 422 |     u = at3(rx0,ry0,rz1); | 
|---|
| 423 |     q = g3[ b10 + bz1 ] ; | 
|---|
| 424 |     v = at3(rx1,ry0,rz1); | 
|---|
| 425 |     a = lerp(t, u, v); | 
|---|
| 426 |  | 
|---|
| 427 |     q = g3[ b01 + bz1 ] ; | 
|---|
| 428 |     u = at3(rx0,ry1,rz1); | 
|---|
| 429 |     q = g3[ b11 + bz1 ] ; | 
|---|
| 430 |     v = at3(rx1,ry1,rz1); | 
|---|
| 431 |     b = lerp(t, u, v); | 
|---|
| 432 |  | 
|---|
| 433 |     d = lerp(sy, a, b); | 
|---|
| 434 |  | 
|---|
| 435 |     return lerp(sz, c, d); | 
|---|
| 436 | } | 
|---|
| 437 |  | 
|---|
| 438 | void CloudEffect::normalize2( double v[2]) { | 
|---|
| 439 |     double s; | 
|---|
| 440 |  | 
|---|
| 441 |     s = sqrt(v[0] * v[0] + v[1] * v[1]); | 
|---|
| 442 |     v[0] = v[0] / s; | 
|---|
| 443 |     v[1] = v[1] / s; | 
|---|
| 444 | } | 
|---|
| 445 |  | 
|---|
| 446 | void CloudEffect::normalize3( double v[3]) { | 
|---|
| 447 |     double s; | 
|---|
| 448 |  | 
|---|
| 449 |     s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); | 
|---|
| 450 |     v[0] = v[0] / s; | 
|---|
| 451 |     v[1] = v[1] / s; | 
|---|
| 452 |     v[2] = v[2] / s; | 
|---|
| 453 | } | 
|---|
| 454 |  | 
|---|