forked from bartvdbraak/blender
Smoke:
* Enable external forces like e.g. wind
This commit is contained in:
parent
8f154364f2
commit
14f62c1321
4
intern/smoke/extern/smoke_API.h
vendored
4
intern/smoke/extern/smoke_API.h
vendored
@ -50,6 +50,10 @@ float *smoke_get_velocity_x(struct FLUID_3D *fluid);
|
|||||||
float *smoke_get_velocity_y(struct FLUID_3D *fluid);
|
float *smoke_get_velocity_y(struct FLUID_3D *fluid);
|
||||||
float *smoke_get_velocity_z(struct FLUID_3D *fluid);
|
float *smoke_get_velocity_z(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
|
float *smoke_get_force_x(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_force_y(struct FLUID_3D *fluid);
|
||||||
|
float *smoke_get_force_z(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid);
|
unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid);
|
||||||
|
|
||||||
size_t smoke_get_index(int x, int max_x, int y, int max_y, int z);
|
size_t smoke_get_index(int x, int max_x, int y, int max_y, int z);
|
||||||
|
@ -185,13 +185,6 @@ void FLUID_3D::step()
|
|||||||
// addSmokeTestCase(_density, _res);
|
// addSmokeTestCase(_density, _res);
|
||||||
// addSmokeTestCase(_heat, _res);
|
// addSmokeTestCase(_heat, _res);
|
||||||
|
|
||||||
// wipe forces
|
|
||||||
for (int i = 0; i < _totalCells; i++)
|
|
||||||
{
|
|
||||||
_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
|
|
||||||
// _obstacles[i] &= ~2;
|
|
||||||
}
|
|
||||||
|
|
||||||
wipeBoundaries();
|
wipeBoundaries();
|
||||||
|
|
||||||
// run the solvers
|
// run the solvers
|
||||||
@ -232,6 +225,13 @@ void FLUID_3D::step()
|
|||||||
|
|
||||||
// todo xxx dg: only clear obstacles, not boundaries
|
// todo xxx dg: only clear obstacles, not boundaries
|
||||||
// memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes);
|
// memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes);
|
||||||
|
|
||||||
|
// wipe forces
|
||||||
|
// for external forces we can't do it at the beginning of this function but at the end
|
||||||
|
for (int i = 0; i < _totalCells; i++)
|
||||||
|
{
|
||||||
|
_xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -235,6 +235,21 @@ extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid)
|
|||||||
return fluid->_zVelocity;
|
return fluid->_zVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_force_x(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_xForce;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_force_y(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_yForce;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" float *smoke_get_force_z(FLUID_3D *fluid)
|
||||||
|
{
|
||||||
|
return fluid->_zForce;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
|
extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
|
||||||
{
|
{
|
||||||
return wt ? wt->getDensityBig() : NULL;
|
return wt ? wt->getDensityBig() : NULL;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
from buttons_particle import point_cache_ui
|
from buttons_physics_common import point_cache_ui
|
||||||
|
from buttons_physics_common import effector_weights_ui
|
||||||
|
|
||||||
class PhysicButtonsPanel(bpy.types.Panel):
|
class PhysicButtonsPanel(bpy.types.Panel):
|
||||||
__space_type__ = 'PROPERTIES'
|
__space_type__ = 'PROPERTIES'
|
||||||
@ -172,7 +173,19 @@ class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel):
|
|||||||
|
|
||||||
point_cache_ui(self, cache, cache.baked==False, 0, 1)
|
point_cache_ui(self, cache, cache.baked==False, 0, 1)
|
||||||
|
|
||||||
|
class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel):
|
||||||
|
__label__ = "Smoke Field Weights"
|
||||||
|
__default_closed__ = True
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
return (context.smoke)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
domain = context.smoke.domain_settings
|
||||||
|
effector_weights_ui(self, domain.effector_weights)
|
||||||
|
|
||||||
bpy.types.register(PHYSICS_PT_smoke)
|
bpy.types.register(PHYSICS_PT_smoke)
|
||||||
|
bpy.types.register(PHYSICS_PT_smoke_field_weights)
|
||||||
bpy.types.register(PHYSICS_PT_smoke_cache)
|
bpy.types.register(PHYSICS_PT_smoke_cache)
|
||||||
bpy.types.register(PHYSICS_PT_smoke_highres)
|
bpy.types.register(PHYSICS_PT_smoke_highres)
|
||||||
bpy.types.register(PHYSICS_PT_smoke_groups)
|
bpy.types.register(PHYSICS_PT_smoke_groups)
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "BKE_cdderivedmesh.h"
|
#include "BKE_cdderivedmesh.h"
|
||||||
#include "BKE_customdata.h"
|
#include "BKE_customdata.h"
|
||||||
#include "BKE_DerivedMesh.h"
|
#include "BKE_DerivedMesh.h"
|
||||||
|
#include "BKE_effect.h"
|
||||||
#include "BKE_modifier.h"
|
#include "BKE_modifier.h"
|
||||||
#include "BKE_particle.h"
|
#include "BKE_particle.h"
|
||||||
#include "BKE_pointcache.h"
|
#include "BKE_pointcache.h"
|
||||||
@ -547,6 +548,10 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd)
|
|||||||
if(smd->domain->wt)
|
if(smd->domain->wt)
|
||||||
smoke_turbulence_free(smd->domain->wt);
|
smoke_turbulence_free(smd->domain->wt);
|
||||||
|
|
||||||
|
if(smd->domain->effector_weights)
|
||||||
|
MEM_freeN(smd->domain->effector_weights);
|
||||||
|
smd->domain->effector_weights = NULL;
|
||||||
|
|
||||||
BKE_ptcache_free_list(&(smd->domain->ptcaches[0]));
|
BKE_ptcache_free_list(&(smd->domain->ptcaches[0]));
|
||||||
smd->domain->point_cache[0] = NULL;
|
smd->domain->point_cache[0] = NULL;
|
||||||
BKE_ptcache_free_list(&(smd->domain->ptcaches[1]));
|
BKE_ptcache_free_list(&(smd->domain->ptcaches[1]));
|
||||||
@ -714,6 +719,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
|
|||||||
smd->domain->diss_speed = 5;
|
smd->domain->diss_speed = 5;
|
||||||
// init 3dview buffer
|
// init 3dview buffer
|
||||||
smd->domain->viewsettings = 0;
|
smd->domain->viewsettings = 0;
|
||||||
|
smd->domain->effector_weights = BKE_add_effector_weights(NULL);
|
||||||
}
|
}
|
||||||
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
|
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
|
||||||
{
|
{
|
||||||
@ -938,21 +944,53 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do effectors
|
// do effectors
|
||||||
/*
|
|
||||||
if(sds->eff_group)
|
|
||||||
{
|
|
||||||
for(go = sds->eff_group->gobject.first; go; go = go->next)
|
|
||||||
{
|
|
||||||
if(go->ob)
|
|
||||||
{
|
|
||||||
if(ob->pd)
|
|
||||||
{
|
{
|
||||||
|
ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights);
|
||||||
|
|
||||||
|
if(effectors)
|
||||||
|
{
|
||||||
|
float *density = smoke_get_density(sds->fluid);
|
||||||
|
float *force_x = smoke_get_force_x(sds->fluid);
|
||||||
|
float *force_y = smoke_get_force_y(sds->fluid);
|
||||||
|
float *force_z = smoke_get_force_z(sds->fluid);
|
||||||
|
float *velocity_x = smoke_get_velocity_x(sds->fluid);
|
||||||
|
float *velocity_y = smoke_get_velocity_y(sds->fluid);
|
||||||
|
float *velocity_z = smoke_get_velocity_z(sds->fluid);
|
||||||
|
int x, y, z;
|
||||||
|
|
||||||
|
// precalculate wind forces
|
||||||
|
for(x = 0; x < sds->res[0]; x++)
|
||||||
|
for(y = 0; y < sds->res[1]; y++)
|
||||||
|
for(z = 0; z < sds->res[2]; z++)
|
||||||
|
{
|
||||||
|
EffectedPoint epoint;
|
||||||
|
float voxelCenter[3], vel[3], retvel[3];
|
||||||
|
|
||||||
|
unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z);
|
||||||
|
|
||||||
|
if(density[index] < FLT_EPSILON)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vel[0] = velocity_x[index];
|
||||||
|
vel[1] = velocity_y[index];
|
||||||
|
vel[2] = velocity_z[index];
|
||||||
|
|
||||||
|
voxelCenter[0] = sds->p0[0] + sds->dx * x + sds->dx * 0.5;
|
||||||
|
voxelCenter[1] = sds->p0[1] + sds->dx * y + sds->dx * 0.5;
|
||||||
|
voxelCenter[2] = sds->p0[2] + sds->dx * z + sds->dx * 0.5;
|
||||||
|
|
||||||
|
pd_point_from_loc(scene, voxelCenter, vel, index, &epoint);
|
||||||
|
pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL);
|
||||||
|
|
||||||
|
// TODO dg - do in force!
|
||||||
|
force_x[index] += MIN2(MAX2(-1.0, retvel[0] * 0.002), 1.0);
|
||||||
|
force_y[index] += MIN2(MAX2(-1.0, retvel[1] * 0.002), 1.0);
|
||||||
|
force_z[index] += MIN2(MAX2(-1.0, retvel[2] * 0.002), 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdEndEffectors(&effectors);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// do collisions
|
// do collisions
|
||||||
if(1)
|
if(1)
|
||||||
|
@ -3655,6 +3655,8 @@ static void lib_link_object(FileData *fd, Main *main)
|
|||||||
smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group);
|
smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group);
|
||||||
smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group);
|
smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group);
|
||||||
smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
|
smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
|
||||||
|
|
||||||
|
smd->domain->effector_weights->group = newlibadr(fd, ob->id.lib, smd->domain->effector_weights->group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3784,6 +3786,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
|||||||
smd->domain->tex_shadow = NULL;
|
smd->domain->tex_shadow = NULL;
|
||||||
smd->domain->tex_wt = NULL;
|
smd->domain->tex_wt = NULL;
|
||||||
|
|
||||||
|
if(smd->domain->effector_weights)
|
||||||
|
smd->domain->effector_weights = newdataadr(fd, smd->domain->effector_weights);
|
||||||
|
else
|
||||||
|
smd->domain->effector_weights = BKE_add_effector_weights(NULL);
|
||||||
|
|
||||||
direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]));
|
direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]));
|
||||||
direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1]));
|
direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1]));
|
||||||
}
|
}
|
||||||
|
@ -1153,7 +1153,10 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
|
|||||||
SmokeModifierData *smd = (SmokeModifierData*) md;
|
SmokeModifierData *smd = (SmokeModifierData*) md;
|
||||||
|
|
||||||
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
|
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
|
||||||
|
{
|
||||||
writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain);
|
writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain);
|
||||||
|
writestruct(wd, DATA, "EffectorWeights", 1, smd->domain->effector_weights);
|
||||||
|
}
|
||||||
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
|
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
|
||||||
writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow);
|
writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow);
|
||||||
else if(smd->type & MOD_SMOKE_TYPE_COLL)
|
else if(smd->type & MOD_SMOKE_TYPE_COLL)
|
||||||
|
@ -45,7 +45,7 @@ typedef struct SmokeDomainSettings {
|
|||||||
struct SmokeModifierData *smd; /* for fast RNA access */
|
struct SmokeModifierData *smd; /* for fast RNA access */
|
||||||
struct FLUID_3D *fluid;
|
struct FLUID_3D *fluid;
|
||||||
struct Group *fluid_group;
|
struct Group *fluid_group;
|
||||||
struct Group *eff_group; // effector group for e.g. wind force
|
struct Group *eff_group; // UNUSED
|
||||||
struct Group *coll_group; // collision objects group
|
struct Group *coll_group; // collision objects group
|
||||||
struct WTURBULENCE *wt; // WTURBULENCE object, if active
|
struct WTURBULENCE *wt; // WTURBULENCE object, if active
|
||||||
struct GPUTexture *tex;
|
struct GPUTexture *tex;
|
||||||
@ -75,6 +75,7 @@ typedef struct SmokeDomainSettings {
|
|||||||
int v3dnum;
|
int v3dnum;
|
||||||
struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */
|
struct PointCache *point_cache[2]; /* definition is in DNA_object_force.h */
|
||||||
struct ListBase ptcaches[2];
|
struct ListBase ptcaches[2];
|
||||||
|
struct EffectorWeights *effector_weights;
|
||||||
} SmokeDomainSettings;
|
} SmokeDomainSettings;
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,6 +220,11 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
|
|||||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]");
|
RNA_def_property_pointer_sdna(prop, NULL, "point_cache[1]");
|
||||||
RNA_def_property_ui_text(prop, "Point Cache", "");
|
RNA_def_property_ui_text(prop, "Point Cache", "");
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "EffectorWeights");
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
RNA_def_property_ui_text(prop, "Effector Weights", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_smoke_flow_settings(BlenderRNA *brna)
|
static void rna_def_smoke_flow_settings(BlenderRNA *brna)
|
||||||
|
Loading…
Reference in New Issue
Block a user