Welcome to mirror list, hosted at ThFree Co, Russian Federation.

BKE_particle.h « blenkernel « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b6be72fadd3ef78fd0c311033b1b276ed155d2bb (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
/*
 * ***** BEGIN GPL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * The Original Code is Copyright (C) 2007 by Janne Karhu.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Adaptive time step
 * Classical SPH
 * Copyright 2011-2012 AutoCRC
 *
 * ***** END GPL LICENSE BLOCK *****
 */

#ifndef __BKE_PARTICLE_H__
#define __BKE_PARTICLE_H__

/** \file BKE_particle.h
 *  \ingroup bke
 */

#include "DNA_particle_types.h"
#include "DNA_object_types.h"

struct ParticleSystemModifierData;
struct ParticleSystem;
struct ParticleKey;
struct ParticleSettings;
struct HairKey;

struct Main;
struct Group;
struct Object;
struct Scene;
struct DerivedMesh;
struct ModifierData;
struct MTFace;
struct MCol;
struct MFace;
struct MVert;
struct IpoCurve;
struct LatticeDeformData;
struct LinkNode;
struct KDTree;
struct RNG;
struct SurfaceModifierData;
struct BVHTreeRay;
struct BVHTreeRayHit; 
struct EdgeHash;

#define PARTICLE_P              ParticleData * pa; int p
#define LOOP_PARTICLES  for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++)
#define LOOP_EXISTING_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) if (!(pa->flag & PARS_UNEXIST))
#define LOOP_SHOWN_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) if (!(pa->flag & (PARS_UNEXIST | PARS_NO_DISP)))
/* OpenMP: Can only advance one variable within loop definition. */
#define LOOP_DYNAMIC_PARTICLES for (p = 0; p < psys->totpart; p++) if ((pa = psys->particles + p)->state.time > 0.0f)

#define PSYS_FRAND_COUNT    1024
#define PSYS_FRAND(seed)    psys->frand[(seed) % PSYS_FRAND_COUNT]

/* fast but sure way to get the modifier*/
#define PARTICLE_PSMD ParticleSystemModifierData * psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)

/* common stuff that many particle functions need */
typedef struct ParticleSimulationData {
	struct Scene *scene;
	struct Object *ob;
	struct ParticleSystem *psys;
	struct ParticleSystemModifierData *psmd;
	struct ListBase *colliders;
	/* Courant number. This is used to implement an adaptive time step. Only the
	 * maximum value per time step is important. Only sph_integrate makes use of
	 * this at the moment. Other solvers could, too. */
	float courant_num;
} ParticleSimulationData;

typedef struct SPHData {
	ParticleSystem *psys[10];
	ParticleData *pa;
	float mass;
	struct EdgeHash *eh;
	float *gravity;
	float hfac;
	/* Average distance to neighbours (other particles in the support domain),
	 * for calculating the Courant number (adaptive time step). */
	int pass;
	float element_size;
	float flow[3];

	/* Integrator callbacks. This allows different SPH implementations. */
	void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
	void (*density_cb) (void *rangedata_v, int index, float squared_dist);
} SPHData;

typedef struct ParticleTexture {
	float ivel;                           /* used in reset */
	float time, life, exist, size;        /* used in init */
	float damp, gravity, field;           /* used in physics */
	float length, clump, kink, effector;  /* used in path caching */
	float rough1, rough2, roughe;         /* used in path caching */
} ParticleTexture;

typedef struct ParticleSeam {
	float v0[3], v1[3];
	float nor[3], dir[3], tan[3];
	float length2;
} ParticleSeam;

typedef struct ParticleCacheKey {
	float co[3];
	float vel[3];
	float rot[4];
	float col[3];
	float time;
	int steps;
} ParticleCacheKey;

typedef struct ParticleThreadContext {
	/* shared */
	struct ParticleSimulationData sim;
	struct DerivedMesh *dm;
	struct Material *ma;

	/* distribution */
	struct KDTree *tree;

	struct ParticleSeam *seams;
	int totseam;

	float *jit, *jitoff, *weight;
	float maxweight;
	int *index, *skip, jitlevel;

	int from, cfrom, distr;

	struct ParticleData *tpars;

	/* path caching */
	int editupdate, between, steps;
	int totchild, totparent, parent_pass;

	float cfra;

	float *vg_length, *vg_clump, *vg_kink;
	float *vg_rough1, *vg_rough2, *vg_roughe;
	float *vg_effector;
} ParticleThreadContext;

typedef struct ParticleThread {
	ParticleThreadContext *ctx;
	struct RNG *rng, *rng_path;
	int num, tot;
} ParticleThread;

typedef struct ParticleBillboardData {
	struct Object *ob;
	float vec[3], vel[3];
	float offset[2];
	float size[2];
	float tilt, random, time;
	int uv[3];
	int lock, num;
	int totnum;
	int lifetime;
	short align, uv_split, anim, split_offset;
} ParticleBillboardData;

typedef struct ParticleCollisionElement {
	/* pointers to original data */
	float *x[4], *v[4];

	/* values interpolated from original data*/
	float x0[3], x1[3], x2[3], p[3];
	
	/* results for found intersection point */
	float nor[3], vel[3], uv[2];

	/* count of original data (1-4) */
	int tot;

	/* index of the collision face */
	int index;

	/* flags for inversed normal / particle already inside element at start */
	short inv_nor, inside;
} ParticleCollisionElement;

/* container for moving data between deflet_particle and particle_intersect_face */
typedef struct ParticleCollision {
	struct Object *current;
	struct Object *hit;
	struct Object *prev;
	struct Object *skip;
	struct Object *emitter;

	struct CollisionModifierData *md; // collision modifier for current object;

	float f;    // time factor of previous collision, needed for substracting face velocity
	float fac1, fac2;

	float cfra, old_cfra;

	float original_ray_length; //original length of co2-co1, needed for collision time evaluation

	int prev_index;

	ParticleCollisionElement pce;

	/* total_time is the amount of time in this subframe
	 * inv_total_time is the opposite
	 * inv_timestep is the inverse of the amount of time in this frame */
	float total_time, inv_total_time, inv_timestep;

	float radius;
	float co1[3], co2[3];
	float ve1[3], ve2[3];

	float acc[3], boid_z;

	int boid;
} ParticleCollision;

typedef struct ParticleDrawData {
	float *vdata, *vd;      /* vertice data */
	float *ndata, *nd;      /* normal data */
	float *cdata, *cd;      /* color data */
	float *vedata, *ved;    /* velocity data */
	float *ma_col;
	int tot_vec_size, flag;
	int totpoint, totve;
} ParticleDrawData;

#define PARTICLE_DRAW_DATA_UPDATED  1

/* ----------- functions needed outside particlesystem ---------------- */
/* particle.c */
int count_particles(struct ParticleSystem *psys);
int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);

struct ParticleSystem *psys_get_current(struct Object *ob);
/* for rna */
short psys_get_current_num(struct Object *ob);
void psys_set_current_num(Object *ob, int index);
/* UNUSED */
// struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);

struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);

int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
int psys_check_edited(struct ParticleSystem *psys);

void psys_check_group_weights(struct ParticleSettings *part);
int psys_uses_gravity(struct ParticleSimulationData *sim);

/* free */
void BKE_particlesettings_free(struct ParticleSettings *part);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
void psys_free(struct Object *ob, struct ParticleSystem *psys);

void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);

void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]);
void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], struct MCol *mc);

void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);

void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache,
                              float fuv[4], float foffset, float vec[3], float nor[3],
                              float utan[3], float vtan[3], float orco[3], float ornor[3]);
struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);

struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name);
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
struct ParticleSettings *psys_new_settings(const char *name, struct Main *main);
struct ParticleSettings *BKE_particlesettings_copy(struct ParticleSettings *part);
void BKE_particlesettings_make_local(struct ParticleSettings *part);

void psys_reset(struct ParticleSystem *psys, int mode);

void psys_find_parents(struct ParticleSimulationData *sim);

void psys_cache_paths(struct ParticleSimulationData *sim, float cfra);
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra);
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate);
int do_guides(struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
float psys_get_timestep(struct ParticleSimulationData *sim);
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel);
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);

void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata);
void psys_sph_finalise(struct SPHData *sphdata);
void psys_sph_density(struct BVHTree *tree, struct SPHData *data, float co[3], float vars[2]);

/* for anim.c */
void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part,
                            struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa,
                            float uv[2], float orco[3]);
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa,
                                   struct ParticleCacheKey *cache, float mat[4][4], float *scale);

ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
void psys_threads_free(ParticleThread *threads);

void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);

/* particle_system.c */
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
void psys_count_keyed_targets(struct ParticleSimulationData *sim);
void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
void psys_changed_type(struct Object *ob, struct ParticleSystem *psys);

void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);

void psys_check_boid_data(struct ParticleSystem *psys);

void psys_get_birth_coordinates(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra);

void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);

/* ----------- functions needed only inside particlesystem ------------ */
/* particle.c */
void psys_disable_all(struct Object *ob);
void psys_enable_all(struct Object *ob);

void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
void free_keyed_keys(struct ParticleSystem *psys);
void psys_free_particles(struct ParticleSystem *psys);
void psys_free_children(struct ParticleSystem *psys);

void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity);
void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]);
void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);

float psys_get_dietime_from_cache(struct PointCache *cache, int index);

void psys_free_pdd(struct ParticleSystem *psys);

float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra);
void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface,
                           float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3],
                           float orco[3], float ornor[3]);
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time);

/* BLI_bvhtree_ray_cast callback */
void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache,
                         const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
                         float orco[3], float ornor[3]);

/* particle_system.c */
void initialize_particle(struct ParticleData *pa);
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node);

void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);

float psys_get_current_display_percentage(struct ParticleSystem *psys);

/* psys_reset */
#define PSYS_RESET_ALL          1
#define PSYS_RESET_DEPSGRAPH    2
/* #define PSYS_RESET_CHILDREN  3 */ /*UNUSED*/
#define PSYS_RESET_CACHE_MISS   4

/* index_dmcache */
#define DMCACHE_NOTFOUND    -1
#define DMCACHE_ISCHILD     -2

#endif