* cache for low res (deactivating high res for now)
* new way of view3d rendering of smoke (no longer 3 axes) -using 3dtexture now (introduced into gpu/intern)
* introducing LZO and LZMA libs into extern (makefiles missing for now)
* reducing memory usage after simulating for the frame ended (freeing temporary buffers)
* splitting smoke into 2 modifier for the cache-sake (it cannot handle more than 1 cache on the same modifier-index)
* no color on gui anymore
* fixing non-power-of-2 resolutions (hopefully)
* fixing select-deselect of domain drawing bug
* fixing drawobject.c coding style (making Ton happy) ;-)

HINT #1: If scons doesn't work -> cmakefiles are up-to-date, couldn't test scons (but i tried to mantain them, too)

CODERS HINT #1: we really need a way to disable adding all modifiers through "Add Modifiers" dropdown!

WARNING #1: before applying this commit, deactivate your SMOKE DOMAIN in your old files and save them then. You can open them then savely after that.

WARNING #2: File and cache format of smoke can be changed, this is not final!
This commit is contained in:
Daniel Genrich
2009-08-20 00:33:59 +00:00
parent c21627e31b
commit 286c2ca80b
80 changed files with 17406 additions and 1540 deletions

View File

@@ -60,8 +60,8 @@
#define PTCACHE_TYPE_SOFTBODY 0
#define PTCACHE_TYPE_PARTICLES 1
#define PTCACHE_TYPE_CLOTH 2
#define PTCACHE_TYPE_SMOKE_DOMAIN_LOW 3
#define PTCACHE_TYPE_SMOKE_DOMAIN_HIGH 4
#define PTCACHE_TYPE_SMOKE_DOMAIN 3
#define PTCACHE_TYPE_SMOKE_HIGHRES 4
/* PTCache read return code */
#define PTCACHE_READ_EXACT 1
@@ -158,7 +158,7 @@ void BKE_ptcache_make_particle_key(struct ParticleKey *key, int index, void **da
void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb);
void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd, int num);
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob);

View File

@@ -32,24 +32,17 @@
#ifndef BKE_SMOKE_H_
#define BKE_SMOKE_H_
typedef int (*bresenham_callback) (float *input, int res[3], int *pixel, float *tRay);
void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
void smokeModifier_free (struct SmokeModifierData *smd);
void smokeModifier_reset(struct SmokeModifierData *smd);
void smokeModifier_createType(struct SmokeModifierData *smd);
void smoke_set_tray(struct SmokeModifierData *smd, size_t index, float transparency);
float smoke_get_tray(struct SmokeModifierData *smd, size_t index);
float smoke_get_tvox(struct SmokeModifierData *smd, size_t index);
void smoke_set_tvox(struct SmokeModifierData *smd, size_t index, float tvox);
// high res modifier
void smokeHRModifier_do(struct SmokeHRModifierData *shrmd, struct Scene *scene, struct Object *ob, int useRenderParams, int isFinalCalc);
void smokeHRModifier_free(struct SmokeHRModifierData *shrmd);
void smoke_set_bigtray(struct SmokeModifierData *smd, size_t index, float transparency);
float smoke_get_bigtray(struct SmokeModifierData *smd, size_t index);
float smoke_get_bigtvox(struct SmokeModifierData *smd, size_t index);
void smoke_set_bigtvox(struct SmokeModifierData *smd, size_t index, float tvox);
long long smoke_get_mem_req(int xres, int yres, int zres, int amplify);
void smoke_prepare_View(struct SmokeModifierData *smd, float *light);
void smoke_prepare_bigView(struct SmokeModifierData *smd, float *light);
#endif /* BKE_SMOKE_H_ */

View File

@@ -34,6 +34,8 @@ SET(INC
../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern
../../../intern/bsp/extern ../blenfont
../../../intern/audaspace/intern
../../../extern/lzo/minilzo
../../../extern/lzma
${ZLIB_INC}
)

View File

@@ -11,6 +11,8 @@ incs += ' #/extern/bullet2/src'
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
incs += ' ../gpu #/extern/glew/include'
incs += ' #/intern/smoke/extern'
incs += ' #/extern/lzo/minilzo'
incs += ' #/extern/lzma'
incs += ' #/intern/audaspace/intern'
incs += ' ' + env['BF_OPENGL_INC']

View File

@@ -5801,26 +5801,6 @@ static void smokeModifier_initData(ModifierData *md)
smd->coll = NULL;
smd->type = 0;
smd->time = -1;
/*
smd->fluid = NULL;
smd->maxres = 48;
smd->amplify = 4;
smd->omega = 0.5;
smd->time = 0;
smd->flags = 0;
smd->noise = MOD_SMOKE_NOISEWAVE;
smd->visibility = 1;
// init 3dview buffer
smd->tvox = NULL;
smd->tray = NULL;
smd->tvoxbig = NULL;
smd->traybig = NULL;
smd->viewsettings = 0;
smd->bind = NULL;
smd->max_textures = 0;
*/
}
static void smokeModifier_freeData(ModifierData *md)
@@ -5884,6 +5864,50 @@ static void smokeModifier_updateDepgraph(
*/
}
/* Smoke High Resolution */
static void smokeHRModifier_initData(ModifierData *md)
{
SmokeHRModifierData *shrmd = (SmokeHRModifierData*) md;
shrmd->wt = NULL;
shrmd->time = -1;
shrmd->strength = 2.0f;
shrmd->amplify = 1;
shrmd->noise = MOD_SMOKE_NOISEWAVE;
shrmd->point_cache = BKE_ptcache_add(&shrmd->ptcaches);
shrmd->point_cache->flag |= PTCACHE_DISK_CACHE;
shrmd->point_cache->step = 1;
}
static void smokeHRModifier_freeData(ModifierData *md)
{
SmokeHRModifierData *shrmd = (SmokeHRModifierData*) md;
smokeHRModifier_free (shrmd);
}
static void smokeHRModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
SmokeHRModifierData *shrmd = (SmokeHRModifierData*) md;
smokeHRModifier_do(shrmd, md->scene, ob, useRenderParams, isFinalCalc);
}
static int smokeHRModifier_dependsOnTime(ModifierData *md)
{
return 1;
}
static void smokeHRModifier_updateDepgraph(
ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
DagNode *obNode)
{
;
}
/* Cloth */
static void clothModifier_initData(ModifierData *md)
@@ -8580,10 +8604,23 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->type = eModifierTypeType_OnlyDeform;
mti->initData = smokeModifier_initData;
mti->freeData = smokeModifier_freeData;
mti->flags = eModifierTypeFlag_AcceptsMesh;
mti->flags = eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_UsesPointCache
| eModifierTypeFlag_Single;
mti->deformVerts = smokeModifier_deformVerts;
mti->dependsOnTime = smokeModifier_dependsOnTime;
mti->updateDepgraph = smokeModifier_updateDepgraph;
mti = INIT_TYPE(SmokeHR);
mti->type = eModifierTypeType_OnlyDeform;
mti->initData = smokeHRModifier_initData;
mti->freeData = smokeHRModifier_freeData;
mti->flags = eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_UsesPointCache
| eModifierTypeFlag_Single;
mti->deformVerts = smokeHRModifier_deformVerts;
mti->dependsOnTime = smokeHRModifier_dependsOnTime;
mti->updateDepgraph = smokeHRModifier_updateDepgraph;
mti = INIT_TYPE(Cloth);
mti->type = eModifierTypeType_Nonconstructive;

View File

@@ -59,7 +59,12 @@
#include "BLI_blenlib.h"
/* both in intern */
#include "smoke_API.h"
#include "minilzo.h"
#include "LzmaLib.h"
/* needed for directory lookup */
#ifndef WIN32
@@ -469,43 +474,116 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->info_types= (1<<BPHYS_DATA_TIMES);
}
#if 0 // XXX smoke pointcache stuff breaks compiling now
/* Smoke functions */
static int ptcache_totpoint_smoke(void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
if(sds->fluid)
{
if(sds->fluid) {
return sds->res[0]*sds->res[1]*sds->res[2];
}
else
return 0;
}
static int ptcache_totpoint_smoke_turbulence(void *smoke_v)
{
SmokeHRModifierData *shrmd= (SmokeHRModifierData *)smoke_v;
if(shrmd->wt) {
/*
unsigned int res[3];
smoke_turbulence_get_res(sds->wt, res);
return res[0]*res[1]*res[2];
*/
return 0;
}
else
return 0;
}
// forward decleration
static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size);
static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode)
{
int r;
unsigned char compressed;
LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
unsigned int out_len = LZO_OUT_LEN(in_len);
unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
size_t sizeOfIt = 5;
if(mode == 1) {
r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem);
if (!(r == LZO_E_OK) || (out_len >= in_len))
compressed = 0;
else
compressed = 1;
}
else if(mode == 2) {
r = LzmaCompress(out, (size_t *)&out_len, in, in_len,//assume sizeof(char)==1....
props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
if(!(r == SZ_OK) || (out_len >= in_len))
compressed = 0;
else
compressed = 2;
}
ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char));
if(compressed) {
ptcache_file_write(pf, &out_len, 1, sizeof(unsigned int));
ptcache_file_write(pf, out, out_len, sizeof(unsigned char));
}
else
ptcache_file_write(pf, in, in_len, sizeof(unsigned char));
if(compressed == 2)
{
ptcache_file_write(pf, &sizeOfIt, 1, sizeof(unsigned int));
ptcache_file_write(pf, props, sizeOfIt, sizeof(unsigned char));
}
MEM_freeN(props);
return r;
}
static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
if(sds->fluid)
{
if(sds->fluid) {
size_t res = sds->res[0]*sds->res[1]*sds->res[2];
float *dens, *densold, *heat, *heatold, *vx, *vy, *vz;
smoke_export(sds->fluid, &dens, &densold, &heat, &heatold, &vx, &vy, &vz);
ptcache_file_write(pf, dens, res, sizeof(float));
ptcache_file_write(pf, densold, res, sizeof(float));
ptcache_file_write(pf, heat, res, sizeof(float));
ptcache_file_write(pf, heatold, res, sizeof(float));
ptcache_file_write(pf, vx, res, sizeof(float));
ptcache_file_write(pf, vy, res, sizeof(float));
ptcache_file_write(pf, vz, res, sizeof(float));
float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold;
unsigned char *obstacles;
unsigned int in_len = sizeof(float)*(unsigned int)res;
unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
int mode = res >= 1000000 ? 2 : 1;
smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
ptcache_compress_write(pf, (unsigned char *)sds->view3d, in_len*4, out, mode);
ptcache_compress_write(pf, (unsigned char *)dens, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)densold, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)heat, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)heatold, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)vx, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)vy, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)vz, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)vxold, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)vyold, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)vzold, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode);
ptcache_file_write(pf, &dt, 1, sizeof(float));
ptcache_file_write(pf, &dx, 1, sizeof(float));
MEM_freeN(out);
return 1;
}
@@ -513,32 +591,134 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
return 0;
}
static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
/*
if(sds->wt) {
unsigned int res_big[3];
size_t res = sds->res[0]*sds->res[1]*sds->res[2];
float *dens, *densold, *tcu, *tcv, *tcw;
unsigned int in_len = sizeof(float)*(unsigned int)res;
unsigned int in_len_big = sizeof(float) * (unsigned int)res_big;
unsigned char *out;
int mode;
smoke_turbulence_get_res(sds->wt, res_big);
mode = res_big[0]*res_big[1]*res_big[2] >= 1000000 ? 2 : 1;
smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer");
ptcache_compress_write(pf, (unsigned char *)dens, in_len_big, out, mode);
ptcache_compress_write(pf, (unsigned char *)densold, in_len_big, out, mode);
MEM_freeN(out);
out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
ptcache_compress_write(pf, (unsigned char *)tcu, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)tcv, in_len, out, mode);
ptcache_compress_write(pf, (unsigned char *)tcw, in_len, out, mode);
MEM_freeN(out);
return 1;
}
*/
return 0;
}
// forward decleration
static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size);
static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigned int len)
{
int r;
unsigned char compressed = 0;
unsigned int in_len;
unsigned int out_len = len;
unsigned char *in;
unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
size_t sizeOfIt = 5;
ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
if(compressed) {
ptcache_file_read(pf, &in_len, 1, sizeof(unsigned int));
in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
if(compressed == 1)
r = lzo1x_decompress(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
else if(compressed == 2)
{
size_t leni = in_len, leno = out_len;
ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
}
MEM_freeN(in);
}
else {
ptcache_file_read(pf, result, len, sizeof(unsigned char));
}
MEM_freeN(props);
return r;
}
static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
if(sds->fluid)
{
if(sds->fluid) {
size_t res = sds->res[0]*sds->res[1]*sds->res[2];
float *dens, *densold, *heat, *heatold, *vx, *vy, *vz;
float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold;
unsigned char *obstacles;
unsigned int out_len = (unsigned int)res * sizeof(float);
smoke_export(sds->fluid, &dens, &densold, &heat, &heatold, &vx, &vy, &vz);
smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
ptcache_file_read(pf, dens, res, sizeof(float));
ptcache_file_read(pf, densold, res, sizeof(float));
ptcache_file_read(pf, heat, res, sizeof(float));
ptcache_file_read(pf, heatold, res, sizeof(float));
ptcache_file_read(pf, vx, res, sizeof(float));
ptcache_file_read(pf, vy, res, sizeof(float));
ptcache_file_read(pf, vz, res, sizeof(float));
ptcache_compress_read(pf, (unsigned char *)sds->view3d, out_len*4);
ptcache_compress_read(pf, (unsigned char*)dens, out_len);
ptcache_compress_read(pf, (unsigned char*)densold, out_len);
ptcache_compress_read(pf, (unsigned char*)heat, out_len);
ptcache_compress_read(pf, (unsigned char*)heatold, out_len);
ptcache_compress_read(pf, (unsigned char*)vx, out_len);
ptcache_compress_read(pf, (unsigned char*)vy, out_len);
ptcache_compress_read(pf, (unsigned char*)vz, out_len);
ptcache_compress_read(pf, (unsigned char*)vxold, out_len);
ptcache_compress_read(pf, (unsigned char*)vyold, out_len);
ptcache_compress_read(pf, (unsigned char*)vzold, out_len);
ptcache_compress_read(pf, (unsigned char*)obstacles, (unsigned int)res);
ptcache_file_read(pf, &dt, 1, sizeof(float));
ptcache_file_read(pf, &dx, 1, sizeof(float));
}
}
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd, int num)
static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
/*
if(sds->fluid) {
unsigned int res[3];
float *dens, *densold, *tcu, *tcv, *tcw;
unsigned int out_len = sizeof(float)*(unsigned int)res;
smoke_turbulence_get_res(sds->wt, res);
smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
ptcache_compress_read(pf, (unsigned char*)dens, out_len);
}
*/
}
void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd)
{
SmokeDomainSettings *sds = smd->domain;
@@ -547,24 +727,21 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
pid->ob= ob;
pid->calldata= smd;
// if(num == 0)
pid->type= PTCACHE_TYPE_SMOKE_DOMAIN_LOW;
// else if(num == 1)
// pid->type= PTCACHE_TYPE_SMOKE_DOMAIN_HIGH;
pid->type= PTCACHE_TYPE_SMOKE_DOMAIN;
pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)smd);
pid->cache= sds->point_cache;
pid->cache_ptr= &sds->point_cache;
pid->ptcaches= &sds->ptcaches;
pid->totpoint= pid->totwrite= ptcache_totpoint_smoke;
pid->write_elem= NULL;
pid->read_elem= NULL;
pid->read_stream = ptcache_read_smoke;
pid->write_stream = ptcache_write_smoke;
pid->interpolate_elem= NULL;
pid->write_header= ptcache_write_basic_header;
@@ -573,7 +750,6 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
pid->data_types= (1<<BPHYS_DATA_LOCATION); // bogus values tot make pointcache happy
pid->info_types= 0;
}
#endif // XXX smoke poitcache stuff breaks compiling
void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
{
@@ -633,18 +809,15 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
BLI_addtail(lb, pid);
}
/*
// enabled on next commit
if(md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md, 0);
BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md);
BLI_addtail(lb, pid);
}
}
*/
}
}
@@ -1140,13 +1313,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(use_old) {
if(pid->read_elem && ptcache_file_read(pf, (void*)old_data1, 1, old_elemsize))
pid->read_elem(i, pid->calldata, NULL, frs_sec, cfra, old_data1);
else
else if(pid->read_elem)
{ error = 1; break; }
}
else {
if(pid->read_elem && (pm || ptcache_file_read_data(pf)))
pid->read_elem(*index, pid->calldata, pm ? pm->cur : pf->cur, frs_sec, cfra1 ? (float)cfra1 : (float)cfrai, NULL);
else
else if(pid->read_elem)
{ error = 1; break; }
}
@@ -1185,7 +1358,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else
{ error = 1; break; }
}
else
else if(pid->read_elem)
{ error = 1; break; }
}
else {
@@ -1197,7 +1370,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else
{ error = 1; break; }
}
else
else if(pid->read_elem)
{ error = 1; break; }
}
@@ -1639,8 +1812,11 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
sbFreeSimulation(pid->calldata);
else if(pid->type == PTCACHE_TYPE_PARTICLES)
psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH);
else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN_LOW)
else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
{
smokeModifier_reset(pid->calldata);
printf("reset PTCACHE_TYPE_SMOKE_DOMAIN\n");
}
}
if(clear)
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
@@ -1689,17 +1865,14 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
}
/*
// enabled on next commit
if(md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md, 0);
BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md);
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
}
}
*/
}
return reset;

View File

@@ -54,10 +54,13 @@
#include "BKE_DerivedMesh.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_smoke.h"
#include "BKE_utildefines.h"
#include "DNA_customdata_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -120,9 +123,9 @@ struct DerivedMesh;
struct SmokeModifierData;
// forward declerations
static void get_cell(struct SmokeModifierData *smd, float *pos, int *cell, int correct);
static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, int correct);
void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct);
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light);
#define TRI_UVOFFSET (1./4.)
@@ -205,17 +208,18 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
// TODO: put in failsafe if res<=0 - dg
// printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
// dt max is 0.1
smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, 0.1);
smd->domain->wt = smoke_turbulence_init(smd->domain->res, (smd->domain->flags & MOD_SMOKE_HIGHRES) ? (smd->domain->amplify + 1) : 0, smd->domain->noise);
smd->time = scene->r.cfra;
smd->domain->firstframe = smd->time;
smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
if(smd->domain->wt)
smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength));
if(!smd->domain->view3d)
{
// TVox is for transparency
smd->domain->view3d = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2]*4, "Smoke_tVox");
}
smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
return 1;
}
@@ -256,7 +260,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
SmokeCollSettings *scs = smd->coll;
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getFaceArray(dm);
size_t i = 0, divs = 0;
size_t i = 0;
int divs = 0;
int *tridivs = NULL;
float cell_len = 1.0 / 50.0; // for res = 50
size_t newdivs = 0;
@@ -507,27 +512,14 @@ void smokeModifier_freeDomain(SmokeModifierData *smd)
if(smd->domain)
{
// free visualisation buffers
if(smd->domain->bind)
{
glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
MEM_freeN(smd->domain->bind);
}
smd->domain->max_textures = 0; // unnecessary but let's be sure
if(smd->domain->tray)
MEM_freeN(smd->domain->tray);
if(smd->domain->tvox)
MEM_freeN(smd->domain->tvox);
if(smd->domain->traybig)
MEM_freeN(smd->domain->traybig);
if(smd->domain->tvoxbig)
MEM_freeN(smd->domain->tvoxbig);
if(smd->domain->view3d)
MEM_freeN(smd->domain->view3d);
if(smd->domain->fluid)
smoke_free(smd->domain->fluid);
if(smd->domain->wt)
smoke_turbulence_free(smd->domain->wt);
BKE_ptcache_free_list(&smd->domain->ptcaches);
smd->domain->point_cache = NULL;
MEM_freeN(smd->domain);
smd->domain = NULL;
@@ -582,44 +574,24 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
{
if(smd->domain)
{
// free visualisation buffers
if(smd->domain->bind)
{
glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
MEM_freeN(smd->domain->bind);
smd->domain->bind = NULL;
}
smd->domain->max_textures = 0;
if(smd->domain->viewsettings < MOD_SMOKE_VIEW_USEBIG)
smd->domain->viewsettings = 0;
else
smd->domain->viewsettings = MOD_SMOKE_VIEW_USEBIG;
if(smd->domain->view3d)
MEM_freeN(smd->domain->view3d);
smd->domain->view3d = NULL;
if(smd->domain->tray)
MEM_freeN(smd->domain->tray);
if(smd->domain->tvox)
MEM_freeN(smd->domain->tvox);
if(smd->domain->traybig)
MEM_freeN(smd->domain->traybig);
if(smd->domain->tvoxbig)
MEM_freeN(smd->domain->tvoxbig);
smd->domain->tvox = NULL;
smd->domain->tray = NULL;
smd->domain->tvoxbig = NULL;
smd->domain->traybig = NULL;
smd->domain->tex = NULL;
if(smd->domain->fluid)
{
smoke_free(smd->domain->fluid);
smd->domain->fluid = NULL;
}
if(smd->domain->wt)
{
smoke_turbulence_free(smd->domain->wt);
smd->domain->wt = NULL;
}
smd->domain->point_cache->flag &= ~PTCACHE_SIMULATION_VALID;
smd->domain->point_cache->flag |= PTCACHE_OUTDATED;
smd->domain->point_cache->simframe= 0;
smd->domain->point_cache->last_exact= 0;
printf("reset_domain\n");
}
else if(smd->flow)
{
@@ -677,31 +649,24 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->domain->smd = smd;
smd->domain->point_cache = BKE_ptcache_add(&smd->domain->ptcaches);
smd->domain->point_cache->flag |= PTCACHE_DISK_CACHE;
smd->domain->point_cache->step = 1;
/* set some standard values */
smd->domain->fluid = NULL;
smd->domain->wt = NULL;
smd->domain->eff_group = NULL;
smd->domain->fluid_group = NULL;
smd->domain->coll_group = NULL;
smd->domain->maxres = 32;
smd->domain->amplify = 1;
smd->domain->omega = 1.0;
smd->domain->alpha = -0.001;
smd->domain->beta = 0.1;
smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG;
smd->domain->strength = 2.0;
smd->domain->noise = MOD_SMOKE_NOISEWAVE;
smd->domain->visibility = 1;
smd->domain->diss_speed = 5;
// init 3dview buffer
smd->domain->tvox = NULL;
smd->domain->tray = NULL;
smd->domain->tvoxbig = NULL;
smd->domain->traybig = NULL;
smd->domain->viewsettings = 0;
smd->domain->bind = NULL;
smd->domain->max_textures = 0;
smd->domain->view3d = NULL;
smd->domain->tex = NULL;
}
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
{
@@ -736,15 +701,15 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
}
// forward declaration
void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big);
void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm);
void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
if(scene->r.cfra >= smd->time)
smokeModifier_init(smd, ob, scene, dm);
if((smd->type & MOD_SMOKE_TYPE_FLOW))
{
if(scene->r.cfra >= smd->time)
smokeModifier_init(smd, ob, scene, dm);
if(scene->r.cfra > smd->time)
{
// XXX TODO
@@ -764,6 +729,9 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_COLL)
{
if(scene->r.cfra >= smd->time)
smokeModifier_init(smd, ob, scene, dm);
if(scene->r.cfra > smd->time)
{
// XXX TODO
@@ -786,459 +754,484 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
PointCache *cache;
PTCacheID pid;
float timescale;
int cache_result = 0;
int startframe, endframe, framenr;
SmokeDomainSettings *sds = smd->domain;
float light[3] = {0.0,0.0,0.0};
int have_lamp = 0;
printf("smd->type & MOD_SMOKE_TYPE_DOMAIN\n");
framenr = scene->r.cfra;
cache = sds->point_cache;
BKE_ptcache_id_from_smoke(&pid, ob, smd);
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
/* handle continuous simulation with the play button */
if(BKE_ptcache_get_continue_physics())
{
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
cache->last_exact= 0;
smokeModifier_init(smd, ob, scene, dm);
smoke_simulate_domain(smd, scene, ob, dm);
return;
}
if(scene->r.cfra > smd->time)
if(framenr < startframe)
{
GroupObject *go = NULL;
Base *base = NULL;
tstart();
if(sds->flags & MOD_SMOKE_DISSOLVE)
{
smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
if(sds->wt)
smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
}
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
cache->last_exact= 0;
/* reset view for new frame */
if(sds->viewsettings < MOD_SMOKE_VIEW_USEBIG)
sds->viewsettings = 0;
else
sds->viewsettings = MOD_SMOKE_VIEW_USEBIG;
// do flows and fluids
if(1)
{
Object *otherobj = NULL;
ModifierData *md = NULL;
if(sds->fluid_group) // we use groups since we have 2 domains
go = sds->fluid_group->gobject.first;
else
base = scene->base.first;
while(base || go)
{
otherobj = NULL;
if(sds->fluid_group)
{
if(go->ob)
otherobj = go->ob;
}
else
otherobj = base->object;
if(!otherobj)
{
if(sds->fluid_group)
go = go->next;
else
base= base->next;
continue;
}
md = modifiers_findByType(otherobj, eModifierType_Smoke);
// check for active smoke modifier
if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
{
SmokeModifierData *smd2 = (SmokeModifierData *)md;
// check for initialized smoke object
if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
{
// we got nice flow object
SmokeFlowSettings *sfs = smd2->flow;
if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
{
ParticleSystem *psys = sfs->psys;
ParticleSettings *part=psys->part;
ParticleData *pa = NULL;
int p = 0;
float *density = smoke_get_density(sds->fluid);
float *bigdensity = smoke_turbulence_get_density(sds->wt);
float *heat = smoke_get_heat(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);
unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
int bigres[3];
printf("found flow psys\n");
// mostly copied from particle code
for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
{
int cell[3];
size_t i = 0;
size_t index = 0;
int badcell = 0;
if(pa->alive == PARS_KILLED) continue;
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
// VECCOPY(pos, pa->state.co);
// Mat4MulVecfl (ob->imat, pos);
// 1. get corresponding cell
get_cell(smd, pa->state.co, cell, 0);
// check if cell is valid (in the domain boundary)
for(i = 0; i < 3; i++)
{
if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
{
badcell = 1;
break;
}
}
if(badcell)
continue;
// 2. set cell values (heat, density and velocity)
index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
{
// heat[index] += sfs->temp * 0.1;
// density[index] += sfs->density * 0.1;
heat[index] = sfs->temp;
density[index] = sfs->density;
/*
velocity_x[index] = pa->state.vel[0];
velocity_y[index] = pa->state.vel[1];
velocity_z[index] = pa->state.vel[2];
*/
obstacle[index] |= 2;
// we need different handling for the high-res feature
if(bigdensity)
{
// init all surrounding cells according to amplification, too
int i, j, k;
smoke_turbulence_get_res(smd->domain->wt, bigres);
for(i = 0; i < smd->domain->amplify + 1; i++)
for(j = 0; j < smd->domain->amplify + 1; j++)
for(k = 0; k < smd->domain->amplify + 1; k++)
{
index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
bigdensity[index] = sfs->density;
}
}
}
else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
{
heat[index] = 0.f;
density[index] = 0.f;
velocity_x[index] = 0.f;
velocity_y[index] = 0.f;
velocity_z[index] = 0.f;
// we need different handling for the high-res feature
if(bigdensity)
{
// init all surrounding cells according to amplification, too
int i, j, k;
smoke_turbulence_get_res(smd->domain->wt, bigres);
for(i = 0; i < smd->domain->amplify + 1; i++)
for(j = 0; j < smd->domain->amplify + 1; j++)
for(k = 0; k < smd->domain->amplify + 1; k++)
{
index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
bigdensity[index] = 0.f;
}
}
}
}
}
else
{
/*
for()
{
// no psys
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist = FLT_MAX;
BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
}*/
}
}
}
if(sds->fluid_group)
go = go->next;
else
base= base->next;
}
}
// do effectors
/*
if(sds->eff_group)
{
for(go = sds->eff_group->gobject.first; go; go = go->next)
{
if(go->ob)
{
if(ob->pd)
{
}
}
}
}
*/
// do collisions
if(1)
{
Object *otherobj = NULL;
ModifierData *md = NULL;
if(sds->coll_group) // we use groups since we have 2 domains
go = sds->coll_group->gobject.first;
else
base = scene->base.first;
while(base || go)
{
otherobj = NULL;
if(sds->coll_group)
{
if(go->ob)
otherobj = go->ob;
}
else
otherobj = base->object;
if(!otherobj)
{
if(sds->coll_group)
go = go->next;
else
base= base->next;
continue;
}
md = modifiers_findByType(otherobj, eModifierType_Smoke);
// check for active smoke modifier
if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
{
SmokeModifierData *smd2 = (SmokeModifierData *)md;
if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
{
// we got nice collision object
SmokeCollSettings *scs = smd2->coll;
size_t i, j;
unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
for(i = 0; i < scs->numpoints; i++)
{
int badcell = 0;
size_t index = 0;
int cell[3];
// 1. get corresponding cell
get_cell(smd, &scs->points[3 * i], cell, 0);
// check if cell is valid (in the domain boundary)
for(j = 0; j < 3; j++)
if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
{
badcell = 1;
break;
}
if(badcell)
continue;
// 2. set cell values (heat, density and velocity)
index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
// printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
// printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
obstacles[index] = 1;
// for moving gobstacles
/*
const LbmFloat maxVelVal = 0.1666;
const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); {
const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;
USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
if(usqr>maxusqr) {
// cutoff at maxVelVal
for(int jj=0; jj<3; jj++) {
if(objvel[jj]>0.) objvel[jj] = maxVelVal;
if(objvel[jj]<0.) objvel[jj] = -maxVelVal;
}
} }
const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );
const LbmVec oldov=objvel; // debug
objvel = vec2L((*pNormals)[n]) *dp;
*/
}
}
}
if(sds->coll_group)
go = go->next;
else
base= base->next;
}
}
// set new time
smd->time = scene->r.cfra;
// simulate the actual smoke (c++ code in intern/smoke)
smoke_step(sds->fluid, smd->time);
if(sds->wt)
smoke_turbulence_step(sds->wt, sds->fluid);
tend();
printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
}
else if(scene->r.cfra < smd->time)
{
// we got back in time, reset smoke in this case (TODO: use cache later)
smd->time = scene->r.cfra;
smokeModifier_reset(smd);
// smd->time = scene->r.cfra;
// smokeModifier_reset(smd);
return;
}
else if(framenr > endframe)
{
framenr = endframe;
}
if(!(cache->flag & PTCACHE_SIMULATION_VALID))
{
// printf("reseting\n");
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
}
smokeModifier_init(smd, ob, scene, dm);
/* try to read from cache */
cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
printf("cache_result: %d\n", cache_result);
if(cache_result == PTCACHE_READ_EXACT)
{
SmokeDomainSettings *sds = smd->domain;
cache->flag |= PTCACHE_SIMULATION_VALID;
cache->simframe= framenr;
sds->v3dnum = framenr;
// printf("PTCACHE_READ_EXACT\n");
return;
}
else if(cache_result==PTCACHE_READ_OLD)
{
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
// printf("PTCACHE_READ_OLD\n");
cache->flag |= PTCACHE_SIMULATION_VALID;
}
else if(ob->id.lib || (cache->flag & PTCACHE_BAKED))
{
/* if baked and nothing in cache, do nothing */
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
cache->last_exact= 0;
// printf("PTCACHE_BAKED\n");
return;
}
else if((cache_result==0) && (startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID))
{
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
cache->last_exact= 0;
return;
}
/* do simulation */
// low res
cache->flag |= PTCACHE_SIMULATION_VALID;
cache->simframe= framenr;
smoke_simulate_domain(smd, scene, ob, dm);
{
// float light[3] = {0.0,0.0,0.0}; // TODO: take real LAMP coordinates - dg
Base *base_tmp = NULL;
for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
{
if(base_tmp->object->type == OB_LAMP)
{
Lamp *la = (Lamp *)base_tmp->object->data;
if(la->type == LA_LOCAL)
{
VECCOPY(light, base_tmp->object->obmat[3]);
have_lamp = 1;
break;
}
}
}
}
smoke_prepare_View(smd, (float)framenr, light, have_lamp);
BKE_ptcache_write_cache(&pid, framenr);
printf("Writing cache_low\n");
tend();
printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
}
}
void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
{
GroupObject *go = NULL;
Base *base = NULL;
SmokeDomainSettings *sds = smd->domain;
tstart();
if(sds->flags & MOD_SMOKE_DISSOLVE)
smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
// do flows and fluids
if(1)
{
Object *otherobj = NULL;
ModifierData *md = NULL;
if(sds->fluid_group) // we use groups since we have 2 domains
go = sds->fluid_group->gobject.first;
else
base = scene->base.first;
while(base || go)
{
otherobj = NULL;
if(sds->fluid_group)
{
if(go->ob)
otherobj = go->ob;
}
else
otherobj = base->object;
if(!otherobj)
{
if(sds->fluid_group)
go = go->next;
else
base= base->next;
continue;
}
md = modifiers_findByType(otherobj, eModifierType_Smoke);
// check for active smoke modifier
if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
{
SmokeModifierData *smd2 = (SmokeModifierData *)md;
// check for initialized smoke object
if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
{
// we got nice flow object
SmokeFlowSettings *sfs = smd2->flow;
if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
{
ParticleSystem *psys = sfs->psys;
ParticleSettings *part=psys->part;
ParticleData *pa = NULL;
int p = 0;
float *density = smoke_get_density(sds->fluid);
// float *bigdensity = smoke_turbulence_get_density(sds->wt);
float *heat = smoke_get_heat(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);
unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
// debug printf("found flow psys\n");
// mostly copied from particle code
for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
{
int cell[3];
size_t i = 0;
size_t index = 0;
int badcell = 0;
if(pa->alive == PARS_KILLED) continue;
else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
// VECCOPY(pos, pa->state.co);
// Mat4MulVecfl (ob->imat, pos);
// 1. get corresponding cell
get_cell(sds->p0, sds->res, sds->dx, pa->state.co, cell, 0);
// check if cell is valid (in the domain boundary)
for(i = 0; i < 3; i++)
{
if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
{
badcell = 1;
break;
}
}
if(badcell)
continue;
// 2. set cell values (heat, density and velocity)
index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
{
// heat[index] += sfs->temp * 0.1;
// density[index] += sfs->density * 0.1;
heat[index] = sfs->temp;
density[index] = sfs->density;
/*
velocity_x[index] = pa->state.vel[0];
velocity_y[index] = pa->state.vel[1];
velocity_z[index] = pa->state.vel[2];
*/
obstacle[index] |= 2;
}
else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
{
heat[index] = 0.f;
density[index] = 0.f;
velocity_x[index] = 0.f;
velocity_y[index] = 0.f;
velocity_z[index] = 0.f;
}
}
}
else
{
/*
for()
{
// no psys
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist = FLT_MAX;
BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
}*/
}
}
}
if(sds->fluid_group)
go = go->next;
else
base= base->next;
}
}
// do effectors
/*
if(sds->eff_group)
{
for(go = sds->eff_group->gobject.first; go; go = go->next)
{
if(go->ob)
{
if(ob->pd)
{
}
}
}
}
*/
// do collisions
if(1)
{
Object *otherobj = NULL;
ModifierData *md = NULL;
if(sds->coll_group) // we use groups since we have 2 domains
go = sds->coll_group->gobject.first;
else
base = scene->base.first;
while(base || go)
{
otherobj = NULL;
if(sds->coll_group)
{
if(go->ob)
otherobj = go->ob;
}
else
otherobj = base->object;
if(!otherobj)
{
if(sds->coll_group)
go = go->next;
else
base= base->next;
continue;
}
md = modifiers_findByType(otherobj, eModifierType_Smoke);
// check for active smoke modifier
if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
{
SmokeModifierData *smd2 = (SmokeModifierData *)md;
if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
{
// we got nice collision object
SmokeCollSettings *scs = smd2->coll;
size_t i, j;
unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
for(i = 0; i < scs->numpoints; i++)
{
int badcell = 0;
size_t index = 0;
int cell[3];
// 1. get corresponding cell
get_cell(sds->p0, sds->res, sds->dx, &scs->points[3 * i], cell, 0);
// check if cell is valid (in the domain boundary)
for(j = 0; j < 3; j++)
if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
{
badcell = 1;
break;
}
if(badcell)
continue;
// 2. set cell values (heat, density and velocity)
index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
// printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
// printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
obstacles[index] = 1;
// for moving gobstacles
/*
const LbmFloat maxVelVal = 0.1666;
const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); {
const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;
USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
if(usqr>maxusqr) {
// cutoff at maxVelVal
for(int jj=0; jj<3; jj++) {
if(objvel[jj]>0.) objvel[jj] = maxVelVal;
if(objvel[jj]<0.) objvel[jj] = -maxVelVal;
}
} }
const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );
const LbmVec oldov=objvel; // debug
objvel = vec2L((*pNormals)[n]) *dp;
*/
}
}
}
if(sds->coll_group)
go = go->next;
else
base= base->next;
}
}
// set new time
smd->time = scene->r.cfra;
// simulate the actual smoke (c++ code in intern/smoke)
smoke_step(sds->fluid, smd->time);
}
static int calc_voxel_transp(float *input, int res[3], int *pixel, float *tRay)
{
const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
// T_ray *= T_vox
*tRay *= input[index*4];
return *tRay;
}
// forward decleration
void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb);
// update necessary information for 3dview
void smoke_prepare_View(SmokeModifierData *smd, float *light)
void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light)
{
float *density = NULL;
int x, y, z;
if(!smd->domain->tray)
{
// TRay is for self shadowing
smd->domain->tray = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2], "Smoke_tRay");
}
if(!smd->domain->tvox)
{
// TVox is for tranaparency
smd->domain->tvox = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2], "Smoke_tVox");
}
size_t cells, i;
SmokeDomainSettings *sds = smd->domain;
// update 3dview
density = smoke_get_density(smd->domain->fluid);
for(x = 0; x < smd->domain->res[0]; x++)
for(y = 0; y < smd->domain->res[1]; y++)
for(z = 0; z < smd->domain->res[2]; z++)
{
size_t index;
for(y = 0; y < smd->domain->res[1]; y++)
for(z = 0; z < smd->domain->res[2]; z++)
{
size_t index;
index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
// Transparency computation
// formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
// T_vox = exp(-C_ext * h)
// C_ext/sigma_t = density * C_ext
smoke_set_tvox(smd, index, exp(-density[index] * 7.0 * smd->domain->dx));
}
smoke_calc_transparency(smd, light, 0);
}
index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
// Transparency computation
// formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
// T_vox = exp(-C_ext * h)
// C_ext/sigma_t = density * C_ext
smd->domain->view3d[index * 4] = smd->domain->view3d[index * 4 + 1] =
smd->domain->view3d[index * 4 + 2] = exp(-density[index] * 7.0 * smd->domain->dx);
smd->domain->view3d[index * 4 + 3] = 1.0 - smd->domain->view3d[index * 4];
}
// update necessary information for 3dview ("high res" option)
void smoke_prepare_bigView(SmokeModifierData *smd, float *light)
{
float *density = NULL;
size_t i = 0;
int bigres[3];
smoke_turbulence_get_res(smd->domain->wt, bigres);
if(!smd->domain->traybig)
if(have_light)
{
// TRay is for self shadowing
smd->domain->traybig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tRayBig");
smoke_calc_transparency(sds->view3d, sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp);
cells = smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2];
for(i = 0; i < cells; i++)
{
smd->domain->view3d[i * 4] = smd->domain->view3d[i * 4 + 1] =
smd->domain->view3d[i * 4 + 2] = smd->domain->view3d[i * 4 + 1] * smd->domain->view3d[i * 4 + 0];
}
}
if(!smd->domain->tvoxbig)
{
// TVox is for tranaparency
smd->domain->tvoxbig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tVoxBig");
}
density = smoke_turbulence_get_density(smd->domain->wt);
for (i = 0; i < bigres[0] * bigres[1] * bigres[2]; i++)
{
// Transparency computation
// formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
// T_vox = exp(-C_ext * h)
// C_ext/sigma_t = density * C_ext
smoke_set_bigtvox(smd, i, exp(-density[i] * 7.0 * smd->domain->dx / (smd->domain->amplify + 1)) );
}
smoke_calc_transparency(smd, light, 1);
}
float smoke_get_tvox(SmokeModifierData *smd, size_t index)
{
return smd->domain->tvox[index];
}
void smoke_set_tvox(SmokeModifierData *smd, size_t index, float tvox)
{
smd->domain->tvox[index] = tvox;
}
float smoke_get_tray(SmokeModifierData *smd, size_t index)
{
return smd->domain->tray[index];
}
void smoke_set_tray(SmokeModifierData *smd, size_t index, float transparency)
{
smd->domain->tray[index] = transparency;
}
float smoke_get_bigtvox(SmokeModifierData *smd, size_t index)
{
return smd->domain->tvoxbig[index];
}
void smoke_set_bigtvox(SmokeModifierData *smd, size_t index, float tvox)
{
smd->domain->tvoxbig[index] = tvox;
}
float smoke_get_bigtray(SmokeModifierData *smd, size_t index)
{
return smd->domain->traybig[index];
}
void smoke_set_bigtray(SmokeModifierData *smd, size_t index, float transparency)
{
smd->domain->traybig[index] = transparency;
smd->domain->v3dnum = framenr;
}
long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
@@ -1259,34 +1252,7 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
return totalMB;
}
static void calc_voxel_transp(SmokeModifierData *smd, int *pixel, float *tRay)
{
// printf("Pixel(%d, %d, %d)\n", pixel[0], pixel[1], pixel[2]);
const size_t index = smoke_get_index(pixel[0], smd->domain->res[0], pixel[1], smd->domain->res[1], pixel[2]);
// T_ray *= T_vox
*tRay *= smoke_get_tvox(smd, index);
}
static void calc_voxel_transp_big(SmokeModifierData *smd, int *pixel, float *tRay)
{
int bigres[3];
size_t index;
smoke_turbulence_get_res(smd->domain->wt, bigres);
index = smoke_get_index(pixel[0], bigres[0], pixel[1], bigres[1], pixel[2]);
/*
if(index > bigres[0]*bigres[1]*bigres[2])
printf("pixel[0]: %d, [1]: %d, [2]: %d\n", pixel[0], pixel[1], pixel[2]);
*/
// T_ray *= T_vox
*tRay *= smoke_get_bigtvox(smd, index);
}
static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, int big)
static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *input, int res[3])
{
int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
int pixel[3];
@@ -1313,11 +1279,7 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
err_1 = dy2 - l;
err_2 = dz2 - l;
for (i = 0; i < l; i++) {
if(!big)
calc_voxel_transp(smd, pixel, tRay);
else
calc_voxel_transp_big(smd, pixel, tRay);
if(*tRay < 0.0f)
if(cb(input, res, pixel, tRay) < 0.0)
return;
if (err_1 > 0) {
pixel[1] += y_inc;
@@ -1335,11 +1297,7 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
err_1 = dx2 - m;
err_2 = dz2 - m;
for (i = 0; i < m; i++) {
if(!big)
calc_voxel_transp(smd, pixel, tRay);
else
calc_voxel_transp_big(smd, pixel, tRay);
if(*tRay < 0.0f)
if(cb(input, res, pixel, tRay) < 0.0f)
return;
if (err_1 > 0) {
pixel[0] += x_inc;
@@ -1357,11 +1315,7 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
err_1 = dy2 - n;
err_2 = dx2 - n;
for (i = 0; i < n; i++) {
if(!big)
calc_voxel_transp(smd, pixel, tRay);
else
calc_voxel_transp_big(smd, pixel, tRay);
if(*tRay < 0.0f)
if(cb(input, res, pixel, tRay) < 0.0f)
return;
if (err_1 > 0) {
pixel[1] += y_inc;
@@ -1376,41 +1330,15 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
pixel[2] += z_inc;
}
}
if(!big)
calc_voxel_transp(smd, pixel, tRay);
else
calc_voxel_transp_big(smd, pixel, tRay);
cb(input, res, pixel, tRay);
}
static void get_cell(struct SmokeModifierData *smd, float *pos, int *cell, int correct)
static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct)
{
float tmp[3];
VECSUB(tmp, pos, smd->domain->p0);
VecMulf(tmp, 1.0 / smd->domain->dx);
if(correct)
{
cell[0] = MIN2(smd->domain->res[0] - 1, MAX2(0, (int)floor(tmp[0])));
cell[1] = MIN2(smd->domain->res[1] - 1, MAX2(0, (int)floor(tmp[1])));
cell[2] = MIN2(smd->domain->res[2] - 1, MAX2(0, (int)floor(tmp[2])));
}
else
{
cell[0] = (int)floor(tmp[0]);
cell[1] = (int)floor(tmp[1]);
cell[2] = (int)floor(tmp[2]);
}
}
static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, int correct)
{
float tmp[3];
int res[3];
smoke_turbulence_get_res(smd->domain->wt, res);
VECSUB(tmp, pos, smd->domain->p0);
VecMulf(tmp, (smd->domain->amplify + 1)/ smd->domain->dx );
VECSUB(tmp, pos, p0);
VecMulf(tmp, 1.0 / dx);
if(correct)
{
@@ -1426,43 +1354,23 @@ static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, in
}
}
void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big)
void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb)
{
int x, y, z;
float bv[6];
int res[3];
float bigfactor = 1.0;
// x
bv[0] = smd->domain->p0[0];
bv[1] = smd->domain->p1[0];
bv[0] = p0[0];
bv[1] = p1[0];
// y
bv[2] = smd->domain->p0[1];
bv[3] = smd->domain->p1[1];
bv[2] = p0[1];
bv[3] = p1[1];
// z
bv[4] = smd->domain->p0[2];
bv[5] = smd->domain->p1[2];
/*
printf("bv[0]: %f, [1]: %f, [2]: %f, [3]: %f, [4]: %f, [5]: %f\n", bv[0], bv[1], bv[2], bv[3], bv[4], bv[5]);
bv[4] = p0[2];
bv[5] = p1[2];
printf("p0[0]: %f, p0[1]: %f, p0[2]: %f\n", smd->domain->p0[0], smd->domain->p0[1], smd->domain->p0[2]);
printf("p1[0]: %f, p1[1]: %f, p1[2]: %f\n", smd->domain->p1[0], smd->domain->p1[1], smd->domain->p1[2]);
printf("dx: %f, amp: %d\n", smd->domain->dx, smd->domain->amplify);
*/
if(!big)
{
res[0] = smd->domain->res[0];
res[1] = smd->domain->res[1];
res[2] = smd->domain->res[2];
}
else
{
smoke_turbulence_get_res(smd->domain->wt, res);
bigfactor = 1.0 / (smd->domain->amplify + 1);
}
#pragma omp parallel for schedule(static) private(y, z) shared(big, smd, light, res, bigfactor)
// #pragma omp parallel for schedule(static) private(y, z)
for(x = 0; x < res[0]; x++)
for(y = 0; y < res[1]; y++)
for(z = 0; z < res[2]; z++)
@@ -1475,41 +1383,26 @@ void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int bi
index = smoke_get_index(x, res[0], y, res[1], z);
// voxelCenter = m_voxelarray[i].GetCenter();
voxelCenter[0] = smd->domain->p0[0] + smd->domain->dx * bigfactor * x + smd->domain->dx * bigfactor * 0.5;
voxelCenter[1] = smd->domain->p0[1] + smd->domain->dx * bigfactor * y + smd->domain->dx * bigfactor * 0.5;
voxelCenter[2] = smd->domain->p0[2] + smd->domain->dx * bigfactor * z + smd->domain->dx * bigfactor * 0.5;
// printf("vc[0]: %f, vc[1]: %f, vc[2]: %f\n", voxelCenter[0], voxelCenter[1], voxelCenter[2]);
// printf("light[0]: %f, light[1]: %f, light[2]: %f\n", light[0], light[1], light[2]);
voxelCenter[0] = p0[0] + dx * x + dx * 0.5;
voxelCenter[1] = p0[1] + dx * y + dx * 0.5;
voxelCenter[2] = p0[2] + dx * z + dx * 0.5;
// get starting position (in voxel coords)
if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON)
{
// we're ouside
// printf("out: pos[0]: %f, pos[1]: %f, pos[2]: %f\n", pos[0], pos[1], pos[2]);
if(!big)
get_cell(smd, pos, cell, 1);
else
get_bigcell(smd, pos, cell, 1);
get_cell(p0, res, dx, pos, cell, 1);
}
else
{
// printf("in: pos[0]: %f, pos[1]: %f, pos[2]: %f\n", light[0], light[1], light[2]);
// we're inside
if(!big)
get_cell(smd, light, cell, 1);
else
get_bigcell(smd, light, cell, 1);
get_cell(p0, res, dx, light, cell, 1);
}
// printf("cell - [0]: %d, [1]: %d, [2]: %d\n", cell[0], cell[1], cell[2]);
bresenham_linie_3D(smd, cell[0], cell[1], cell[2], x, y, z, &tRay, big);
bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, res);
if(!big)
smoke_set_tray(smd, index, tRay);
else
smoke_set_bigtray(smd, index, tRay);
// convention -> from a RGBA float array, use G value for tRay
result[index*4 + 1] = tRay;
}
}

View File

@@ -0,0 +1,137 @@
/**
* smokehighres.c
*
* $Id$
*
* ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Daniel Genrich
*
* ***** END GPL LICENSE BLOCK *****
*/
/* Part of the code copied from elbeem fluid library, copyright by Nils Thuerey */
#include "DNA_scene_types.h"
#include "DNA_listBase.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_smoke_types.h"
#include "BKE_modifier.h"
#include "BKE_smoke.h"
#include "BKE_pointcache.h"
#include "smoke_API.h"
// we need different handling for the high-res feature
/*
if(bigdensity)
{
// init all surrounding cells according to amplification, too
int i, j, k;
smoke_turbulence_get_res(smd->domain->wt, bigres);
for(i = 0; i < smd->domain->amplify + 1; i++)
for(j = 0; j < smd->domain->amplify + 1; j++)
for(k = 0; k < smd->domain->amplify + 1; k++)
{
index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
bigdensity[index] = sfs->density;
}
}
*/
static void smokeHRinit(SmokeHRModifierData *shrmd, SmokeDomainSettings *sds)
{
if(!shrmd->wt)
{
shrmd->wt = smoke_turbulence_init(sds->res, shrmd->amplify + 1, shrmd->noise);
smoke_turbulence_initBlenderRNA(shrmd->wt, &shrmd->strength);
}
}
void smokeHRModifier_free(SmokeHRModifierData *shrmd)
{
if(shrmd->wt)
smoke_turbulence_free(shrmd->wt);
BKE_ptcache_free_list(&shrmd->ptcaches);
shrmd->point_cache = NULL;
}
void smokeHRModifier_do(SmokeHRModifierData *shrmd, Scene *scene, Object *ob, int useRenderParams, int isFinalCalc)
{
ModifierData *md = NULL;
SmokeModifierData *smd = NULL;
SmokeDomainSettings *sds = NULL;
// find underlaying smoke domain
smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke);
if(!(smd && smd->type == MOD_SMOKE_TYPE_DOMAIN))
return;
sds = smd->domain;
smokeHRinit(shrmd, sds);
// smoke_turbulence_dissolve(shrmd->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
// smoke_turbulence_step(shrmd->wt, sds->fluid);
}
// update necessary information for 3dview ("high res" option)
void smoke_prepare_bigView(SmokeHRModifierData *shrmd, float *light)
{
float *density = NULL;
size_t i = 0;
int bigres[3];
/*
smoke_turbulence_get_res(shrmd->wt, bigres);
if(!smd->domain->traybig)
{
// TRay is for self shadowing
smd->domain->traybig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tRayBig");
}
if(!smd->domain->tvoxbig)
{
// TVox is for tranaparency
smd->domain->tvoxbig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tVoxBig");
}
density = smoke_turbulence_get_density(smd->domain->wt);
for (i = 0; i < bigres[0] * bigres[1] * bigres[2]; i++)
{
// Transparency computation
// formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
// T_vox = exp(-C_ext * h)
// C_ext/sigma_t = density * C_ext
smoke_set_bigtvox(smd, i, exp(-density[i] * 7.0 * smd->domain->dx / (smd->domain->amplify + 1)) );
}
smoke_calc_transparency(smd, light, 1);
*/
}

View File

@@ -65,20 +65,22 @@
extern "C" {
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
#ifndef M_1_PI
#define M_1_PI 0.318309886183790671538
# ifndef _WIN64
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
#ifndef M_1_PI
#define M_1_PI 0.318309886183790671538
#endif
#endif
#define MAXPATHLEN MAX_PATH

View File

@@ -3669,8 +3669,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
else if (md->type==eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData*) md;
smd->point_cache = NULL;
if(smd->type==MOD_SMOKE_TYPE_DOMAIN)
{
smd->flow = NULL;
@@ -3679,23 +3677,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->domain->smd = smd;
smd->domain->fluid = NULL;
smd->domain->wt = NULL;
smd->domain->tvox = NULL;
smd->domain->tray = NULL;
smd->domain->tvoxbig = NULL;
smd->domain->traybig = NULL;
smd->domain->bind = NULL;
smd->domain->max_textures= 0;
smd->domain->view3d = NULL;
smd->domain->tex = NULL;
// do_versions trick
if(smd->domain->strength < 1.0)
smd->domain->strength = 2.0;
// reset 3dview
if(smd->domain->viewsettings < MOD_SMOKE_VIEW_USEBIG)
smd->domain->viewsettings = 0;
else
smd->domain->viewsettings = MOD_SMOKE_VIEW_USEBIG;
direct_link_pointcache_list(fd, &smd->domain->ptcaches, &smd->domain->point_cache);
}
else if(smd->type==MOD_SMOKE_TYPE_FLOW)
{

View File

@@ -1126,14 +1126,17 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
else if(md->type==eModifierType_Smoke) {
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);
else if(smd->type==MOD_SMOKE_TYPE_FLOW)
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow);
/*
else if(smd->type==MOD_SMOKE_TYPE_COLL)
else if(smd->type & MOD_SMOKE_TYPE_COLL)
writestruct(wd, DATA, "SmokeCollSettings", 1, smd->coll);
*/
if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
write_pointcaches(wd, &smd->domain->ptcaches);
}
else if(md->type==eModifierType_Fluidsim) {
FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;

View File

@@ -161,6 +161,13 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod
DAG_scene_sort(scene);
}
else if(md->type == eModifierType_Smoke) {
ModifierData *tmd = modifiers_findByType(ob, eModifierType_SmokeHR);
if(tmd) {
BLI_remlink(&ob->modifiers, tmd);
modifier_free(tmd);
}
}
BLI_remlink(&ob->modifiers, md);
modifier_free(md);

View File

@@ -553,7 +553,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
"world", "object", "mesh", "armature", "lattice", "curve",
"meta_ball", "lamp", "camera", "material", "material_slot",
"texture", "texture_slot", "bone", "edit_bone", "particle_system",
"cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL};
"cloth", "soft_body", "fluid", "smoke", "smoke_hr", "collision", "brush", NULL};
CTX_data_dir_set(result, dir);
return 1;
@@ -697,6 +697,16 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
}
else if(CTX_data_equals(member, "smoke_hr")) {
PointerRNA *ptr= get_pointer_type(path, &RNA_Object);
if(ptr && ptr->data) {
Object *ob= ptr->data;
ModifierData *md= modifiers_findByType(ob, eModifierType_SmokeHR);
CTX_data_pointer_set(result, &ob->id, &RNA_SmokeHRModifier, md);
return 1;
}
}
else if(CTX_data_equals(member, "collision")) {
PointerRNA *ptr= get_pointer_type(path, &RNA_Object);

View File

@@ -5309,356 +5309,20 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
/* draw code for smoke */
if((md = modifiers_findByType(ob, eModifierType_Smoke)))
{
SmokeModifierData *smd = (SmokeModifierData *)md;
// draw collision objects
if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)
{
/*SmokeCollSettings *scs = smd->coll;
if(scs->points)
{
size_t i;
wmLoadMatrix(rv3d->viewmat);
if(col || (ob->flag & SELECT)) cpack(0xFFFFFF);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
// glPointSize(3.0);
bglBegin(GL_POINTS);
for(i = 0; i < scs->numpoints; i++)
{
bglVertex3fv(&scs->points[3*i]);
}
bglEnd();
glPointSize(1.0);
wmMultMatrix(ob->obmat);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
if(col) cpack(col);
if(((SmokeHRModifierData *)(md = modifiers_findByType(ob, eModifierType_SmokeHR)) && (((SmokeHRModifierData *)md)->flags & MOD_SMOKE_SHOWHIGHRES))) {
// GPU_create_smoke(smd);
// draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res);
// GPU_free_smoke(smd);
}
else {
md = modifiers_findByType(ob, eModifierType_Smoke);
if (md) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain) {
GPU_create_smoke(smd);
draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res);
GPU_free_smoke(smd);
}
*/
}
// only draw domains
if(smd->domain && smd->domain->fluid)
{
int x, y, z, i;
float viewnormal[3];
int mainaxis[3] = {0,0,0};
float align = 0, signed_align = 0;
int max_textures = 0, counter_textures = 0;
float *buffer = NULL;
int res[3];
float bigfactor = 1.0;
int big = (smd->domain->flags & MOD_SMOKE_HIGHRES) && (smd->domain->viewsettings & MOD_SMOKE_VIEW_USEBIG);
int new = 0;
int have_lamp = 0;
// GUI sent redraw event
if(smd->domain->flags & MOD_SMOKE_VIEW_REDRAWNICE)
{
new = 1;
smd->domain->flags &= ~MOD_SMOKE_VIEW_REDRAWNICE;
}
if(!big)
{
res[0] = smd->domain->res[0];
res[1] = smd->domain->res[1];
res[2] = smd->domain->res[2];
}
else
{
smoke_turbulence_get_res(smd->domain->wt, res);
bigfactor = 1.0 / (smd->domain->amplify + 1);
}
wmLoadMatrix(rv3d->viewmat);
if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
// get view vector
VECCOPY(viewnormal, rv3d->viewinv[2]);
Normalize(viewnormal);
for(i = 0; i < 3; i++)
{
if(ABS(viewnormal[i]) > align)
{
mainaxis[0] = i;
align = ABS(viewnormal[i]);
signed_align = viewnormal[i];
}
}
mainaxis[1] = (mainaxis[0] + 1) % 3;
mainaxis[2] = (mainaxis[0] + 2) % 3;
if(!smd->domain->bind)
{
smd->domain->bind = MEM_callocN(sizeof(GLuint)*256, "Smoke_bind");
if(big)
smd->domain->viewsettings |= MOD_SMOKE_VIEW_CHANGETOBIG;
new = 3;
}
// check if view axis / mode has been changed
if(smd->domain->viewsettings)
{
if(big)
{
if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_BIG))
new = 2;
else if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_CHANGETOBIG))
new = 1;
smd->domain->viewsettings |= MOD_SMOKE_VIEW_CHANGETOBIG;
}
else
{
if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_SMALL))
new = 2;
else if(smd->domain->viewsettings & MOD_SMOKE_VIEW_CHANGETOBIG)
new = 1;
smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_CHANGETOBIG;
}
if(!new)
{
if((mainaxis[0] == 0) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_X))
new = 1;
else if((mainaxis[0] == 1) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_Y))
new = 1;
else if((mainaxis[0] == 2) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_Z))
new = 1;
// printf("check axis\n");
}
}
else
new = 3;
if(new > 1)
{
float light[3] = {0.0,0.0,0.0}; // TODO: take real LAMP coordinates - dg
Base *base_tmp = NULL;
for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
{
if(base_tmp->object->type == OB_LAMP)
{
Lamp *la = (Lamp *)base_tmp->object->data;
if(la->type == LA_LOCAL)
{
VECCOPY(light, base_tmp->object->obmat[3]);
have_lamp = 1;
break;
}
}
}
if(!big && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SMALL))
{
smoke_prepare_View(smd, light);
// printf("prepared View!\n");
}
else if(big && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_BIG))
{
smoke_prepare_bigView(smd, light);
// printf("prepared bigView!\n");
}
}
// printf("big: %d, new: %d\n", big, new);
// only create buffer if we need to create new textures
if(new)
buffer = MEM_mallocN(sizeof(float)*res[mainaxis[1]]*res[mainaxis[2]]*4, "SmokeDrawBuffer");
if(buffer || smd->domain->viewsettings)
{
int mod_texture = 0;
// printf("if(buffer || smd->domain->viewsettings)\n");
max_textures = (res[mainaxis[0]] > 256) ? 256 : res[mainaxis[0]];
if(!smd->domain->viewsettings) // new frame or new start
{
smd->domain->max_textures = max_textures;
glGenTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
new = 1;
// printf("glGenTextures\n");
}
else
{
if(new)
{
// printf("glDeleteTextures\n");
glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
smd->domain->max_textures = max_textures;
glGenTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
}
}
mod_texture = MAX3(1, smd->domain->visibility, (int)(res[mainaxis[0]] / smd->domain->max_textures ));
// align order of billboards to be front or backview (e.g. +x or -x axis)
if(signed_align < 0)
{
z = res[mainaxis[0]] - 1;
}
else
{
z = 0;
}
for (; signed_align > 0 ? (z < res[mainaxis[0]]) : (z >= 0); signed_align > 0 ? z++ : z--) // 2
{
float quad[4][3];
if(new)
{
for (y = 0; y < res[mainaxis[1]]; y++) // 1
{
for (x = 0; x < res[mainaxis[2]]; x++) // 0
{
size_t index;
size_t image_index;
float tray, tvox;
image_index = smoke_get_index2d(y, res[mainaxis[1]], x);
if(mainaxis[0] == 0)
{
// mainaxis[1] == 1, mainaxis[2] == 2
index = smoke_get_index(z, res[mainaxis[0]], y, res[mainaxis[1]], x);
}
else if(mainaxis[0] == 1)
{
// mainaxis[1] == 2, mainaxis[2] == 0
index = smoke_get_index(x, res[mainaxis[2]], z, res[mainaxis[0]], y);
}
else // mainaxis[0] == 2
{
// mainaxis[1] == 0, mainaxis[2] == 1
index = smoke_get_index(y, res[mainaxis[1]], x, res[mainaxis[2]], z);
}
if(!big)
{
tvox = smoke_get_tvox(smd, index);
tray = smoke_get_tray(smd, index);
}
else
{
tvox = smoke_get_bigtvox(smd, index);
tray = smoke_get_bigtray(smd, index);
}
if(!have_lamp)
tray = 1.0;
// fill buffer with luminance and alpha
// 1 - T_vox
buffer[image_index*4 + 3] = 1.0 - tvox; // 0 = transparent => d.h. tvox = 1
// L_vox = Omega * L_light * (1 - T_vox) * T_ray
buffer[image_index*4] = buffer[image_index*4 + 1] = buffer[image_index*4 + 2] = smd->domain->omega * 1.0 * tvox * tray;
}
}
}
glBindTexture(GL_TEXTURE_2D, smd->domain->bind[counter_textures]);
glEnable(GL_TEXTURE_2D);
if(new)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res[mainaxis[1]], res[mainaxis[2]], 0, GL_RGBA, GL_FLOAT, buffer);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
}
if((z % mod_texture) == 0 )
{
// botttom left
quad[3][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
quad[3][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + smd->domain->dx * bigfactor * 0.5;
quad[3][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + smd->domain->dx * bigfactor * 0.5;
// top right
quad[1][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
quad[1][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + (res[mainaxis[1]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
quad[1][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + (res[mainaxis[2]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
// top left
quad[2][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
quad[2][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + smd->domain->dx * bigfactor * 0.5;
quad[2][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + (res[mainaxis[2]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
// bottom right
quad[0][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
quad[0][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + (res[mainaxis[1]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
quad[0][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + smd->domain->dx * bigfactor * 0.5;
glBegin(GL_QUADS); // Start Drawing Quads
glTexCoord2f(1.0f, 0.0f);
glVertex3fv(quad[0]); // Left And Up 1 Unit (Top Left)
glTexCoord2f(1.0f, 1.0f);
glVertex3fv(quad[1]); // Right And Up 1 Unit (Top Right)
glTexCoord2f(0.0f, 1.0f);
glVertex3fv(quad[2]); // Right And Down One Unit (Bottom Right)
glTexCoord2f(0.0f, 0.0f);
glVertex3fv(quad[3]); // Left And Down One Unit (Bottom Left)
glEnd();
}
counter_textures++;
}
}
if(buffer)
{
MEM_freeN(buffer);
buffer = NULL;
}
// set correct flag for viewsettings
if(1)
{
// do not clear BIG/SMALL flag
smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_X;
smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_Y;
smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_Z;
// set what caches we have
if(big)
smd->domain->viewsettings |= MOD_SMOKE_VIEW_BIG;
else
smd->domain->viewsettings |= MOD_SMOKE_VIEW_SMALL;
if(mainaxis[0] == 0)
smd->domain->viewsettings |= MOD_SMOKE_VIEW_X;
else if(mainaxis[0] == 1)
smd->domain->viewsettings |= MOD_SMOKE_VIEW_Y;
else if(mainaxis[0] == 2)
smd->domain->viewsettings |= MOD_SMOKE_VIEW_Z;
}
wmMultMatrix(ob->obmat);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
if(col) cpack(col);
}
}

View File

@@ -0,0 +1,304 @@
/**
* $Id$
*
* ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* Contributor(s): Daniel Genrich
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "MEM_guardedalloc.h"
#include "IMB_imbuf.h"
#include "MTC_matrixops.h"
#include "DNA_armature_types.h"
#include "DNA_boid_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
#include "DNA_constraint_types.h" // for drawing constraint
#include "DNA_effect_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
#include "DNA_particle_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_smoke_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BLI_edgehash.h"
#include "BLI_rand.h"
#include "BKE_anim.h" //for the where_on_path function
#include "BKE_curve.h"
#include "BKE_constraint.h" // for the get_constraint_target function
#include "BKE_DerivedMesh.h"
#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_property.h"
#include "BKE_smoke.h"
#include "BKE_unit.h"
#include "BKE_utildefines.h"
#include "smoke_API.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
#include "ED_mesh.h"
#include "ED_particle.h"
#include "ED_screen.h"
#include "ED_types.h"
#include "ED_util.h"
#include "UI_resources.h"
#include "UI_interface_icons.h"
#include "WM_api.h"
#include "BLF_api.h"
#include "GPU_extensions.h"
#include "view3d_intern.h" // own include
struct GPUTexture;
/* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
static float cv[][3] = {
{1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
{1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
};
// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
static float edges[12][2][3] = {
{{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
{{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
{{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}
};
int intersect_edges(float *points, float a, float b, float c, float d)
{
int i;
float t;
int numpoints = 0;
for (i=0; i<12; i++) {
t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d)
/ (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]);
if ((t>0)&&(t<2)) {
points[numpoints * 3 + 0] = edges[i][0][0] + edges[i][1][0]*t;
points[numpoints * 3 + 1] = edges[i][0][1] + edges[i][1][1]*t;
points[numpoints * 3 + 2] = edges[i][0][2] + edges[i][1][2]*t;
numpoints++;
}
}
return numpoints;
}
static int convex(float *p0, float *up, float *a, float *b)
{
// Vec3 va = a-p0, vb = b-p0;
float va[3], vb[3], tmp[3];
VECSUB(va, a, p0);
VECSUB(vb, b, p0);
Crossf(tmp, va, vb);
return INPR(up, tmp) >= 0;
}
// copied from gpu_extension.c
static int is_pow2(int n)
{
return ((n)&(n-1))==0;
}
static int larger_pow2(int n)
{
if (is_pow2(n))
return n;
while(!is_pow2(n))
n= n&(n-1);
return n*2;
}
void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3])
{
Object *ob = base->object;
RegionView3D *rv3d= ar->regiondata;
float viewnormal[3];
// int res[3];
int i, j, n;
float d, d0, dd;
float *points = NULL;
int numpoints = 0;
float cor[3] = {1.,1.,1.};
/*
res[0] = smd->domain->res[0];
res[1] = smd->domain->res[1];
res[2] = smd->domain->res[2];
*/
wmLoadMatrix(rv3d->viewmat);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_3D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// get view vector
VECCOPY(viewnormal, rv3d->viewinv[2]);
Normalize(viewnormal);
// find cube vertex that is closest to the viewer
for (i=0; i<8; i++) {
float x,y,z;
x = cv[i][0] + viewnormal[0];
y = cv[i][1] + viewnormal[1];
z = cv[i][2] + viewnormal[2];
if ((x>=-1.0f)&&(x<=1.0f)
&&(y>=-1.0f)&&(y<=1.0f)
&&(z>=-1.0f)&&(z<=1.0f)) {
break;
}
}
GPU_texture_bind(tex, 0);
cor[0] = (float)res[0]/(float)larger_pow2(res[0]);
cor[1] = (float)res[1]/(float)larger_pow2(res[1]);
cor[2] = (float)res[2]/(float)larger_pow2(res[2]);
// our slices are defined by the plane equation a*x + b*y +c*z + d = 0
// (a,b,c), the plane normal, are given by viewdir
// d is the parameter along the view direction. the first d is given by
// inserting previously found vertex into the plane equation
d0 = -(viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]);
dd = 2.0*d0/64.0f;
n = 0;
// printf("d0: %f, dd: %f\n", d0, dd);
points = MEM_callocN(sizeof(float)*12*3, "smoke_points_preview");
for (d = d0; d > -d0; d -= dd) {
float p0[3];
// intersect_edges returns the intersection points of all cube edges with
// the given plane that lie within the cube
numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d);
if (numpoints > 2) {
VECCOPY(p0, points);
// sort points to get a convex polygon
for(i = 1; i < numpoints - 1; i++)
{
for(j = i + 1; j < numpoints; j++)
{
if(convex(p0, viewnormal, &points[j * 3], &points[i * 3]))
{
float tmp2[3];
VECCOPY(tmp2, &points[i * 3]);
VECCOPY(&points[i * 3], &points[j * 3]);
VECCOPY(&points[j * 3], tmp2);
}
}
}
glBegin(GL_POLYGON);
for (i = 0; i < numpoints; i++) {
glColor3f(1.0, 1.0, 1.0);
glTexCoord3d((points[i * 3 + 0] + 1.0)*cor[0]/2.0, (points[i * 3 + 1] + 1)*cor[1]/2.0, (points[i * 3 + 2] + 1.0)*cor[2]/2.0);
glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
}
glEnd();
}
n++;
}
GPU_texture_unbind(tex);
MEM_freeN(points);
wmMultMatrix(ob->obmat);
glDisable(GL_TEXTURE_3D);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
}

View File

@@ -156,6 +156,9 @@ void VIEW3D_OT_snap_menu(struct wmOperatorType *ot);
ARegion *view3d_has_buttons_region(ScrArea *sa);
ARegion *view3d_has_tools_region(ScrArea *sa);
/* draw_volume.c */
void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, int res[3]);
#endif /* ED_VIEW3D_INTERN_H */

View File

@@ -112,6 +112,10 @@ int GPU_verify_image(struct Image *ima, int tftile, int tfmode, int compare, int
void GPU_free_image(struct Image *ima);
void GPU_free_images(void);
/* smoke drawing functions */
void GPU_free_smoke(struct SmokeModifierData *smd);
void GPU_create_smoke(struct SmokeModifierData *smd);
#ifdef __cplusplus
}
#endif

View File

@@ -73,6 +73,7 @@ int GPU_print_error(char *str);
GPUTexture *GPU_texture_create_1D(int w, float *pixels);
GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels);
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels);
GPUTexture *GPU_texture_create_depth(int w, int h);
GPUTexture *GPU_texture_from_blender(struct Image *ima,
struct ImageUser *iuser, double time, int mipmap);

View File

@@ -38,9 +38,11 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
@@ -744,6 +746,23 @@ int GPU_update_image_time(Image *ima, double time)
return inc;
}
void GPU_free_smoke(SmokeModifierData *smd)
{
if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain)
{
if(smd->domain->tex)
GPU_texture_free(smd->domain->tex);
smd->domain->tex = NULL;
}
}
void GPU_create_smoke(SmokeModifierData *smd)
{
if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex)
smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->view3d);
}
void GPU_free_image(Image *ima)
{
/* free regular image binding */

View File

@@ -312,6 +312,78 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
return tex;
}
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
{
GPUTexture *tex;
GLenum type, format, internalformat;
void *pixels = NULL;
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
tex->w = w;
tex->h = h;
tex->depth = depth;
tex->number = -1;
tex->refcount = 1;
tex->target = GL_TEXTURE_3D;
glGenTextures(1, &tex->bindcode);
if (!tex->bindcode) {
fprintf(stderr, "GPUTexture: texture create failed: %d\n",
(int)glGetError());
GPU_texture_free(tex);
return NULL;
}
// if (!GLEW_ARB_texture_non_power_of_two)
{
tex->w = larger_pow2(tex->w);
tex->h = larger_pow2(tex->h);
tex->depth = larger_pow2(tex->depth);
}
tex->number = 0;
glBindTexture(tex->target, tex->bindcode);
type = GL_UNSIGNED_BYTE;
format = GL_RGBA;
internalformat = GL_RGBA8;
if (fpixels)
pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, 0);
if (fpixels) {
glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, pixels);
/*
if (tex->w > w)
GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
if (tex->h > h)
GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
*/
}
// glTexImage3D(tex->target, 0, GL_RGBA, w, h, depth, 0, GL_RGBA, GL_FLOAT, fpixels);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,GL_CLAMP_TO_BORDER);
if (pixels)
MEM_freeN(pixels);
if (tex)
GPU_texture_unbind(tex);
return tex;
}
GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time, int mipmap)
{
GPUTexture *tex;

View File

@@ -42,6 +42,7 @@ typedef enum ModifierType {
eModifierType_Multires,
eModifierType_Surface,
eModifierType_Smoke,
eModifierType_SmokeHR,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -252,9 +253,36 @@ typedef struct SmokeModifierData {
struct SmokeCollSettings *coll; /* collision objects */
float time;
int type; /* domain, inflow, outflow, ... */
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
} SmokeModifierData;
/* noise */
#define MOD_SMOKE_NOISEWAVE (1<<0)
#define MOD_SMOKE_NOISEFFT (1<<1)
#define MOD_SMOKE_NOISECURL (1<<2)
/* flags */
#define MOD_SMOKE_SHOWHIGHRES (1<<0) /* show high resolution */
typedef struct SmokeHRModifierData {
ModifierData modifier;
struct WTURBULENCE *wt; // WTURBULENCE object, if active
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
struct ListBase ptcaches;
struct GPUTexture *tex;
float *view3d; /* voxel data for display */
unsigned int v3dnum; /* number of frame in view3d buffer */
float time;
float strength;
int res[3];
int maxres;
short noise; /* noise type: wave, curl, anisotropic */
short pad;
int amplify;
int flags;
} SmokeHRModifierData;
typedef struct DisplaceModifierData {
ModifierData modifier;

View File

@@ -30,24 +30,12 @@
#define DNA_SMOKE_TYPES_H
/* flags */
#define MOD_SMOKE_HIGHRES (1<<1) /* compute high resolution */
#define MOD_SMOKE_HIGHRES (1<<1) /* enable high resolution */
#define MOD_SMOKE_DISSOLVE (1<<2) /* let smoke dissolve */
#define MOD_SMOKE_DISSOLVE_LOG (1<<3) /* using 1/x for dissolve */
/* noise */
#define MOD_SMOKE_NOISEWAVE (1<<0)
#define MOD_SMOKE_NOISEFFT (1<<1)
#define MOD_SMOKE_NOISECURL (1<<2)
/* viewsettings */
#define MOD_SMOKE_VIEW_X (1<<0)
#define MOD_SMOKE_VIEW_Y (1<<1)
#define MOD_SMOKE_VIEW_Z (1<<2)
#define MOD_SMOKE_VIEW_SMALL (1<<3)
#define MOD_SMOKE_VIEW_BIG (1<<4)
#define MOD_SMOKE_VIEW_CHANGETOBIG (1<<5)
#define MOD_SMOKE_VIEW_REDRAWNICE (1<<6)
#define MOD_SMOKE_VIEW_REDRAWALL (1<<7)
#define MOD_SMOKE_VIEW_USEBIG (1<<8)
/* nothing so far */
typedef struct SmokeDomainSettings {
struct SmokeModifierData *smd; /* for fast RNA access */
@@ -55,33 +43,27 @@ typedef struct SmokeDomainSettings {
struct Group *fluid_group;
struct Group *eff_group; // effector group for e.g. wind force
struct Group *coll_group; // collision objects group
unsigned int *bind;
float *tvox;
float *tray;
float *tvoxbig;
float *traybig;
struct GPUTexture *tex;
float *view3d; /* voxel data for display */
unsigned int v3dnum; /* number of frame in view3d buffer */
float p0[3]; /* start point of BB */
float p1[3]; /* end point of BB */
float dx; /* edge length of one cell */
float firstframe;
float lastframe;
float omega; /* smoke color - from 0 to 1 */
float temp; /* fluid temperature */
float tempAmb; /* ambient temperature */
float alpha;
float beta;
int res[3]; /* domain resolution */
int amplify; /* wavelet amplification */
int maxres; /* longest axis on the BB gets this resolution assigned */
int flags; /* show up-res or low res, etc */
int visibility; /* how many billboards to show (every 2nd, 3rd, 4th,..) */
int viewsettings;
int max_textures;
short noise; /* noise type: wave, curl, anisotropic */
short diss_percent;
short pad;
int diss_speed;/* in frames */
float strength;
struct WTURBULENCE *wt; // WTURBULENCE object, if active
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
struct ListBase ptcaches;
} SmokeDomainSettings;

View File

@@ -387,6 +387,7 @@ extern StructRNA RNA_SmokeCollSettings;
extern StructRNA RNA_SmokeDomainSettings;
extern StructRNA RNA_SmokeFlowSettings;
extern StructRNA RNA_SmokeModifier;
extern StructRNA RNA_SmokeHRModifier;
extern StructRNA RNA_SmoothModifier;
extern StructRNA RNA_SoftBodyModifier;
extern StructRNA RNA_SoftBodySettings;

View File

@@ -68,6 +68,7 @@ EnumPropertyItem modifier_type_items[] ={
{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
{eModifierType_Smoke, "SMOKE", 0, "Smoke", ""},
{eModifierType_SmokeHR, "SMOKE_HR", 0, "SmokeHR", ""},
{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
@@ -156,6 +157,8 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_SurfaceModifier;
case eModifierType_Smoke:
return &RNA_SmokeModifier;
case eModifierType_SmokeHR:
return &RNA_SmokeHRModifier;
default:
return &RNA_Modifier;
}
@@ -181,19 +184,30 @@ static void rna_Smoke_set_type(bContext *C, PointerRNA *ptr)
{
SmokeModifierData *smd= (SmokeModifierData *)ptr->data;
Object *ob= (Object*)ptr->id.data;
// nothing changed
if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
return;
smokeModifier_free(smd); // XXX TODO: completely free all 3 pointers
smokeModifier_createType(smd); // create regarding of selected type
// particle_system_slot_add_exec(C, NULL);
// particle_system_slot_remove_exec(C, NULL);
if(smd->type == MOD_SMOKE_TYPE_DOMAIN)
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
ob->dt = OB_WIRE;
// update dependancy since a domain - other type switch could have happened
rna_Modifier_dependency_update(C, ptr);
}
static void rna_SmokeHR_reset(bContext *C, PointerRNA *ptr)
{
// SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data;
// smokeModifier_reset(settings->smd);
// rna_Smoke_update(C, ptr);
}
static void rna_ExplodeModifier_vgroup_get(PointerRNA *ptr, char *value)
{
ExplodeModifierData *emd= (ExplodeModifierData*)ptr->data;
@@ -1499,6 +1513,55 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Point Cache", "");
}
static void rna_def_modifier_smoke_highresolution(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem prop_noise_type_items[] = {
{MOD_SMOKE_NOISEWAVE, "NOISEWAVE", 0, "Wavelet", ""},
#if FFTW3 == 1
{MOD_SMOKE_NOISEFFT, "NOISEFFT", 0, "FFT", ""},
#endif
/* {MOD_SMOKE_NOISECURL, "NOISECURL", 0, "Curl", ""}, */
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "SmokeHRModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Smoke High Resolution Modifier", "Smoke high resolution simulation modifier.");
RNA_def_struct_sdna(srna, "SmokeHRModifierData");
prop= RNA_def_property(srna, "show_highres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_SHOWHIGHRES);
RNA_def_property_ui_text(prop, "High res", "Show high resolution (using amplification).");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noise");
RNA_def_property_enum_items(prop, prop_noise_type_items);
RNA_def_property_ui_text(prop, "Noise Method", "Noise method which is used for creating the high resolution");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_SmokeHR_reset");
prop= RNA_def_property(srna, "amplify", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "amplify");
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_range(prop, 1, 10, 1, 0);
RNA_def_property_ui_text(prop, "Amplification", "Enhance the resolution of smoke by this factor using noise.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_SmokeHR_reset");
prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "strength");
RNA_def_property_range(prop, 1.0, 10.0);
RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2);
RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_SmokeHR_reset");
prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "point_cache");
RNA_def_property_struct_type(prop, "PointCache");
RNA_def_property_ui_text(prop, "Point Cache", "");
}
static void rna_def_modifier_smoke(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1915,6 +1978,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_multires(brna);
rna_def_modifier_surface(brna);
rna_def_modifier_smoke(brna);
rna_def_modifier_smoke_highresolution(brna);
}
#endif

View File

@@ -78,11 +78,28 @@ static void rna_Smoke_reset_dependancy(bContext *C, PointerRNA *ptr)
rna_Smoke_dependency_update(C, ptr);
}
static void rna_Smoke_enable_HR(bContext *C, PointerRNA *ptr)
{
SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data;
Object *ob = (Object*)ptr->id.data;
if(settings->flags & MOD_SMOKE_HIGHRES)
BLI_addtail(&ob->modifiers, modifier_new(eModifierType_SmokeHR));
else
{
ModifierData *tmd = modifiers_findByType(ob, eModifierType_SmokeHR);
if(tmd) {
BLI_remlink(&ob->modifiers, tmd);
modifier_free(tmd);
}
}
}
static void rna_Smoke_redraw(bContext *C, PointerRNA *ptr)
{
SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data;
settings->flags |= MOD_SMOKE_VIEW_REDRAWNICE;
// settings->flags |= MOD_SMOKE_VIEW_REDRAWNICE;
}
static char *rna_SmokeDomainSettings_path(PointerRNA *ptr)
@@ -116,14 +133,6 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem prop_noise_type_items[] = {
{MOD_SMOKE_NOISEWAVE, "NOISEWAVE", 0, "Wavelet", ""},
#if FFTW3 == 1
{MOD_SMOKE_NOISEFFT, "NOISEFFT", 0, "FFT", ""},
#endif
/* {MOD_SMOKE_NOISECURL, "NOISECURL", 0, "Curl", ""}, */
{0, NULL, 0, NULL, NULL}};
srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL);
RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings.");
RNA_def_struct_sdna(srna, "SmokeDomainSettings");
@@ -136,56 +145,19 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Max Res", "Maximal resolution used in the fluid domain.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "omega");
RNA_def_property_range(prop, 0.02, 1.0);
RNA_def_property_ui_range(prop, 0.02, 1.0, 0.02, 2);
RNA_def_property_ui_text(prop, "Color", "Smoke color (0 = black, 1 = white).");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Smoke_redraw");
prop= RNA_def_property(srna, "amplify", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "amplify");
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_range(prop, 1, 10, 1, 0);
RNA_def_property_ui_text(prop, "Amplification", "Enhance the resolution of smoke by this factor using noise.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
prop= RNA_def_property(srna, "highres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGHRES);
RNA_def_property_ui_text(prop, "High res", "Enable high resolution (using amplification).");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
prop= RNA_def_property(srna, "viewhighres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "viewsettings", MOD_SMOKE_VIEW_USEBIG);
RNA_def_property_ui_text(prop, "Show High Resolution", "Show high resolution (using amplification).");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_redraw");
prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noise");
RNA_def_property_enum_items(prop, prop_noise_type_items);
RNA_def_property_ui_text(prop, "Noise Method", "Noise method which is used for creating the high resolution");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
prop= RNA_def_property(srna, "visibility", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "visibility");
RNA_def_property_range(prop, 1, 15);
RNA_def_property_ui_range(prop, 1, 15, 1, 0);
RNA_def_property_ui_text(prop, "Display", "How much of the resolution should be shown during preview (every 2nd, 3rd, etc).");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Smoke_redraw");
prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "alpha");
RNA_def_property_range(prop, -5.0, 5.0);
RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5);
RNA_def_property_ui_text(prop, "Gravity", "Higher value results in sinking smoke");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
prop= RNA_def_property(srna, "beta", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "beta");
RNA_def_property_range(prop, -5.0, 5.0);
RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5);
RNA_def_property_ui_text(prop, "Heat", "Higher value results in faster rising smoke.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
prop= RNA_def_property(srna, "coll_group", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "coll_group");
@@ -208,13 +180,6 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this group.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset_dependancy");
prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "strength");
RNA_def_property_range(prop, 1.0, 10.0);
RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2);
RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
prop= RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "diss_speed");
RNA_def_property_range(prop, 1.0, 100.0);
@@ -222,6 +187,11 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
prop= RNA_def_property(srna, "highres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGHRES);
RNA_def_property_ui_text(prop, "High Resolution Smoke", "Enable high resolution smoke");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_enable_HR");
prop= RNA_def_property(srna, "dissolve_smoke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE);
RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time.");
@@ -231,6 +201,11 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG);
RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x ");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "point_cache");
RNA_def_property_struct_type(prop, "PointCache");
RNA_def_property_ui_text(prop, "Point Cache", "");
}
static void rna_def_smoke_flow_settings(BlenderRNA *brna)

View File

@@ -319,6 +319,8 @@ IF(UNIX)
bf_dummy
bf_bullet
bf_smoke
bf_minilzo
bf_lzma
bf_common
bf_ketsji
bf_logic