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!
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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}
|
||||
)
|
||||
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, ×cale);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
137
source/blender/blenkernel/intern/smokehighres.c
Normal file
137
source/blender/blenkernel/intern/smokehighres.c
Normal 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);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
304
source/blender/editors/space_view3d/drawvolume.c
Normal file
304
source/blender/editors/space_view3d/drawvolume.c
Normal 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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -319,6 +319,8 @@ IF(UNIX)
|
||||
bf_dummy
|
||||
bf_bullet
|
||||
bf_smoke
|
||||
bf_minilzo
|
||||
bf_lzma
|
||||
bf_common
|
||||
bf_ketsji
|
||||
bf_logic
|
||||
|
||||
Reference in New Issue
Block a user