28 namespace SkyX {
namespace VClouds
31 const float& Height,
const Ogre::Radian& Alpha,
const Ogre::Radian& Beta,
32 const float& Radius,
const Ogre::Radian& Phi,
const int& Na,
33 const int& Nb,
const int& Nc,
const int& A,
34 const int& B,
const int& C,
const int& Position)
40 , mNumberOfTriangles(0)
47 , mNa(Na) , mNb(Nb) , mNc(Nc)
48 , mA(A) , mB(B) , mC(C)
50 , mDisplacement(
Ogre::Vector3(0,0,0))
51 , mWorldOffset(
Ogre::Vector2(0,0))
53 , mDistance(
Ogre::Vector3(0,0,0))
54 , mLastFallingDistance(0)
69 mMesh = Ogre::MeshManager::getSingleton().createManual(
"_SkyX_VClouds_Block" + Ogre::StringConverter::toString(
mPosition),
70 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
78 mMesh->buildEdgeList();
86 mEntity->setMaterialName(
"SkyX_VolClouds");
103 Ogre::MeshManager::getSingleton().remove(
mMesh->getName());
119 Ogre::Vector2 Center = Ogre::Vector2(0,0);
123 Ogre::Vector2 Max = Ogre::Vector2(std::max<float>(std::max<float>(V1.x, V2.x), Center.x), std::max<float>(std::max<float>(V1.y, V2.y), Center.y) );
124 Ogre::Vector2 Min = Ogre::Vector2(std::min<float>(std::min<float>(V1.x, V2.x), Center.x), std::min<float>(std::min<float>(V1.y, V2.y), Center.y) );
126 return Ogre::AxisAlignedBox(
128 Min.x, -std::max<float>(fd,0), Min.y,
130 Max.x,
mHeight - std::min<float>(fd,0), Max.y);
141 mBetaSin = Ogre::Math::Sin(Ogre::Math::PI-
mBeta.valueRadians());
148 mSubMesh->vertexData =
new Ogre::VertexData();
149 mSubMesh->vertexData->vertexStart = 0;
152 Ogre::VertexDeclaration* vdecl =
mSubMesh->vertexData->vertexDeclaration;
153 Ogre::VertexBufferBinding* vbind =
mSubMesh->vertexData->vertexBufferBinding;
157 vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
158 offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
160 vdecl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES, 0);
161 offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
163 vdecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 1);
164 offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
166 vdecl->addElement(0, offset, Ogre::VET_FLOAT1, Ogre::VES_TEXTURE_COORDINATES, 2);
169 createVertexBuffer(
sizeof(
VERTEX),
171 Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
178 int VertexOffset = 0;
181 for (
int k = 0; k <
mNc; k++)
184 indexbuffer[IndexOffset] = VertexOffset;
185 indexbuffer[IndexOffset+1] = VertexOffset+1;
186 indexbuffer[IndexOffset+2] = VertexOffset+3;
189 indexbuffer[IndexOffset+3] = VertexOffset;
190 indexbuffer[IndexOffset+4] = VertexOffset+3;
191 indexbuffer[IndexOffset+5] = VertexOffset+2;
198 for (
int k = 0; k <
mNb; k++)
201 indexbuffer[IndexOffset] = VertexOffset;
202 indexbuffer[IndexOffset+1] = VertexOffset+1;
203 indexbuffer[IndexOffset+2] = VertexOffset+3;
206 indexbuffer[IndexOffset+3] = VertexOffset;
207 indexbuffer[IndexOffset+4] = VertexOffset+3;
208 indexbuffer[IndexOffset+5] = VertexOffset+2;
211 indexbuffer[IndexOffset+6] = VertexOffset+2;
212 indexbuffer[IndexOffset+7] = VertexOffset+3;
213 indexbuffer[IndexOffset+8] = VertexOffset+5;
216 indexbuffer[IndexOffset+9] = VertexOffset+2;
217 indexbuffer[IndexOffset+10] = VertexOffset+5;
218 indexbuffer[IndexOffset+11] = VertexOffset+4;
225 for (
int k = 0; k <
mNa; k++)
228 indexbuffer[IndexOffset] = VertexOffset;
229 indexbuffer[IndexOffset+1] = VertexOffset+1;
230 indexbuffer[IndexOffset+2] = VertexOffset+3;
233 indexbuffer[IndexOffset+3] = VertexOffset;
234 indexbuffer[IndexOffset+4] = VertexOffset+3;
235 indexbuffer[IndexOffset+5] = VertexOffset+2;
238 indexbuffer[IndexOffset+6] = VertexOffset+2;
239 indexbuffer[IndexOffset+7] = VertexOffset+3;
240 indexbuffer[IndexOffset+8] = VertexOffset+5;
243 indexbuffer[IndexOffset+9] = VertexOffset+2;
244 indexbuffer[IndexOffset+10] = VertexOffset+5;
245 indexbuffer[IndexOffset+11] = VertexOffset+4;
248 indexbuffer[IndexOffset+12] = VertexOffset+4;
249 indexbuffer[IndexOffset+13] = VertexOffset+5;
250 indexbuffer[IndexOffset+14] = VertexOffset+6;
258 Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
259 Ogre::HardwareIndexBuffer::IT_16BIT,
261 Ogre::HardwareBuffer::HBU_STATIC,
true);
269 delete []indexbuffer;
273 mSubMesh->indexData->indexStart = 0;
293 if (fallingDistance > 0)
326 for (
int k = 0; k <
mNc; k++)
332 for (
int k = 0; k <
mNb; k++)
338 for (
int k = 0; k <
mNa; k++)
353 int VertexOffset = n*4;
371 Ogre::Vector2 x1 = Radius*
mV2Cos,
376 Ogre::Vector3 or0 = Ogre::Vector3(x1.x, 0, z1.x),
377 or1 = Ogre::Vector3(x1.y, 0, z1.y);
379 float y0 = Radius*Ogre::Math::Sin(
mAlpha),
380 d = Ogre::Vector2(x1.x - x2.x, z1.x - z2.x).length(),
381 ang = Ogre::Math::ATan(y0/d).valueRadians(),
382 hip =
mHeight / Ogre::Math::Sin(ang);
389 _setVertexData(VertexOffset+2, or0+(Ogre::Vector3(x2.x, y0, z2.x)-or0).normalisedCopy()*hip, opacity);
391 _setVertexData(VertexOffset+3, or1+(Ogre::Vector3(x2.y, y0, z2.y)-or1).normalisedCopy()*hip, opacity);
396 int VertexOffset =
mNc*4 + n*6;
414 Ogre::Vector2 x1 = Radius*
mV2Cos,
419 float y0 = Radius*Ogre::Math::Sin(
mAlpha);
422 _setVertexData(VertexOffset, Ogre::Vector3(x1.x, 0, z1.x), opacity);
424 _setVertexData(VertexOffset+1, Ogre::Vector3(x1.y, 0, z1.y), opacity);
426 _setVertexData(VertexOffset+2, Ogre::Vector3(x2.x, y0, z2.x), opacity);
428 _setVertexData(VertexOffset+3, Ogre::Vector3(x2.y, y0, z2.y), opacity);
433 Ogre::Vector3 or0 = Ogre::Vector3(x2.x, y0, z2.x),
434 or1 = Ogre::Vector3(x2.y, y0, z2.y);
436 float y1 = Radius*Ogre::Math::Sin(
mBeta),
438 d = Ogre::Vector2(x3.x - x2.x, z3.x - z2.x).length(),
439 ang = Ogre::Math::ATan(y3/d).valueRadians(),
440 hip = (
mHeight-y0) / Ogre::Math::Sin(ang);
443 _setVertexData(VertexOffset+4, or0 + (Ogre::Vector3(x3.x, y1, z3.x)-or0).normalisedCopy()*hip, opacity);
445 _setVertexData(VertexOffset+5, or1 + (Ogre::Vector3(x3.y, y1, z3.y)-or1).normalisedCopy()*hip, opacity);
450 int VertexOffset =
mNc*4 +
mNb*6 +n*7;
459 Ogre::Vector2 x1 = Radius*
mV2Cos,
464 float y0 = Radius*Ogre::Math::Sin(
mAlpha);
467 _setVertexData(VertexOffset, Ogre::Vector3(x1.x, 0, z1.x), opacity);
469 _setVertexData(VertexOffset+1, Ogre::Vector3(x1.y, 0, z1.y), opacity);
471 _setVertexData(VertexOffset+2, Ogre::Vector3(x2.x, y0, z2.x), opacity);
473 _setVertexData(VertexOffset+3, Ogre::Vector3(x2.y, y0, z2.y), opacity);
478 float y1 = Radius*Ogre::Math::Sin(
mBeta);
481 _setVertexData(VertexOffset+4, Ogre::Vector3(x3.x, y1, z3.x), opacity);
483 _setVertexData(VertexOffset+5, Ogre::Vector3(x3.y, y1, z3.y), opacity);
486 _setVertexData(VertexOffset+6, Ogre::Vector3(0, Radius, 0), opacity);
496 if (fallingDistance > 0)
512 fallingDistance *= Ogre::Math::Sign(yDist);
540 float xz_length_radius = Ogre::Vector2(p.x,p.z).length() /
mRadius;
541 Ogre::Vector3 origin = Ogre::Vector3(0,-(
mEntity->getParentSceneNode()->_getDerivedPosition().y-
mCamera->getDerivedPosition().y) -
mRadius*(0.5f+0.5f*Ogre::Vector2(p.x,p.z).length()/
mRadius),0);
542 Ogre::Vector3 dir = (p-origin).normalisedCopy();
543 float hip = Ogre::Math::Sqrt(Ogre::Math::Pow(xz_length_radius *
mRadius, 2) + Ogre::Math::Pow(origin.y, 2));
544 Ogre::Vector3 uv = dir*hip;
549 float dist = (
mDistance - Ogre::Vector3(p.x, p.y - fallingDistance, p.z)).length();
550 float att = Ogre::Math::Clamp((dist-
mA/3.25f)/(
mA/3.25f),0.0f,1.0f);
564 return c->isVisible(
mEntity->getParentSceneNode()->_getWorldAABB());