1 #ifndef PARTICLES_PARTICLE_FIELD_H_
2 #define PARTICLES_PARTICLE_FIELD_H_
4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include "float-rand.h"
21 #include "dali/public-api/math/vector2.h"
22 #include "dali/public-api/math/vector3.h"
23 #include "dali/public-api/math/vector4.h"
24 #include "dali/public-api/rendering/geometry.h"
30 Dali::Vector3 mBoxSize;
31 Dali::Vector3 mParticlesPerAxis;
33 float mNoiseAmount; // affects color, motion (phase), twinkle (frequency, phase, size, opacity),
36 float mMotionCycleLength; // seconds
37 float mTwinkleFrequency; // per motion cycle
38 float mTwinkleSizeScale;
39 float mTwinkleOpacityWeight;
41 Dali::Vector3 GetParticlesPerAxisSafe() const
44 return Vector3(std::max(1.f, FastFloor(mParticlesPerAxis.x)),
45 std::max(1.f, FastFloor(mParticlesPerAxis.y)),
46 std::max(1.f, FastFloor(mParticlesPerAxis.z)));
49 Dali::Geometry MakeGeometry() const
55 FloatRand frandDisperse;
67 const int numPatternVertices = 6;
68 Vector2 vertexPattern[numPatternVertices] = {
77 Vector3 particlesPerAxis = GetParticlesPerAxisSafe();
78 auto numParticles = particlesPerAxis.x * particlesPerAxis.y * particlesPerAxis.z;
80 std::vector<Vertex> vertices;
81 vertices.reserve(numParticles * numPatternVertices);
83 Vector3 invBoxSize(1. / std::max(mBoxSize.x, 1.f),
84 1. / std::max(mBoxSize.y, 1.f),
85 1. / std::max(mBoxSize.z, 1.f));
86 Vector3 spacing(mBoxSize.x / particlesPerAxis.x,
87 mBoxSize.y / particlesPerAxis.y,
88 mBoxSize.z / particlesPerAxis.z);
89 auto offset = (mBoxSize - spacing) * .5;
90 int nx = particlesPerAxis.x;
91 int ny = particlesPerAxis.y;
93 for (size_t i = 0; i < numParticles; ++i)
96 v.aPosition = Vector3((i % nx) * spacing.x, (i / nx) % ny * spacing.y, (i / nxy) * spacing.z) - offset;
98 Vector3 disperseDir(frandDisperse() - .5, frandDisperse() - .5, frandDisperse() - .5);
99 disperseDir.Normalize();
101 v.aPosition += disperseDir * (frandDisperse() * mDisperse);
102 v.aPosition *= invBoxSize;
104 v.aSeed = frandSeed() * mNoiseAmount;
105 v.aPath = Vector4(frandPath() - .5, frandPath() - .5, frandPath() - .5, frandPath() - .5) * mMotionScale;
107 const float size = mSize * ((1.f + (frandSize() - .5) * mSizeVariance) * .5f);
108 for (int j = 0; j < numPatternVertices; ++j)
110 v.aSubPosition = vertexPattern[j];
112 vertices.push_back(v);
116 VertexBuffer vertexBuffer = VertexBuffer::New( Property::Map()
117 .Add( "aPosition", Property::VECTOR3 )
118 .Add( "aSeed", Property::FLOAT )
119 .Add( "aPath", Property::VECTOR4 )
120 .Add( "aSubPosition", Property::VECTOR2 )
121 .Add( "aSize", Property::FLOAT )
123 vertexBuffer.SetData( vertices.data(), vertices.size() );
125 Geometry geometry = Geometry::New();
126 geometry.AddVertexBuffer( vertexBuffer );
127 geometry.SetType( Geometry::TRIANGLES );
132 #endif //PARTICLES_PARTICLE_FIELD_H_