1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "fb.h"
#include "rototiller.h"
#include "util.h"
#include "particles.h"
/* particle system gadget (C) Vito Caputo <vcaputo@pengaru.com> 2/15/2014 */
/* 1/10/2015 added octree bsp (though not yet leveraged) */
/* 11/25/2016 refactor and begun adapting to rototiller */
#define INIT_PARTS 100
typedef struct sparkler_context_t {
particles_t *particles;
unsigned n_cpus;
} sparkler_context_t;
extern particle_ops_t simple_ops;
static void * sparkler_create_context(void)
{
static int initialized;
sparkler_context_t *ctxt;
if (!initialized) {
srand(time(NULL) + getpid());
initialized = 1;
}
ctxt = calloc(1, sizeof(sparkler_context_t));
if (!ctxt)
return NULL;
ctxt->particles = particles_new();
if (!ctxt->particles) {
free(ctxt);
return NULL;
}
particles_add_particles(ctxt->particles, NULL, &simple_ops, INIT_PARTS);
return ctxt;
}
static void sparkler_destroy_context(void *context)
{
sparkler_context_t *ctxt = context;
particles_free(ctxt->particles);
free(ctxt);
}
static int sparkler_fragmenter(void *context, const fb_fragment_t *fragment, unsigned num, fb_fragment_t *res_fragment)
{
sparkler_context_t *ctxt = context;
return fb_fragment_slice_single(fragment, ctxt->n_cpus, num, res_fragment);
}
static void sparkler_prepare_frame(void *context, unsigned ncpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
sparkler_context_t *ctxt = context;
*res_fragmenter = sparkler_fragmenter;
ctxt->n_cpus = ncpus;
particles_sim(ctxt->particles);
particles_add_particles(ctxt->particles, NULL, &simple_ops, INIT_PARTS / 4);
particles_age(ctxt->particles);
}
/* Render a 3D particle system */
static void sparkler_render_fragment(void *context, fb_fragment_t *fragment)
{
sparkler_context_t *ctxt = context;
fb_fragment_zero(fragment);
particles_draw(ctxt->particles, fragment);
}
rototiller_module_t sparkler_module = {
.create_context = sparkler_create_context,
.destroy_context = sparkler_destroy_context,
.prepare_frame = sparkler_prepare_frame,
.render_fragment = sparkler_render_fragment,
.name = "sparkler",
.description = "Particle system with spatial interactions (threaded (poorly))",
.author = "Vito Caputo <vcaputo@pengaru.com>",
.license = "GPLv2",
};
|