X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fbubble-effect%2Fbubble-emitter-impl.cpp;h=dde825373166eb425a3714bf48913d870f873bdf;hb=ec503e92aa01bc67f8ea118cf14aa3b1ed9d390e;hp=d19daa46c57ff03b972424423b28d013e8239328;hpb=f58b8383147de70affa1e3949cf1c6757d705d3c;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.cpp b/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.cpp index d19daa4..dde8253 100644 --- a/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.cpp +++ b/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,63 +19,135 @@ #include "bubble-emitter-impl.h" // EXTERNAL INCLUDES -#include #include #include -#include +#include +#include // INTERNAL INCLUDES -#include +#include +#include +#include -namespace Dali +namespace +{ +struct Vertex { + Vertex() + : index(0.0f), + position(), + textureCoord() + { + } -namespace Toolkit + Vertex(float index, const Dali::Vector2& position, const Dali::Vector2& textureCoord) + : index(index), + position(position), + textureCoord(textureCoord) + { + } + + float index; + Dali::Vector2 position; + Dali::Vector2 textureCoord; +}; + +/** + * Return a random value between the given interval. + * @param[in] f0 The low bound + * @param[in] f1 The up bound + * @param[in] seed The seed to genergate random number + * @return A random value between the given interval + */ +float RandomRange(float f0, float f1, unsigned int& seed) +{ + return f0 + (rand_r(&seed) & 0xfff) * (f1 - f0) * (1.0f / 4095.0f); +} + +Dali::Geometry CreateTexturedQuad() { + struct Vertex + { + Dali::Vector2 position; + Dali::Vector2 texCoord; + }; + + static const Vertex data[] = {{Dali::Vector2(-0.5f, -0.5f), Dali::Vector2(0.0f, 0.0f)}, + {Dali::Vector2(0.5f, -0.5f), Dali::Vector2(1.0f, 0.0f)}, + {Dali::Vector2(-0.5f, 0.5f), Dali::Vector2(0.0f, 1.0f)}, + {Dali::Vector2(0.5f, 0.5f), Dali::Vector2(1.0f, 1.0f)}}; + + // Create a vertex buffer for vertex positions and texture coordinates + Dali::VertexBuffer vertexBuffer = Dali::VertexBuffer::New(Dali::Property::Map() + .Add("aPosition", Dali::Property::VECTOR2) + .Add("aTexCoord", Dali::Property::VECTOR2)); + vertexBuffer.SetData(data, 4u); + + //Create the geometry + Dali::Geometry geometry = Dali::Geometry::New(); + geometry.AddVertexBuffer(vertexBuffer); + geometry.SetType(Dali::Geometry::TRIANGLE_STRIP); + + return geometry; +} + +} // namespace +namespace Dali +{ +namespace Toolkit +{ namespace Internal { -BubbleEmitter::BubbleEmitter( const Vector2& movementArea, - Image shapeImage, - unsigned int maximumNumberOfBubble, - const Vector2& bubbleSizeRange ) -: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ), - mMovementArea( movementArea ), - mShapeImage( shapeImage ), - mTotalNumOfBubble( maximumNumberOfBubble ), - mRenderTaskRunning(false), - mBubbleSizeRange( bubbleSizeRange ), - mCurrentUniform( 0 ), - mDensity( 5 ) +BubbleEmitter::BubbleEmitter(const Vector2& movementArea, + Texture shapeTexture, + unsigned int maximumNumberOfBubble, + const Vector2& bubbleSizeRange) +: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), + mShapeTexture(shapeTexture), + mMovementArea(movementArea), + mBubbleSizeRange(bubbleSizeRange), + mDensity(5), + mTotalNumOfBubble(maximumNumberOfBubble), + mCurrentBubble(0), + mRandomSeed(0), + mRenderTaskRunning(false) { - // Calculate how many BubbleEffect shaders are required - if( mTotalNumOfBubble>100 ) + // Calculate how many shaders are required + if(mTotalNumOfBubble > 100) { - mNumBubblePerShader = 100; - mNumShader = mTotalNumOfBubble / 100; + mNumBubblePerRenderer = 100; + mNumRenderer = mTotalNumOfBubble / 100; + if(mNumRenderer * mNumBubblePerRenderer < mTotalNumOfBubble) + { + mNumRenderer++; + mNumBubblePerRenderer = mTotalNumOfBubble / mNumRenderer + 1; + mTotalNumOfBubble = mNumRenderer * mNumBubblePerRenderer; + } } else { - mNumBubblePerShader = mTotalNumOfBubble; - mNumShader = 1; + mNumBubblePerRenderer = mTotalNumOfBubble; + mNumRenderer = 1; } + + mRandomSeed = time(NULL); } BubbleEmitter::~BubbleEmitter() { } -Toolkit::BubbleEmitter BubbleEmitter::New( const Vector2& winSize, - Image shapeImage, - unsigned int maximumNumberOfBubble, - const Vector2& bubbleSizeRange ) +Toolkit::BubbleEmitter BubbleEmitter::New(const Vector2& winSize, + Texture shapeTexture, + unsigned int maximumNumberOfBubble, + const Vector2& bubbleSizeRange) { // Create the implementation - IntrusivePtr internalBubbleEmitter ( new BubbleEmitter( winSize, shapeImage, - maximumNumberOfBubble,bubbleSizeRange ) ); + IntrusivePtr internalBubbleEmitter(new BubbleEmitter(winSize, shapeTexture, maximumNumberOfBubble, bubbleSizeRange)); // Pass ownership to Toolkit::BubbleEmitter handle - Toolkit::BubbleEmitter bubbleEmitter( *internalBubbleEmitter ); + Toolkit::BubbleEmitter bubbleEmitter(*internalBubbleEmitter); //Second phase of implementeation : Initialization internalBubbleEmitter->OnInitialize(); @@ -87,47 +159,34 @@ void BubbleEmitter::OnInitialize() { // Create the root actor, all the meshActor should be its children mBubbleRoot = Actor::New(); - mBubbleRoot.SetSize(mMovementArea); + mBubbleRoot.SetProperty(Actor::Property::SIZE, mMovementArea); + + // Prepare the frame buffer to store the color adjusted background texture + Vector2 imageSize = Vector2(mMovementArea.width / 4.f, mMovementArea.height / 4.f); + mFrameBuffer = FrameBuffer::New(imageSize.x, imageSize.y, FrameBuffer::Attachment::NONE); + mEffectTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, imageSize.x, imageSize.y); + mFrameBuffer.AttachColorTexture(mEffectTexture); - // Prepare the frame buffer to store the color adjusted background image - mEffectImage = FrameBufferImage::New( mMovementArea.width/4.f, mMovementArea.height/4.f, Pixel::RGBA8888, Dali::Image::UNUSED ); + // Generate the geometry, which is used by all bubbleActors + mMeshGeometry = CreateGeometry(mNumBubblePerRenderer * mDensity); - // Generate the material object, which is used by all meshActors - GenMaterial(); + Shader bubbleShader = CreateBubbleShader(mNumBubblePerRenderer); - mMesh.resize( mNumShader ); - mMeshActor.resize( mNumShader ); - mEffect.resize( mNumShader ); + mTextureSet = TextureSet::New(); + mTextureSet.SetTexture(0u, mEffectTexture); + mTextureSet.SetTexture(1u, mShapeTexture); - // Create the meshActor group and bubbleEffect group to emit bubbles following the given track, such as finger touch track. - MeshData meshData; - ConstructBubbleMesh( meshData, mNumBubblePerShader*mDensity); - for(unsigned int i=0; i < mNumShader; i++ ) + // Create the renderers to render the bubbles + mBubbleRenderers.resize(mNumRenderer); + for(unsigned int i = 0; i < mNumRenderer; i++) { - mMesh[i] = Mesh::New( meshData ); - mMeshActor[i] = MeshActor::New( mMesh[i] ); - mMeshActor[i].SetParentOrigin(ParentOrigin::TOP_LEFT); - mEffect[i] = BubbleEffect::New( mNumBubblePerShader ); - mEffect[i].SetEffectImage( mEffectImage ); - mEffect[i].SetMovementArea( mMovementArea ); - mMeshActor[i].SetShaderEffect( mEffect[i] ); - mBubbleRoot.Add( mMeshActor[i] ); + mBubbleRenderers[i].Initialize(mNumBubblePerRenderer, mMovementArea, mMeshGeometry, mTextureSet, bubbleShader); + mBubbleRoot.AddRenderer(mBubbleRenderers[i].GetRenderer()); } - // Create the extra meshActor and bubbleEffect to emit bubbles in totally random angle. - MeshData meshDataForNoise; - ConstructBubbleMesh( meshDataForNoise, mNumBubblePerShader); - mMeshActorForNoise = MeshActor::New( Mesh::New(meshDataForNoise) ); - mMeshActorForNoise.SetParentOrigin(ParentOrigin::TOP_LEFT); - mEffectForNoise = BubbleEffect::New( mNumBubblePerShader ); - mEffectForNoise.SetMovementArea( mMovementArea ); - mEffectForNoise.SetEffectImage( mEffectImage ); - mMeshActorForNoise.SetShaderEffect( mEffectForNoise ); - mBubbleRoot.Add( mMeshActorForNoise ); - // Create a cameraActor for the off screen render task. mCameraActor = CameraActor::New(mMovementArea); - mCameraActor.SetParentOrigin(ParentOrigin::CENTER); + mCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); Stage stage = Stage::GetCurrent(); @@ -140,61 +199,67 @@ Actor BubbleEmitter::GetRootActor() return mBubbleRoot; } -void BubbleEmitter::SetBackground( Image bgImage, const Vector3& hsvDelta ) +void BubbleEmitter::SetBackground(Texture bgTexture, const Vector3& hsvDelta) { - mBackgroundImage = bgImage; - mHSVDelta = hsvDelta; - - ImageActor sourceActor = ImageActor::New( bgImage ); - sourceActor.SetSize( mMovementArea ); - sourceActor.SetParentOrigin(ParentOrigin::CENTER); - Stage::GetCurrent().Add( sourceActor ); - - ColorAdjuster colorAdjuster = ColorAdjuster::New( hsvDelta, true /*ignore alpha to make bubble color always*/ ); - sourceActor.SetShaderEffect( colorAdjuster ); + mBackgroundTexture = bgTexture; + mHSVDelta = hsvDelta; + + //Create RenderTask source actor + Actor sourceActor = Actor::New(); + sourceActor.SetProperty(Actor::Property::SIZE, mMovementArea); + sourceActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + sourceActor.RegisterProperty("uHSVDelta", hsvDelta); + Stage::GetCurrent().Add(sourceActor); + + //Create renderer + Dali::Geometry geometry = CreateTexturedQuad(); + Shader shader = Shader::New(SHADER_BUBBLE_EMITTER_VERT, SHADER_BUBBLE_EMITTER_FRAG); + Renderer renderer = Renderer::New(geometry, shader); + TextureSet textureSet = TextureSet::New(); + textureSet.SetTexture(0u, bgTexture); + renderer.SetTextures(textureSet); + sourceActor.AddRenderer(renderer); RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); - RenderTask task = taskList.CreateTask(); - task.SetRefreshRate( RenderTask::REFRESH_ONCE ); - task.SetSourceActor( sourceActor ); + RenderTask task = taskList.CreateTask(); + task.SetRefreshRate(RenderTask::REFRESH_ONCE); + task.SetSourceActor(sourceActor); task.SetExclusive(true); task.SetCameraActor(mCameraActor); task.GetCameraActor().SetInvertYAxis(true); - task.SetTargetFrameBuffer( mEffectImage ); + task.SetFrameBuffer(mFrameBuffer); task.FinishedSignal().Connect(this, &BubbleEmitter::OnRenderFinished); mRenderTaskRunning = true; } -void BubbleEmitter::SetShapeImage( Image shapeImage ) +void BubbleEmitter::SetBubbleShape(Texture shapeTexture) { - mCustomMaterial.SetDiffuseTexture( shapeImage ); + mTextureSet.SetTexture(1, shapeTexture); } -void BubbleEmitter::SetBubbleScale( float scale ) +void BubbleEmitter::SetBubbleScale(float scale) { - for(unsigned int i=0; i < mNumShader; i++ ) + for(unsigned int i = 0; i < mNumRenderer; i++) { - mEffect[i].SetDynamicScale( scale ); + mBubbleRenderers[i].SetDynamicScale(scale); } - mEffectForNoise.SetDynamicScale( scale ); } -void BubbleEmitter::SetBubbleDensity( unsigned int density ) +void BubbleEmitter::SetBubbleDensity(unsigned int density) { - DALI_ASSERT_ALWAYS( density>0 && density<=9 && " Only densities between 1 to 9 are valid " ); + DALI_ASSERT_ALWAYS(density > 0 && density <= 9 && " Only densities between 1 to 9 are valid "); - if( density == mDensity ) + if(density == mDensity) { return; } else { - mDensity = density; - MeshData meshData; - ConstructBubbleMesh( meshData, mNumBubblePerShader*mDensity); - for(unsigned int i=0; i < mNumShader; i++ ) + mDensity = density; + mMeshGeometry = CreateGeometry(mNumBubblePerRenderer * mDensity); + for(unsigned int i = 0; i < mNumRenderer; i++) { - mMesh[i].UpdateMeshData(meshData); + mBubbleRenderers[i].SetGeometry(mMeshGeometry); } } } @@ -203,17 +268,8 @@ void BubbleEmitter::SetBubbleDensity( unsigned int density ) void BubbleEmitter::OnRenderFinished(RenderTask& source) { mRenderTaskRunning = false; - Actor sourceActor = source.GetSourceActor(); - if( sourceActor ) - { - RenderableActor renderable = RenderableActor::DownCast( sourceActor ); - if( renderable ) - { - renderable.RemoveShaderEffect(); - } - } - - Stage stage = Stage::GetCurrent(); + Actor sourceActor = source.GetSourceActor(); + Stage stage = Stage::GetCurrent(); stage.Remove(sourceActor); stage.GetRenderTaskList().RemoveTask(source); } @@ -222,187 +278,94 @@ void BubbleEmitter::OnContextRegained() { // Context was lost, so the framebuffer has been destroyed. Re-create render task // and trigger re-draw if not already running - if( ! mRenderTaskRunning ) - { - SetBackground( mBackgroundImage, mHSVDelta ); - } -} - -void BubbleEmitter::SetBlendMode( bool enable ) -{ - if(enable) - { - for(unsigned int i=0; i < mNumShader; i++ ) - { - // linear overlay - // TODO: if BlendColor would be public api from renderable actor, then can optimize the constant color - mMeshActor[i].SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE, - BlendingFactor::ZERO, BlendingFactor::ONE); - } - mMeshActorForNoise.SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE, - BlendingFactor::ZERO, BlendingFactor::ONE); - } - else - { - for(unsigned int i=0; i < mNumShader; i++ ) - { - // using default blend func - mMeshActor[i].SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA, - BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA ); - } - mMeshActorForNoise.SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA, - BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA ); - } -} - -void BubbleEmitter::EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement ) -{ - unsigned int curUniform = mCurrentUniform % mNumBubblePerShader; - unsigned int groupIdx = mCurrentUniform / mNumBubblePerShader; - SetBubbleParameter( mEffect[groupIdx], curUniform, emitPosition, direction, displacement); - animation.AnimateTo( Property( mEffect[groupIdx], mEffect[groupIdx].GetPercentagePropertyName(curUniform) ), - 1.f, AlphaFunction::LINEAR ); - - if( mCurrentUniform % mNumShader == 0 ) + if(!mRenderTaskRunning) { - unsigned int uniform = mCurrentUniform / mNumShader; - SetBubbleParameter(mEffectForNoise, uniform, emitPosition, displacement); - animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetPercentagePropertyName(uniform) ), - 1.f, AlphaFunction::LINEAR ); + SetBackground(mBackgroundTexture, mHSVDelta); } - - mCurrentUniform = (mCurrentUniform + 1) % mTotalNumOfBubble; } -void BubbleEmitter::StartExplosion( float duration, float multiple ) +void BubbleEmitter::EmitBubble(Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement) { - Animation animation = Animation::New( duration ); - for(unsigned int i=0; i < mNumShader; i++ ) - { - animation.AnimateTo( Property( mEffect[i], mEffect[i].GetMagnificationPropertyName() ), - multiple, AlphaFunction::EASE_OUT); - } - animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetMagnificationPropertyName() ), - multiple, AlphaFunction::EASE_OUT); - animation.Play(); - - animation.FinishedSignal().Connect(this, &BubbleEmitter::OnExplosionFinished); + unsigned int curUniform = mCurrentBubble % mNumBubblePerRenderer; + unsigned int groupIdx = mCurrentBubble / mNumBubblePerRenderer; + SetBubbleParameter(mBubbleRenderers[groupIdx], curUniform, emitPosition - Vector2(mMovementArea.x * 0.5f, mMovementArea.y * 0.5f), direction, displacement); + animation.AnimateTo(mBubbleRenderers[groupIdx].GetPercentageProperty(curUniform), + 1.f, + AlphaFunction::LINEAR); + + mCurrentBubble = (mCurrentBubble + 1) % mTotalNumOfBubble; } void BubbleEmitter::Restore() { - for(unsigned int i=0; i < mNumShader; i++ ) + for(unsigned int i = 0; i < mNumRenderer; i++) { - mEffect[i].ResetParameters(); + mBubbleRenderers[i].ResetProperties(); } - mEffectForNoise.ResetParameters(); } -void BubbleEmitter::GenMaterial() +Geometry BubbleEmitter::CreateGeometry(unsigned int numOfPatch) { - mCustomMaterial = Material::New("CustomMaterial"); - mCustomMaterial.SetOpacity(1.0f); - mCustomMaterial.SetDiffuseColor(Color::WHITE); - mCustomMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0)); - mCustomMaterial.SetMapU( Material::MAPPING_MODE_WRAP ); - mCustomMaterial.SetMapV( Material::MAPPING_MODE_WRAP ); - mCustomMaterial.SetDiffuseTexture( mShapeImage ); -} + unsigned int numVertex = numOfPatch * 4u; + Vector vertexData; + vertexData.Reserve(numVertex); -void BubbleEmitter::AddVertex(MeshData::VertexContainer& vertices, Vector3 XYZ, Vector2 UV) -{ - MeshData::Vertex meshVertex; - meshVertex.x = XYZ.x; - meshVertex.y = XYZ.y; - meshVertex.z = XYZ.z; - meshVertex.u = UV.x; - meshVertex.v = UV.y; - vertices.push_back(meshVertex); -} + unsigned int numIndex = numOfPatch * 6u; + Vector indexData; + indexData.Reserve(numIndex); -void BubbleEmitter::AddTriangle(MeshData::FaceIndices& faces, -size_t v0, size_t v1, size_t v2) -{ - faces.push_back(v0); - faces.push_back(v1); - faces.push_back(v2); -} - -void BubbleEmitter::ConstructBubbleMesh( MeshData& meshData, unsigned int numOfBubble) -{ - MeshData::VertexContainer vertices; - MeshData::FaceIndices faces; - BoneContainer bones(0); - - for(unsigned int index = 0; index < numOfBubble; index ++) + for(unsigned int i = 0; i < numOfPatch; i++) { - float curSize = RandomRange(mBubbleSizeRange.x, mBubbleSizeRange.y); - if(rand()%100 < 1) - { - curSize *= 2.f; - } - float depth = static_cast( index ); - AddVertex( vertices, Vector3(0.f,0.f,depth), Vector2(0.f,0.f) ); - AddVertex( vertices, Vector3(0.f,curSize,depth), Vector2( 0.f,1.f )); - AddVertex( vertices, Vector3(curSize,curSize,depth), Vector2(1.f,1.f) ); - AddVertex( vertices, Vector3(curSize,0.f,depth), Vector2(1.f,0.f) ); - - unsigned int idx = index * 4; - AddTriangle( faces, idx, idx+1, idx+2); - AddTriangle( faces, idx, idx+2, idx+3); + float halfSize = RandomRange(mBubbleSizeRange.x, mBubbleSizeRange.y, mRandomSeed) * 0.5f; + + float index = static_cast(i); + vertexData.PushBack(Vertex(index, Vector2(-halfSize, -halfSize), Vector2(0.f, 0.f))); + vertexData.PushBack(Vertex(index, Vector2(-halfSize, halfSize), Vector2(0.f, 1.f))); + vertexData.PushBack(Vertex(index, Vector2(halfSize, halfSize), Vector2(1.f, 1.f))); + vertexData.PushBack(Vertex(index, Vector2(halfSize, -halfSize), Vector2(1.f, 0.f))); + + unsigned short idx = index * 4; + indexData.PushBack(idx); + indexData.PushBack(idx + 1); + indexData.PushBack(idx + 2); + indexData.PushBack(idx); + indexData.PushBack(idx + 2); + indexData.PushBack(idx + 3); } - meshData.SetData(vertices, faces, bones, mCustomMaterial); - meshData.SetHasColor(false); - meshData.SetHasTextureCoords(true); -} + Property::Map vertexFormat; + vertexFormat["aIndex"] = Property::FLOAT; + vertexFormat["aPosition"] = Property::VECTOR2; + vertexFormat["aTexCoord"] = Property::VECTOR2; + VertexBuffer vertices = VertexBuffer::New(vertexFormat); + vertices.SetData(&vertexData[0], numVertex); -void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform, - const Vector2& emitPosition, const Vector2& displacement ) -{ - int halfRange = displacement.x / 2; - Vector2 randomVec(rand()%static_cast(displacement.x) - halfRange, rand()%static_cast(displacement.y) - halfRange); - if(randomVec.y > 0.0f) - { - randomVec.y *= 0.33f; - } - - Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y ); - effect.SetStartAndEndPosition( curUniform, startAndEndPos ); + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer(vertices); + geometry.SetIndexBuffer(&indexData[0], numIndex); - effect.SetPercentage( curUniform, 0.f); + return geometry; } -void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform, - const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement ) +void BubbleEmitter::SetBubbleParameter(BubbleRenderer& bubbleRenderer, unsigned int curUniform, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement) { Vector2 dir(direction); int halfRange = displacement.x / 2; // for the y coordinate, always negative, so bubbles always go upwards - Vector2 randomVec(rand()%static_cast(displacement.x) - halfRange, -rand()%static_cast(displacement.y)); + Vector2 randomVec(rand_r(&mRandomSeed) % static_cast(displacement.x) - halfRange, -rand_r(&mRandomSeed) % static_cast(displacement.y)); dir.Normalize(); - randomVec.x -= dir.x*halfRange; - randomVec.y *= 1.0f - fabsf(dir.x)*0.33f; + randomVec.x -= dir.x * halfRange; + randomVec.y *= 1.0f - fabsf(dir.x) * 0.33f; if(randomVec.y > 0.0f) { randomVec.y *= 0.33f; } - Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y ); - effect.SetStartAndEndPosition( curUniform, startAndEndPos ); - - effect.SetPercentage( curUniform, 0.f); -} + Vector4 startAndEndPos(emitPosition.x, emitPosition.y, emitPosition.x + randomVec.x, emitPosition.y + randomVec.y); + bubbleRenderer.SetStartAndEndPosition(curUniform, startAndEndPos); -void BubbleEmitter::OnExplosionFinished( Animation& source ) -{ - Restore(); -} - -float BubbleEmitter::RandomRange(float f0, float f1) -{ - return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f); + bubbleRenderer.SetPercentage(curUniform, 0.f); } } // namespace Internal