Blender V4.3
scene/particles.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "scene/particles.h"
6#include "device/device.h"
7#include "scene/scene.h"
8#include "scene/stats.h"
9
10#include "util/foreach.h"
11#include "util/hash.h"
12#include "util/log.h"
13#include "util/map.h"
14#include "util/progress.h"
15#include "util/vector.h"
16
18
19/* Particle System */
20
22{
23 NodeType *type = NodeType::add("particle_system", create);
24 return type;
25}
26
27ParticleSystem::ParticleSystem() : Node(get_node_type()) {}
28
30
32{
33 scene->particle_system_manager->tag_update(scene);
34}
35
36/* Particle System Manager */
37
39{
40 need_update_ = true;
41}
42
44
46 DeviceScene *dscene,
47 Scene *scene,
48 Progress &progress)
49{
50 /* count particles.
51 * adds one dummy particle at the beginning to avoid invalid lookups,
52 * in case a shader uses particle info without actual particle data. */
53 int num_particles = 1;
54 for (size_t j = 0; j < scene->particle_systems.size(); j++) {
55 num_particles += scene->particle_systems[j]->particles.size();
56 }
57
58 KernelParticle *kparticles = dscene->particles.alloc(num_particles);
59
60 /* dummy particle */
61 memset(kparticles, 0, sizeof(KernelParticle));
62
63 int i = 1;
64 for (size_t j = 0; j < scene->particle_systems.size(); j++) {
65 ParticleSystem *psys = scene->particle_systems[j];
66
67 for (size_t k = 0; k < psys->particles.size(); k++) {
68 /* pack in texture */
69 Particle &pa = psys->particles[k];
70
71 kparticles[i].index = pa.index;
72 kparticles[i].age = pa.age;
73 kparticles[i].lifetime = pa.lifetime;
74 kparticles[i].size = pa.size;
75 kparticles[i].rotation = pa.rotation;
76 kparticles[i].location = float3_to_float4(pa.location);
77 kparticles[i].velocity = float3_to_float4(pa.velocity);
79
80 i++;
81
82 if (progress.get_cancel()) {
83 return;
84 }
85 }
86 }
87
88 dscene->particles.copy_to_device();
89}
90
92 DeviceScene *dscene,
93 Scene *scene,
94 Progress &progress)
95{
96 if (!need_update()) {
97 return;
98 }
99
100 scoped_callback_timer timer([scene](double time) {
101 if (scene->update_stats) {
102 scene->update_stats->particles.times.add_entry({"device_update", time});
103 }
104 });
105
106 VLOG_INFO << "Total " << scene->particle_systems.size() << " particle systems.";
107
108 device_free(device, dscene);
109
110 progress.set_status("Updating Particle Systems", "Copying Particles to device");
111 device_update_particles(device, dscene, scene, progress);
112
113 if (progress.get_cancel()) {
114 return;
115 }
116
117 need_update_ = false;
118}
119
121{
122 dscene->particles.free();
123}
124
126{
127 need_update_ = true;
128}
129
131{
132 return need_update_;
133}
134
device_vector< KernelParticle > particles
Definition devicescene.h:80
void device_free(Device *device, DeviceScene *dscene)
void tag_update(Scene *scene)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
bool get_cancel() const
Definition progress.h:93
T * alloc(size_t width, size_t height=0, size_t depth=0)
#define CCL_NAMESPACE_END
#define VLOG_INFO
Definition log.h:72
#define NODE_DEFINE(structname)
Definition node_type.h:148
float4 angular_velocity
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
ParticleData * particles
NODE_DECLARE ParticleSystem()
void tag_update(Scene *scene)
float age
Definition particles.h:24
float3 location
Definition particles.h:26
float size
Definition particles.h:28
float4 rotation
Definition particles.h:27
float3 velocity
Definition particles.h:29
float3 angular_velocity
Definition particles.h:30
int index
Definition particles.h:23
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition util/math.h:540
wmTimer * timer