Fixed SVACE defects in Particles example.
[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       float x = float(i % nx);
97       float y = float((i / nx) % ny);
98       float z = float(i / nxy);
99       v.aPosition = Vector3(x, y, z) * spacing - offset;
100
101       Vector3 disperseDir(frandDisperse() - .5, frandDisperse() - .5, frandDisperse() - .5);
102       disperseDir.Normalize();
103
104       v.aPosition += disperseDir * (frandDisperse() * mDisperse);
105       v.aPosition *= invBoxSize;
106
107       v.aSeed = frandSeed() * mNoiseAmount;
108       v.aPath = Vector4(frandPath() - .5, frandPath() - .5, frandPath() - .5, frandPath() - .5) * mMotionScale;
109
110       const float size = mSize * ((1.f + (frandSize() - .5) * mSizeVariance) * .5f);
111       for (int j = 0; j < numPatternVertices; ++j)
112       {
113         v.aSubPosition = vertexPattern[j];
114         v.aSize = size;
115         vertices.push_back(v);
116       }
117     }
118
119     VertexBuffer vertexBuffer = VertexBuffer::New( Property::Map()
120       .Add( "aPosition", Property::VECTOR3 )
121       .Add( "aSeed", Property::FLOAT )
122       .Add( "aPath", Property::VECTOR4 )
123       .Add( "aSubPosition", Property::VECTOR2 )
124       .Add( "aSize", Property::FLOAT )
125     );
126     vertexBuffer.SetData( vertices.data(), vertices.size() );
127
128     Geometry geometry = Geometry::New();
129     geometry.AddVertexBuffer( vertexBuffer );
130     geometry.SetType( Geometry::TRIANGLES );
131     return geometry;
132   }
133 };
134
135 #endif //PARTICLES_PARTICLE_FIELD_H_