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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Genrich <daniel.genrich@gmx.net>2009-08-20 04:33:59 +0400
committerDaniel Genrich <daniel.genrich@gmx.net>2009-08-20 04:33:59 +0400
commit286c2ca80be4ae46dc220ada2fcc5bf636d5ff49 (patch)
tree91492852f1b0f8d6bc70d8b88113325e218e7f9d /source/blender/blenkernel
parentc21627e31b0e82f28e35af51cec681897285ff78 (diff)
Smoke:
* 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!
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h6
-rw-r--r--source/blender/blenkernel/BKE_smoke.h17
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/SConscript2
-rw-r--r--source/blender/blenkernel/intern/modifier.c79
-rw-r--r--source/blender/blenkernel/intern/pointcache.c271
-rw-r--r--source/blender/blenkernel/intern/smoke.c1063
-rw-r--r--source/blender/blenkernel/intern/smokehighres.c137
8 files changed, 907 insertions, 670 deletions
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 5d9dddfe30d..531487549da 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -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);
diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h
index 8dc38640e9a..bd8581112f8 100644
--- a/source/blender/blenkernel/BKE_smoke.h
+++ b/source/blender/blenkernel/BKE_smoke.h
@@ -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);
-
-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);
+// 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);
-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_ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 8d1df98c5b4..17079205423 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -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}
)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index fdc7782a0b1..0c7922de6ff 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -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']
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 53d1baa5c9c..1e2560bf809 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 09170d92866..ca27bde039b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -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);
-
- 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));
+ smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
+
+ 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));
+ }
+}
+
+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, int num)
+
+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;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 22ea41276ff..6449ae10eee 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -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->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;
+ if(smd->domain->view3d)
+ MEM_freeN(smd->domain->view3d);
+ smd->domain->view3d = 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;
+ // we got back in time, reset smoke in this case (TODO: use cache later)
+ // smd->time = scene->r.cfra;
+ // smokeModifier_reset(smd);
- // do flows and fluids
- if(1)
- {
- Object *otherobj = NULL;
- ModifierData *md = NULL;
+ return;
+ }
+ else if(framenr > endframe)
+ {
+ framenr = endframe;
+ }
- if(sds->fluid_group) // we use groups since we have 2 domains
- go = sds->fluid_group->gobject.first;
- else
- base = scene->base.first;
+ if(!(cache->flag & PTCACHE_SIMULATION_VALID))
+ {
+ // printf("reseting\n");
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ }
+
+ smokeModifier_init(smd, ob, scene, dm);
- while(base || go)
- {
- otherobj = NULL;
+ /* 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;
- if(sds->fluid_group)
+ 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)
{
- if(go->ob)
- otherobj = go->ob;
+ VECCOPY(light, base_tmp->object->obmat[3]);
+ have_lamp = 1;
+ break;
}
- else
- otherobj = base->object;
+ }
+ }
+ }
- if(!otherobj)
- {
- if(sds->fluid_group)
- go = go->next;
- else
- base= base->next;
+ smoke_prepare_View(smd, (float)framenr, light, have_lamp);
- continue;
- }
+ BKE_ptcache_write_cache(&pid, framenr);
+
+ printf("Writing cache_low\n");
+
- md = modifiers_findByType(otherobj, eModifierType_Smoke);
+ 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;
- // check for active smoke modifier
- if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+ if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
{
- SmokeModifierData *smd2 = (SmokeModifierData *)md;
+ 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");
- // check for initialized smoke object
- if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+ // mostly copied from particle code
+ for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
{
- // we got nice flow object
- SmokeFlowSettings *sfs = smd2->flow;
+ int cell[3];
+ size_t i = 0;
+ size_t index = 0;
+ int badcell = 0;
- if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
+ 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++)
{
- 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++)
+ if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
{
- 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;
- }
- }
- }
+ badcell = 1;
+ break;
}
}
- else
+
+ 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
{
- /*
- for()
- {
- // no psys
- BVHTreeNearest nearest;
+ // heat[index] += sfs->temp * 0.1;
+ // density[index] += sfs->density * 0.1;
- nearest.index = -1;
- nearest.dist = FLT_MAX;
+ heat[index] = sfs->temp;
+ density[index] = sfs->density;
- BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
- }*/
+ /*
+ 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;
}
- }
+ }
}
-
- if(sds->fluid_group)
- go = go->next;
else
- base= base->next;
- }
+ {
+ /*
+ 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);
+ }*/
+ }
+ }
}
- // do effectors
- /*
- if(sds->eff_group)
+ 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)
{
- for(go = sds->eff_group->gobject.first; go; go = go->next)
+ if(ob->pd)
{
- 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;
- // do collisions
- if(1)
+ if(sds->coll_group)
{
- Object *otherobj = NULL;
- ModifierData *md = NULL;
+ if(go->ob)
+ otherobj = go->ob;
+ }
+ else
+ otherobj = base->object;
- if(sds->coll_group) // we use groups since we have 2 domains
- go = sds->coll_group->gobject.first;
+ if(!otherobj)
+ {
+ if(sds->coll_group)
+ go = go->next;
else
- base = scene->base.first;
+ base= base->next;
- while(base || go)
- {
- otherobj = NULL;
+ 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(sds->coll_group)
- {
- if(go->ob)
- otherobj = go->ob;
- }
- else
- otherobj = base->object;
+ 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);
- if(!otherobj)
+ for(i = 0; i < scs->numpoints; i++)
{
- if(sds->coll_group)
- go = go->next;
- else
- base= base->next;
+ int badcell = 0;
+ size_t index = 0;
+ int cell[3];
- continue;
- }
-
- md = modifiers_findByType(otherobj, eModifierType_Smoke);
+ // 1. get corresponding cell
+ get_cell(sds->p0, sds->res, sds->dx, &scs->points[3 * i], cell, 0);
- // 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++)
+ // 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))
{
- 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]);
+ badcell = 1;
+ break;
+ }
- // 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;
+ if(badcell)
+ continue;
- // 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;
- */
- }
- }
+ // 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);
+ 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;
-
- 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);
-}
-
-// 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];
+ for(y = 0; y < smd->domain->res[1]; y++)
+ for(z = 0; z < smd->domain->res[2]; z++)
+ {
+ size_t index;
- smoke_turbulence_get_res(smd->domain->wt, bigres);
+ 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];
+
+ }
- 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");
- }
- if(!smd->domain->tvoxbig)
- {
- // TVox is for tranaparency
- smd->domain->tvoxbig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tVoxBig");
- }
+ smoke_calc_transparency(sds->view3d, sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp);
- 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)) );
+ 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];
+ }
}
- 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)
-{
- 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)
+static void get_cell(float *p0, int res[3], float dx, 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]);
-
- 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);
- }
+ bv[4] = p0[2];
+ bv[5] = p1[2];
-#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;
}
}
diff --git a/source/blender/blenkernel/intern/smokehighres.c b/source/blender/blenkernel/intern/smokehighres.c
new file mode 100644
index 00000000000..6a2e0549158
--- /dev/null
+++ b/source/blender/blenkernel/intern/smokehighres.c
@@ -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);
+ */
+}
+
+