Merge "Reduced complexity of dali-table-view" into devel/master
[platform/core/uifw/dali-demo.git] / examples / particles / particle-field.h
1 #ifndef PARTICLES_PARTICLE_FIELD_H_
2 #define PARTICLES_PARTICLE_FIELD_H_
3 /*
4  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19 #include "utils.h"
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"
25 #include <vector>
26
27 struct ParticleField
28 {
29   float mSize;
30   Dali::Vector3 mBoxSize;
31   Dali::Vector3 mParticlesPerAxis;
32   float mSizeVariance;
33   float mNoiseAmount;    // affects color, motion (phase), twinkle (frequency, phase, size, opacity),
34   float mDisperse;
35   float mMotionScale;
36   float mMotionCycleLength;    // seconds
37   float mTwinkleFrequency;    // per motion cycle
38   float mTwinkleSizeScale;
39   float mTwinkleOpacityWeight;
40
41   Dali::Vector3 GetParticlesPerAxisSafe() const
42   {
43     using namespace Dali;
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)));
47   }
48
49   Dali::Geometry MakeGeometry() const
50   {
51     using namespace Dali;
52     FloatRand frandPath;
53     FloatRand frandSeed;
54     FloatRand frandPos;
55     FloatRand frandDisperse;
56     FloatRand frandSize;
57
58     struct Vertex
59     {
60       Vector3 aPosition;
61       float aSeed;
62       Vector4 aPath;
63       Vector2 aSubPosition;
64       float aSize;
65     };
66
67     const int numPatternVertices = 6;
68     Vector2 vertexPattern[numPatternVertices] = {
69       Vector2(-1.f, 1.f),
70       Vector2(-1.f, -1.f),
71       Vector2(1.f, 1.f),
72       Vector2(1.f, 1.f),
73       Vector2(-1.f, -1.f),
74       Vector2(1.f, -1.f),
75     };
76
77     Vector3 particlesPerAxis = GetParticlesPerAxisSafe();
78     auto numParticles = particlesPerAxis.x * particlesPerAxis.y * particlesPerAxis.z;
79
80     std::vector<Vertex> vertices;
81     vertices.reserve(numParticles * numPatternVertices);
82
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;
92     int nxy = nx * ny;
93     for (size_t i = 0; i < numParticles; ++i)
94     {
95       Vertex v;
96       v.aPosition = Vector3((i % nx) * spacing.x, (i / nx) % ny * spacing.y, (i / nxy) * spacing.z) - offset;
97
98       Vector3 disperseDir(frandDisperse() - .5, frandDisperse() - .5, frandDisperse() - .5);
99       disperseDir.Normalize();
100
101       v.aPosition += disperseDir * (frandDisperse() * mDisperse);
102       v.aPosition *= invBoxSize;
103
104       v.aSeed = frandSeed() * mNoiseAmount;
105       v.aPath = Vector4(frandPath() - .5, frandPath() - .5, frandPath() - .5, frandPath() - .5) * mMotionScale;
106
107       const float size = mSize * ((1.f + (frandSize() - .5) * mSizeVariance) * .5f);
108       for (int j = 0; j < numPatternVertices; ++j)
109       {
110         v.aSubPosition = vertexPattern[j];
111         v.aSize = size;
112         vertices.push_back(v);
113       }
114     }
115
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 )
122     );
123     vertexBuffer.SetData( vertices.data(), vertices.size() );
124
125     Geometry geometry = Geometry::New();
126     geometry.AddVertexBuffer( vertexBuffer );
127     geometry.SetType( Geometry::TRIANGLES );
128     return geometry;
129   }
130 };
131
132 #endif //PARTICLES_PARTICLE_FIELD_H_