Page MenuHome

fluidDensity_r42811_1_svn.patch

Authored By
Alex Fraser (adfries)
Nov 13 2013, 4:23 PM
Size
37 KB
Subscribers
None

fluidDensity_r42811_1_svn.patch

Index: b/blender/release/scripts/startup/bl_ui/properties_texture.py
===================================================================
--- a/blender/release/scripts/startup/bl_ui/properties_texture.py (HEAD)
+++ b/blender/release/scripts/startup/bl_ui/properties_texture.py (working copy)
@@ -778,6 +778,38 @@ class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel):
col.prop(pd, "turbulence_strength")
+class TEXTURE_PT_fluiddensity(TextureButtonsPanel, bpy.types.Panel):
+ bl_label = "Fluid Density"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ @classmethod
+ def poll(cls, context):
+ tex = context.texture
+ engine = context.scene.render.engine
+ return tex and (tex.type == 'FLUID_DENSITY' and (engine in cls.COMPAT_ENGINES))
+
+ def draw(self, context):
+ layout = self.layout
+
+ tex = context.texture
+ fd = tex.fluid_density
+
+ split = layout.split(percentage=0.3)
+ split.label(text="Object:")
+ split.prop(fd, "object", text="")
+
+ sub = layout.column()
+ sub.enabled = bool(fd.object)
+ if fd.object:
+ split = sub.split(percentage=0.3)
+ split.label(text="System:")
+ split.prop_search(fd, "particle_system", fd.object, "particle_systems", text="")
+
+ split = layout.split(percentage=0.3)
+ split.label(text="Sample Source:")
+ split.prop(fd, "sample_source", expand=True)
+
+
class TEXTURE_PT_ocean(TextureTypePanel, Panel):
bl_label = "Ocean"
tex_type = 'OCEAN'
Index: b/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- a/blender/source/blender/blenkernel/BKE_particle.h (HEAD)
+++ b/blender/source/blender/blenkernel/BKE_particle.h (working copy)
@@ -58,6 +58,7 @@ 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++)
@@ -84,6 +85,22 @@ typedef struct ParticleSimulationData {
float courant_num;
} ParticleSimulationData;
+typedef struct SPHData {
+ ParticleSystem *psys[10];
+ ParticleData *pa;
+ float mass;
+ struct EdgeHash *eh;
+ float *gravity;
+ /* Average distance to neighbours (other particles in the support domain),
+ for calculating the Courant number (adaptive time step). */
+ 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 */
@@ -283,6 +300,10 @@ float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa
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, float *orco);
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
@@ -296,6 +317,7 @@ void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct Part
/* 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_bvhtree(struct ParticleSystem *psys, float cfra);
void psys_update_particle_tree(struct ParticleSystem *psys, float cfra);
void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
Index: b/blender/source/blender/blenkernel/BKE_texture.h
===================================================================
--- a/blender/source/blender/blenkernel/BKE_texture.h (HEAD)
+++ b/blender/source/blender/blenkernel/BKE_texture.h (working copy)
@@ -50,6 +50,7 @@ struct OceanTex;
struct ParticleSettings;
struct PluginTex;
struct PointDensity;
+struct FluidDensity;
struct Tex;
struct TexMapping;
struct VoxelData;
@@ -121,6 +122,11 @@ void BKE_free_pointdensity(struct PointDensity *pd);
struct PointDensity *BKE_add_pointdensity(void);
struct PointDensity *BKE_copy_pointdensity(struct PointDensity *pd);
+void BKE_free_fluiddensitydata(struct FluidDensity *pd);
+void BKE_free_fluiddensity(struct FluidDensity *fd);
+struct FluidDensity *BKE_add_fluiddensity(void);
+struct FluidDensity *BKE_copy_fluiddensity(struct FluidDensity *fd);
+
void BKE_free_voxeldatadata(struct VoxelData *vd);
void BKE_free_voxeldata(struct VoxelData *vd);
struct VoxelData *BKE_add_voxeldata(void);
Index: b/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- a/blender/source/blender/blenkernel/intern/object.c (HEAD)
+++ b/blender/source/blender/blenkernel/intern/object.c (working copy)
@@ -561,6 +561,7 @@ void unlink_object(Object *ob)
for(tex= bmain->tex.first; tex; tex= tex->id.next) {
if(tex->env && (ob==tex->env->object)) tex->env->object= NULL;
if(tex->pd && (ob==tex->pd->object)) tex->pd->object= NULL;
+ if(tex->fd && (ob==tex->fd->object)) tex->fd->object= NULL;
if(tex->vd && (ob==tex->vd->object)) tex->vd->object= NULL;
}
Index: b/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- a/blender/source/blender/blenkernel/intern/particle_system.c (HEAD)
+++ b/blender/source/blender/blenkernel/intern/particle_system.c (working copy)
@@ -2004,7 +2004,7 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
/************************************************/
/* Effectors */
/************************************************/
-static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
+void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
{
if(psys) {
PARTICLE_P;
@@ -2322,17 +2322,7 @@ typedef struct SPHRangeData
float element_size;
float flow[3];
} SPHRangeData;
-typedef struct SPHData {
- ParticleSystem *psys[10];
- ParticleData *pa;
- float mass;
- EdgeHash *eh;
- float *gravity;
- /* Average distance to neighbours (other particles in the support domain),
- for calculating the Courant number (adaptive time step). */
- float element_size;
- float flow[3];
-}SPHData;
+
static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
{
SPHRangeData *pfr = (SPHRangeData *)userdata;
@@ -2414,7 +2404,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
pfr.massfac = psys[i]->part->mass*inv_mass;
pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
- BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sph_density_accum_cb, &pfr);
+ BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr);
}
if (pfr.tot_neighbors > 0) {
pfr.element_size /= pfr.tot_neighbors;
@@ -2489,28 +2479,69 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
if (fluid->buoyancy > 0.f && gravity)
madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
}
+/* Sample the density field at a point in space. */
+void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) {
+ ParticleSystem **psys = sphdata->psys;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
+ SPHRangeData pfr;
+ int i;
+ float inv_mass = 1.0f/sphdata->mass;
+
+ pfr.tot_neighbors = 0;
+ pfr.density = pfr.near_density = 0.f;
+ pfr.h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*psys[0]->part->size : 1.f); /* 4.0 seems to be a pretty good value */
+ pfr.pa = NULL;
+
+ for(i=0; i<10 && psys[i]; i++) {
+ pfr.npsys = psys[i];
+ pfr.massfac = psys[i]->part->mass*inv_mass;
+ pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
+
+ BLI_bvhtree_range_query(tree, co, pfr.h, sphdata->density_cb, &pfr);
+ }
+
+ vars[0] = pfr.density;
+ vars[1] = pfr.near_density;
+}
-static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash, float *element_size, float flow[3]) {
+void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) {
ParticleTarget *pt;
int i;
+ // Add other coupled particle systems.
+ sphdata->psys[0] = sim->psys;
+ for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL))
+ sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL;
+
+ if (psys_uses_gravity(sim))
+ sphdata->gravity = sim->scene->physics_settings.gravity;
+ else
+ sphdata->gravity = NULL;
+ sphdata->eh = sph_springhash_build(sim->psys);
+
+ // These per-particle values should be overridden later, but just for
+ // completeness we give them default values now.
+ sphdata->pa = NULL;
+ sphdata->mass = 1.0f;
+
+ sphdata->force_cb = sph_force_cb;
+ sphdata->density_cb = sph_density_accum_cb;
+}
+void psys_sph_finalise(SPHData *sphdata) {
+ if (sphdata->eh) {
+ BLI_edgehash_free(sphdata->eh, NULL);
+ sphdata->eh = NULL;
+ }
+}
+static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata){
ParticleSettings *part = sim->psys->part;
// float timestep = psys_get_timestep(sim); // UNUSED
- float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f);
float dtime = dfra*psys_get_timestep(sim);
// int steps = 1; // UNUSED
float effector_acceleration[3];
- SPHData sphdata;
- sphdata.psys[0] = sim->psys;
- for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL))
- sphdata.psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL;
-
- sphdata.pa = pa;
- sphdata.gravity = gravity;
- sphdata.mass = pa_mass;
- sphdata.eh = springhash;
- //sphdata.element_size and sphdata.flow are set in the callback.
+ sphdata->pa = pa;
+ sphdata->mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f);
/* restore previous state and treat gravity & effectors as external acceleration*/
sub_v3_v3v3(effector_acceleration, pa->state.vel, pa->prev_state.vel);
@@ -2518,9 +2549,7 @@ static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float d
copy_particle_key(&pa->state, &pa->prev_state, 0);
- integrate_particle(part, pa, dtime, effector_acceleration, sph_force_cb, &sphdata);
- *element_size = sphdata.element_size;
- copy_v3_v3(flow, sphdata.flow);
+ integrate_particle(part, pa, dtime, effector_acceleration, sphdata->force_cb, sphdata);
}
/************************************************/
@@ -3618,15 +3647,15 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)){
step, after the velocity has been updated. element_size defines the scale of
the simulation, and is typically the distance to neighbourning particles. */
void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
- float dtime, float element_size, float flow[3])
+ float dtime, SPHData *sphdata)
{
float relative_vel[3];
float speed;
- sub_v3_v3v3(relative_vel, pa->state.vel, flow);
+ sub_v3_v3v3(relative_vel, pa->state.vel, sphdata->flow);
speed = len_v3(relative_vel);
- if (sim->courant_num < speed * dtime / element_size)
- sim->courant_num = speed * dtime / element_size;
+ if (sim->courant_num < speed * dtime / sphdata->element_size)
+ sim->courant_num = speed * dtime / sphdata->element_size;
}
/* Update time step size to suit current conditions. */
float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim,
@@ -3712,11 +3741,11 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
case PART_PHYS_FLUID:
{
ParticleTarget *pt = psys->targets.first;
- psys_update_particle_bvhtree(psys, psys->cfra);
+ psys_update_particle_bvhtree(psys, cfra);
for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */
if(pt->ob)
- psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), psys->cfra);
+ psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
}
break;
}
@@ -3798,20 +3827,15 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
}
case PART_PHYS_FLUID:
{
- EdgeHash *springhash = sph_springhash_build(psys);
- float *gravity = NULL;
- float element_size, flow[3];
-
- if(psys_uses_gravity(sim))
- gravity = sim->scene->physics_settings.gravity;
+ SPHData sphdata;
+ psys_sph_init(sim, &sphdata);
LOOP_DYNAMIC_PARTICLES {
/* do global forces & effectors */
basic_integrate(sim, p, pa->state.time, cfra);
/* actual fluids calculations */
- sph_integrate(sim, pa, pa->state.time, gravity, springhash,
- &element_size, flow);
+ sph_integrate(sim, pa, pa->state.time, &sphdata);
if(sim->colliders)
collision_check(sim, p, pa->state.time, cfra);
@@ -3820,15 +3844,12 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
basic_rotate(part, pa, pa->state.time, timestep);
if (part->time_flag & PART_TIME_AUTOSF)
- update_courant_num(sim, pa, dtime, element_size, flow);
+ update_courant_num(sim, pa, dtime, &sphdata);
}
sph_springs_modify(psys, timestep);
- if(springhash) {
- BLI_edgehash_free(springhash, NULL);
- springhash = NULL;
- }
+ psys_sph_finalise(&sphdata);
break;
}
}
Index: b/blender/source/blender/blenkernel/intern/texture.c
===================================================================
--- a/blender/source/blender/blenkernel/intern/texture.c (HEAD)
+++ b/blender/source/blender/blenkernel/intern/texture.c (working copy)
@@ -20,7 +20,8 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Fluid Density texture
+ * Copyright 2011 AutoCRC
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -545,6 +546,7 @@ void free_texture(Tex *tex)
if(tex->coba) MEM_freeN(tex->coba);
if(tex->env) BKE_free_envmap(tex->env);
if(tex->pd) BKE_free_pointdensity(tex->pd);
+ if(tex->fd) BKE_free_fluiddensity(tex->fd);
if(tex->vd) BKE_free_voxeldata(tex->vd);
if(tex->ot) BKE_free_oceantex(tex->ot);
BKE_free_animdata((struct ID *)tex);
@@ -624,6 +626,10 @@ void default_tex(Tex *tex)
tex->pd->falloff_type = TEX_PD_FALLOFF_STD;
}
+ if (tex->fd) {
+ tex->fd->source = TEX_FD_SAMPLE_DENSITY;
+ }
+
if (tex->vd) {
tex->vd->resol[0] = tex->vd->resol[1] = tex->vd->resol[2] = 0;
tex->vd->interp_type=TEX_VD_LINEAR;
@@ -664,6 +670,10 @@ void tex_set_type(Tex *tex, int type)
if (tex->pd == NULL)
tex->pd = BKE_add_pointdensity();
break;
+ case TEX_FLUIDDENSITY:
+ if (tex->fd == NULL)
+ tex->fd = BKE_add_fluiddensity();
+ break;
case TEX_ENVMAP:
if (tex->env == NULL)
tex->env = BKE_add_envmap();
@@ -832,6 +842,7 @@ Tex *copy_texture(Tex *tex)
if(texn->env) texn->env= BKE_copy_envmap(texn->env);
if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
if(texn->vd) texn->vd= MEM_dupallocN(texn->vd);
+ if(texn->fd) texn->fd= BKE_copy_fluiddensity(texn->fd);
if(texn->ot) texn->ot= BKE_copy_oceantex(texn->ot);
if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
@@ -866,6 +877,7 @@ Tex *localize_texture(Tex *tex)
id_us_min(&texn->env->ima->id);
}
if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
+ if(texn->fd) texn->fd= BKE_copy_fluiddensity(texn->fd);
if(texn->vd) {
texn->vd= MEM_dupallocN(texn->vd);
if(texn->vd->dataset)
@@ -1049,7 +1061,7 @@ void autotexname(Tex *tex)
Main *bmain= G.main;
char texstr[20][15]= {"None" , "Clouds" , "Wood", "Marble", "Magic" , "Blend",
"Stucci", "Noise" , "Image", "Plugin", "EnvMap" , "Musgrave",
- "Voronoi", "DistNoise", "Point Density", "Voxel Data", "Ocean", "", "", ""};
+ "Voronoi", "DistNoise", "Point Density", "Voxel Data", "Ocean", "Fluid Density", "", ""};
Image *ima;
char di[FILE_MAXDIR], fi[FILE_MAXFILE];
@@ -1549,6 +1561,44 @@ void BKE_free_oceantex(struct OceanTex *ot)
MEM_freeN(ot);
}
+/* ------------------------------------------------------------------------- */
+
+FluidDensity *BKE_add_fluiddensity(void)
+{
+ FluidDensity *fd;
+
+ fd= MEM_callocN(sizeof(FluidDensity), "fluiddensity");
+ fd->object = NULL;
+ fd->psys = 0;
+ fd->source = TEX_FD_SAMPLE_DENSITY;
+ fd->fddata = NULL;
+ return fd;
+}
+
+FluidDensity *BKE_copy_fluiddensity(FluidDensity *fd)
+{
+ FluidDensity *fdn;
+
+ fdn= MEM_dupallocN(fd);
+ fd->fddata = NULL;
+ return fdn;
+}
+
+void BKE_free_fluiddensitydata(FluidDensity *fd)
+{
+ if (fd->fddata) {
+ MEM_freeN(fd->fddata);
+ fd->fddata = NULL;
+ }
+}
+
+void BKE_free_fluiddensity(FluidDensity *fd)
+{
+ BKE_free_fluiddensitydata(fd);
+ MEM_freeN(fd);
+}
+
+/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int BKE_texture_dependsOnTime(const struct Tex *texture)
Index: b/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- a/blender/source/blender/blenloader/intern/readfile.c (HEAD)
+++ b/blender/source/blender/blenloader/intern/readfile.c (working copy)
@@ -3106,6 +3106,8 @@ static void lib_link_texture(FileData *fd, Main *main)
if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
if(tex->pd)
tex->pd->object= newlibadr(fd, tex->id.lib, tex->pd->object);
+ if(tex->fd)
+ tex->fd->object= newlibadr(fd, tex->id.lib, tex->fd->object);
if(tex->vd) tex->vd->object= newlibadr(fd, tex->id.lib, tex->vd->object);
if(tex->ot) tex->ot->object= newlibadr(fd, tex->id.lib, tex->ot->object);
@@ -3143,6 +3145,7 @@ static void direct_link_texture(FileData *fd, Tex *tex)
}
tex->pd= newdataadr(fd, tex->pd);
if(tex->pd) {
+ /* Zero temporary data */
tex->pd->point_tree = NULL;
tex->pd->coba= newdataadr(fd, tex->pd->coba);
tex->pd->falloff_curve= newdataadr(fd, tex->pd->falloff_curve);
@@ -3150,9 +3153,16 @@ static void direct_link_texture(FileData *fd, Tex *tex)
direct_link_curvemapping(fd, tex->pd->falloff_curve);
}
}
+
+ tex->fd= newdataadr(fd, tex->fd);
+ if(tex->fd) {
+ /* Zero temporary data */
+ tex->fd->fddata = NULL;
+ }
tex->vd= newdataadr(fd, tex->vd);
if(tex->vd) {
+ /* Zero temporary data */
tex->vd->dataset = NULL;
tex->vd->ok = 0;
} else {
Index: b/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- a/blender/source/blender/blenloader/intern/writefile.c (HEAD)
+++ b/blender/source/blender/blenloader/intern/writefile.c (working copy)
@@ -1799,6 +1799,7 @@ static void write_textures(WriteData *wd, ListBase *idbase)
}
if(tex->type == TEX_VOXELDATA) writestruct(wd, DATA, "VoxelData", 1, tex->vd);
if(tex->type == TEX_OCEAN && tex->ot) writestruct(wd, DATA, "OceanTex", 1, tex->ot);
+ if(tex->type == TEX_FLUIDDENSITY && tex->fd) writestruct(wd, DATA, "FluidDensity", 1, tex->fd);
/* nodetree is integral part of texture, no libdata */
if(tex->nodetree) {
Index: b/blender/source/blender/makesdna/DNA_texture_types.h
===================================================================
--- a/blender/source/blender/makesdna/DNA_texture_types.h (HEAD)
+++ b/blender/source/blender/makesdna/DNA_texture_types.h (working copy)
@@ -188,6 +188,20 @@ typedef struct PointDensity {
struct CurveMapping *falloff_curve; /* falloff density curve */
} PointDensity;
+typedef struct FluidDensity {
+ short source;
+
+ short fdpad[3]; // Aligned to 64 bits
+
+ struct Object *object; /* for 'Object' or 'Particle system' type - source object */
+ int psys; /* index+1 in ob.particlesystem, non-ID pointer not allowed */
+
+ int fdpad2; // Aligned to 64 bits
+
+ /* temporary data */
+ void *fddata;
+} FluidDensity;
+
typedef struct VoxelData {
int resol[3];
int interp_type;
@@ -271,6 +285,7 @@ typedef struct Tex {
struct EnvMap *env;
struct PreviewImage * preview;
struct PointDensity *pd;
+ struct FluidDensity *fd;
struct VoxelData *vd;
struct OceanTex *ot;
@@ -331,6 +346,7 @@ typedef struct ColorMapping {
#define TEX_POINTDENSITY 14
#define TEX_VOXELDATA 15
#define TEX_OCEAN 16
+#define TEX_FLUIDDENSITY 17
/* musgrave stype */
#define TEX_MFRACTAL 0
@@ -576,6 +592,11 @@ typedef struct ColorMapping {
#define POINT_DATA_VEL 1
#define POINT_DATA_LIFE 2
+/* **************** FluidDensity ********************* */
+
+#define TEX_FD_SAMPLE_DENSITY 0
+#define TEX_FD_SAMPLE_DENSITY_NEAR 1
+
/******************** Voxel Data *****************************/
/* flag */
#define TEX_VD_STILL 1
Index: b/blender/source/blender/makesrna/RNA_access.h
===================================================================
--- a/blender/source/blender/makesrna/RNA_access.h (HEAD)
+++ b/blender/source/blender/makesrna/RNA_access.h (working copy)
@@ -228,6 +228,8 @@ extern StructRNA RNA_FieldSettings;
extern StructRNA RNA_FileSelectParams;
extern StructRNA RNA_FloatProperty;
extern StructRNA RNA_FloorConstraint;
+extern StructRNA RNA_FluidDensity;
+extern StructRNA RNA_FluidDensityTexture;
extern StructRNA RNA_FluidFluidSettings;
extern StructRNA RNA_FluidSettings;
extern StructRNA RNA_FluidSimulationModifier;
Index: b/blender/source/blender/makesrna/intern/rna_texture.c
===================================================================
--- a/blender/source/blender/makesrna/intern/rna_texture.c (HEAD)
+++ b/blender/source/blender/makesrna/intern/rna_texture.c (working copy)
@@ -17,6 +17,9 @@
*
* Contributor(s): Blender Foundation (2008).
*
+ * Fluid Density texture
+ * Copyright 2011 AutoCRC
+ *
* ***** END GPL LICENSE BLOCK *****
*/
@@ -69,6 +72,7 @@ EnumPropertyItem texture_type_items[] = {
"Procedural - random noise, gives a different result every time, for every frame, for every pixel"},
//{TEX_PLUGIN, "PLUGIN", ICON_PLUGIN, "Plugin", ""}, /* Nothing yet */
{TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""},
+ {TEX_FLUIDDENSITY, "FLUID_DENSITY", ICON_TEXTURE, "Fluid Density", ""},
{TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"},
{TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"},
{TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3d texture based on volumetric data"},
@@ -138,6 +142,8 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
return &RNA_PluginTexture;
case TEX_POINTDENSITY:
return &RNA_PointDensityTexture;
+ case TEX_FLUIDDENSITY:
+ return &RNA_FluidDensityTexture;
case TEX_STUCCI:
return &RNA_StucciTexture;
case TEX_VORONOI:
@@ -433,6 +439,34 @@ static char *rna_PointDensity_path(PointerRNA *UNUSED(ptr))
return BLI_sprintfN("point_density");
}
+static PointerRNA rna_FluidDensity_psys_get(PointerRNA *ptr)
+{
+ FluidDensity *fd= ptr->data;
+ Object *ob= fd->object;
+ ParticleSystem *psys= NULL;
+ PointerRNA value;
+
+ if(ob && fd->psys)
+ psys= BLI_findlink(&ob->particlesystem, fd->psys-1);
+
+ RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &value);
+ return value;
+}
+
+static void rna_FluidDensity_psys_set(PointerRNA *ptr, PointerRNA value)
+{
+ FluidDensity *fd= ptr->data;
+ Object *ob= fd->object;
+
+ if(ob && value.id.data == ob)
+ fd->psys= BLI_findindex(&ob->particlesystem, value.data) + 1;
+}
+
+static char *rna_FluidDensity_path(PointerRNA *UNUSED(ptr))
+{
+ return BLI_sprintfN("fluid_density");
+}
+
static char *rna_VoxelData_path(PointerRNA *UNUSED(ptr))
{
return BLI_sprintfN("voxel_data");
@@ -1737,6 +1771,51 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Texture_update");
}
+static void rna_def_texture_fluiddensity(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem sample_source_items[] = {
+ {TEX_FD_SAMPLE_DENSITY, "DENSITY", 0, "Density", ""},
+ {TEX_FD_SAMPLE_DENSITY_NEAR, "DENSITY_NEAR", 0, "Density (near)", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "FluidDensity", NULL);
+ RNA_def_struct_sdna(srna, "FluidDensity");
+ RNA_def_struct_ui_text(srna, "FluidDensity", "Fluid density settings");
+ RNA_def_struct_path_func(srna, "rna_FluidDensity_path");
+
+ prop= RNA_def_property(srna, "sample_source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "source");
+ RNA_def_property_enum_items(prop, sample_source_items);
+ RNA_def_property_ui_text(prop, "Sample Source", "Data to use as renderable density");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+ prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "object");
+ RNA_def_property_ui_text(prop, "Object", "Object to take fluid data from");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+ prop= RNA_def_property(srna, "particle_system", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Particle System", "Particle System to sample");
+ RNA_def_property_struct_type(prop, "ParticleSystem");
+ RNA_def_property_pointer_funcs(prop, "rna_FluidDensity_psys_get", "rna_FluidDensity_psys_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
+ srna= RNA_def_struct(brna, "FluidDensityTexture", "Texture");
+ RNA_def_struct_sdna(srna, "Tex");
+ RNA_def_struct_ui_text(srna, "Fluid Density", "Settings for the Fluid Density texture");
+
+ prop= RNA_def_property(srna, "fluid_density", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "fd");
+ RNA_def_property_struct_type(prop, "FluidDensity");
+ RNA_def_property_ui_text(prop, "Fluid Density", "The fluid density settings associated with this texture");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+}
+
static void rna_def_texture_voxeldata(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2003,6 +2082,7 @@ static void rna_def_texture(BlenderRNA *brna)
rna_def_texture_pointdensity(brna);
rna_def_texture_voxeldata(brna);
rna_def_texture_ocean(brna);
+ rna_def_texture_fluiddensity(brna);
/* XXX add more types here .. */
RNA_api_texture(srna);
Index: b/blender/source/blender/render/CMakeLists.txt
===================================================================
--- a/blender/source/blender/render/CMakeLists.txt (HEAD)
+++ b/blender/source/blender/render/CMakeLists.txt (working copy)
@@ -64,6 +64,7 @@ set(SRC
intern/source/pixelblending.c
intern/source/pixelshading.c
intern/source/pointdensity.c
+ intern/source/fluiddensity.c
intern/source/rayshade.c
intern/source/rendercore.c
intern/source/render_texture.c
@@ -91,6 +92,7 @@ set(SRC
intern/include/pixelblending.h
intern/include/pixelshading.h
intern/include/pointdensity.h
+ intern/include/fluiddensity.h
intern/include/raycounter.h
intern/include/rayobject.h
intern/include/rayintersection.h
Index: b/blender/source/blender/render/intern/include/fluiddensity.h
new file mode 100644
===================================================================
b/blender/source/blender/render/intern/include/fluiddensity.h (revision 0)
b/blender/source/blender/render/intern/include/fluiddensity.h (revision 0)
@@ -0,0 +1,50 @@
+/*
+ *
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: Matt Ebb
+ *
+ * Fluid Density texture
+ * Copyright 2011 AutoCRC
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/fluiddensity.h
+ * \ingroup render
+ */
+
+
+#ifndef FLUIDDENSITY_H
+#define FLUIDDENSITY_H
+
+/**
+ * Make particle bvh-trees for all fluid density textures in the scene
+ */
+
+struct Render;
+struct TexResult;
+
+void make_fluiddensities(struct Render *re);
+void free_fluiddensities(struct Render *re);
+int fluiddensitytex(struct Tex *tex, float *texvec, struct TexResult *texres);
+
+#endif /* FLUIDDENSITY_H */
+
Index: b/blender/source/blender/render/intern/include/texture.h
===================================================================
--- a/blender/source/blender/render/intern/include/texture.h (HEAD)
+++ b/blender/source/blender/render/intern/include/texture.h (working copy)
@@ -36,6 +36,7 @@
#ifndef TEXTURE_EXT_H
#define TEXTURE_EXT_H
+/* Brightness and contrast adjustment. */
#define BRICONT \
texres->tin= (texres->tin-0.5f) * tex->contrast+tex->bright-0.5f; \
if(texres->tin < 0.0f) texres->tin= 0.0f; \
Index: b/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- a/blender/source/blender/render/intern/source/convertblender.c (HEAD)
+++ b/blender/source/blender/render/intern/source/convertblender.c (working copy)
@@ -103,6 +103,7 @@
#include "envmap.h"
#include "occlusion.h"
#include "pointdensity.h"
+#include "fluiddensity.h"
#include "voxeldata.h"
#include "render_types.h"
#include "rendercore.h"
@@ -4669,6 +4670,7 @@ void RE_Database_Free(Render *re)
end_render_textures(re);
free_pointdensities(re);
+ free_fluiddensities(re);
free_camera_inside_volumes(re);
@@ -5129,6 +5131,9 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
/* voxel data texture */
if(!re->test_break(re->tbh))
make_voxeldata(re);
+ /* fluid density texture */
+ if(!re->test_break(re->tbh))
+ make_fluiddensities(re);
}
if(!re->test_break(re->tbh))
@@ -5793,6 +5798,10 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
if(!re->test_break(re->tbh))
make_pointdensities(re);
+ /* fluid density texture */
+ if(!re->test_break(re->tbh))
+ make_fluiddensities(re);
+
/* voxel data texture */
if(!re->test_break(re->tbh))
make_voxeldata(re);
Index: b/blender/source/blender/render/intern/source/fluiddensity.c
new file mode 100644
===================================================================
b/blender/source/blender/render/intern/source/fluiddensity.c (revision 0)
b/blender/source/blender/render/intern/source/fluiddensity.c (revision 0)
@@ -0,0 +1,221 @@
+/*
+ * ***** 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributors: Matt Ebb
+ *
+ * Fluid Density texture
+ * Copyright 2011 AutoCRC
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/fluiddensity.c
+ * \ingroup render
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_kdtree.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_lattice.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_scene.h"
+#include "BKE_texture.h"
+
+#include "DNA_meshdata_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_particle_types.h"
+
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "texture.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+typedef struct FDData {
+ struct ParticleSimulationData sim;
+ struct SPHData sphdata;
+} FDData;
+
+/* Build up a BVH tree of particles. */
+static void fluiddensity_cache_psys(Render *re, FluidDensity *fd, Object *ob, ParticleSystem *psys)
+{
+ DerivedMesh* dm;
+ ParticleSimulationData sim= {0};
+ float cfra = BKE_curframe(re->scene);
+ int total_particles;
+
+ /* init everything */
+ if (!psys || !ob || !fd)
+ return;
+
+ /* Just to create a valid rendering context for particles */
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, 0);
+
+ /* Not sure if this is really needed, but pointdensity does it! */
+ dm = mesh_create_derived_render(re->scene, ob, CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+
+ if (!psys_check_enabled(ob, psys)) {
+ psys_render_restore(ob, psys);
+ return;
+ }
+
+ sim.scene = re->scene;
+ sim.ob = ob;
+ sim.psys = psys;
+
+ /* in case ob->imat isn't up-to-date */
+ invert_m4_m4(ob->imat, ob->obmat);
+
+ total_particles = psys->totpart;
+ psys_update_particle_bvhtree(sim.psys, cfra);
+ dm->release(dm);
+
+ psys_render_restore(ob, psys);
+}
+
+static void cache_fluiddensity(Render *re, Tex *tex)
+{
+ FluidDensity *fd = tex->fd;
+ Object *ob = fd->object;
+ ParticleSystem *psys;
+ FDData *fddata;
+
+ if(!fd)
+ return;
+
+ if (fd->fddata) {
+ MEM_freeN(fd->fddata);
+ fd->fddata = NULL;
+ }
+
+ if (!ob || !fd->psys)
+ return;
+
+ psys = BLI_findlink(&ob->particlesystem, fd->psys - 1);
+ if (!psys)
+ return;
+
+ fddata = MEM_callocN(sizeof(FDData), "Fluid density texture FDData");
+ fddata->sim.scene = re->scene;
+ fddata->sim.ob = ob;
+ fddata->sim.psys = psys;
+ fd->fddata = fddata;
+ psys_sph_init(&(fddata->sim), &(fddata->sphdata));
+ fluiddensity_cache_psys(re, fd, ob, psys);
+}
+
+static void free_fluiddensity(Render *UNUSED(re), Tex *tex)
+{
+ FluidDensity *fd = tex->fd;
+ FDData *fddata;
+
+ if (!fd)
+ return;
+
+ if (fd->fddata) {
+ fddata = (FDData*)fd->fddata;
+ psys_sph_finalise(&(fddata->sphdata));
+ MEM_freeN(fd->fddata);
+ fd->fddata = NULL;
+ }
+}
+
+void make_fluiddensities(Render *re)
+{
+ Tex *tex;
+
+ if(re->scene->r.scemode & R_PREVIEWBUTS)
+ return;
+
+ re->i.infostr= "Caching Fluid Densities";
+ re->stats_draw(re->sdh, &re->i);
+
+ for (tex= re->main->tex.first; tex; tex= tex->id.next) {
+ if(tex->id.us && tex->type == TEX_FLUIDDENSITY) {
+ cache_fluiddensity(re, tex);
+ }
+ }
+
+ re->i.infostr= NULL;
+ re->stats_draw(re->sdh, &re->i);
+}
+
+void free_fluiddensities(Render *re)
+{
+ Tex *tex;
+
+ if(re->scene->r.scemode & R_PREVIEWBUTS)
+ return;
+
+ for (tex= re->main->tex.first; tex; tex= tex->id.next) {
+ if(tex->id.us && tex->type == TEX_FLUIDDENSITY) {
+ free_fluiddensity(re, tex);
+ }
+ }
+}
+
+int fluiddensitytex(Tex *tex, float *texvec, TexResult *texres)
+{
+ FluidDensity *fd = tex->fd;
+ FDData *fddata;
+
+ float co[3];
+ float vars[2];
+
+ texres->tin = 0.0f;
+
+ if ((!fd) || (!fd->object) || (!fd->fddata))
+ return 0;
+
+ fddata = (FDData*) fd->fddata;
+
+ copy_v3_v3(co, texvec);
+ psys_sph_density(fddata->sim.psys->bvhtree, &(fddata->sphdata), co, vars);
+
+ switch (fd->source) {
+ case TEX_FD_SAMPLE_DENSITY:
+ texres->tin = vars[0];
+ break;
+ case TEX_FD_SAMPLE_DENSITY_NEAR:
+ texres->tin = vars[1];
+ break;
+ }
+
+ BRICONT;
+
+ return TEX_INT;
+}
Index: b/blender/source/blender/render/intern/source/render_texture.c
===================================================================
--- a/blender/source/blender/render/intern/source/render_texture.c (HEAD)
+++ b/blender/source/blender/render/intern/source/render_texture.c (working copy)
@@ -73,6 +73,7 @@
#include "envmap.h"
#include "pointdensity.h"
+#include "fluiddensity.h"
#include "voxeldata.h"
#include "renderpipeline.h"
#include "render_types.h"
@@ -1262,6 +1263,9 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex,
case TEX_POINTDENSITY:
retval= pointdensitytex(tex, texvec, texres);
break;
+ case TEX_FLUIDDENSITY:
+ retval= fluiddensitytex(tex, texvec, texres);
+ break;
case TEX_VOXELDATA:
retval= voxeldatatex(tex, texvec, texres);
break;

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
5f/a5/e0bc0c0d1a81a6dad0c6a899d0f1

Event Timeline