Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/smoke.c
| Show First 20 Lines • Show All 701 Lines • ▼ Show 20 Lines | typedef struct ObstaclesFromDMData { | ||||
| const MLoop *mloop; | const MLoop *mloop; | ||||
| const MLoopTri *looptri; | const MLoopTri *looptri; | ||||
| BVHTreeFromMesh *tree; | BVHTreeFromMesh *tree; | ||||
| unsigned char *obstacle_map; | unsigned char *obstacle_map; | ||||
| bool has_velocity; | bool has_velocity; | ||||
| float *vert_vel; | float *vert_vel; | ||||
| float *velocityX, *velocityY, *velocityZ; | float *velocityX, *velocityY, *velocityZ; | ||||
| int *num_obstacles; | |||||
| } ObstaclesFromDMData; | } ObstaclesFromDMData; | ||||
| static void obstacles_from_derivedmesh_task_cb(void *userdata, const int z) | static void obstacles_from_derivedmesh_task_cb(void *userdata, const int z) | ||||
| { | { | ||||
| ObstaclesFromDMData *data = userdata; | ObstaclesFromDMData *data = userdata; | ||||
| SmokeDomainSettings *sds = data->sds; | SmokeDomainSettings *sds = data->sds; | ||||
| /* slightly rounded-up sqrt(3 * (0.5)^2) == max. distance of cell boundary along the diagonal */ | /* slightly rounded-up sqrt(3 * (0.5)^2) == max. distance of cell boundary along the diagonal */ | ||||
| Show All 32 Lines | for (int y = sds->res_min[1]; y < sds->res_max[1]; y++) { | ||||
| data->velocityY[index] += hit_vel[1]; | data->velocityY[index] += hit_vel[1]; | ||||
| data->velocityZ[index] += hit_vel[2]; | data->velocityZ[index] += hit_vel[2]; | ||||
| } | } | ||||
| } | } | ||||
| /* tag obstacle cells */ | /* tag obstacle cells */ | ||||
| data->obstacle_map[index] = 1; | data->obstacle_map[index] = 1; | ||||
| if (data->has_velocity) | if (data->has_velocity) { | ||||
| data->obstacle_map[index] |= 8; | data->obstacle_map[index] |= 8; | ||||
| data->num_obstacles[index]++; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void obstacles_from_derivedmesh( | static void obstacles_from_derivedmesh( | ||||
| Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, | Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, | ||||
| unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, float dt) | unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, int *num_obstacles, float dt) | ||||
| { | { | ||||
| if (!scs->dm) return; | if (!scs->dm) return; | ||||
| { | { | ||||
| DerivedMesh *dm = NULL; | DerivedMesh *dm = NULL; | ||||
| MVert *mvert = NULL; | MVert *mvert = NULL; | ||||
| const MLoopTri *looptri; | const MLoopTri *looptri; | ||||
| const MLoop *mloop; | const MLoop *mloop; | ||||
| BVHTreeFromMesh treeData = {NULL}; | BVHTreeFromMesh treeData = {NULL}; | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | for (i = 0; i < numverts; i++) { | ||||
| copy_v3_v3(&scs->verts_old[i * 3], co); | copy_v3_v3(&scs->verts_old[i * 3], co); | ||||
| } | } | ||||
| if (bvhtree_from_mesh_looptri(&treeData, dm, 0.0f, 4, 6)) { | if (bvhtree_from_mesh_looptri(&treeData, dm, 0.0f, 4, 6)) { | ||||
| ObstaclesFromDMData data = { | ObstaclesFromDMData data = { | ||||
| .sds = sds, .mvert = mvert, .mloop = mloop, .looptri = looptri, | .sds = sds, .mvert = mvert, .mloop = mloop, .looptri = looptri, | ||||
| .tree = &treeData, .obstacle_map = obstacle_map, | .tree = &treeData, .obstacle_map = obstacle_map, | ||||
| .has_velocity = has_velocity, .vert_vel = vert_vel, | .has_velocity = has_velocity, .vert_vel = vert_vel, | ||||
| .velocityX = velocityX, .velocityY = velocityY, .velocityZ = velocityZ | .velocityX = velocityX, .velocityY = velocityY, .velocityZ = velocityZ, | ||||
| .num_obstacles = num_obstacles | |||||
| }; | }; | ||||
| BLI_task_parallel_range( | BLI_task_parallel_range( | ||||
| sds->res_min[2], sds->res_max[2], &data, obstacles_from_derivedmesh_task_cb, true); | sds->res_min[2], sds->res_max[2], &data, obstacles_from_derivedmesh_task_cb, true); | ||||
| } | } | ||||
| /* free bvh tree */ | /* free bvh tree */ | ||||
| free_bvhtree_from_mesh(&treeData); | free_bvhtree_from_mesh(&treeData); | ||||
| dm->release(dm); | dm->release(dm); | ||||
| Show All 19 Lines | static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, | ||||
| float *density = smoke_get_density(sds->fluid); | float *density = smoke_get_density(sds->fluid); | ||||
| float *fuel = smoke_get_fuel(sds->fluid); | float *fuel = smoke_get_fuel(sds->fluid); | ||||
| float *flame = smoke_get_flame(sds->fluid); | float *flame = smoke_get_flame(sds->fluid); | ||||
| float *r = smoke_get_color_r(sds->fluid); | float *r = smoke_get_color_r(sds->fluid); | ||||
| float *g = smoke_get_color_g(sds->fluid); | float *g = smoke_get_color_g(sds->fluid); | ||||
| float *b = smoke_get_color_b(sds->fluid); | float *b = smoke_get_color_b(sds->fluid); | ||||
| unsigned int z; | unsigned int z; | ||||
| int *num_obstacles = MEM_callocN(sizeof(int) * sds->res[0] * sds->res[1] * sds->res[2], "smoke_num_obstacles"); | |||||
| smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); | smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); | ||||
| // TODO: delete old obstacle flags | // TODO: delete old obstacle flags | ||||
| for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) | for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) | ||||
| { | { | ||||
| if (obstacles[z] & 8) // Do not delete static obstacles | if (obstacles[z] & 8) // Do not delete static obstacles | ||||
| { | { | ||||
| obstacles[z] = 0; | obstacles[z] = 0; | ||||
| Show All 13 Lines | for (collIndex = 0; collIndex < numcollobj; collIndex++) | ||||
| Object *collob = collobjs[collIndex]; | Object *collob = collobjs[collIndex]; | ||||
| SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); | SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); | ||||
| // DG TODO: check if modifier is active? | // DG TODO: check if modifier is active? | ||||
| if ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) | if ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) | ||||
| { | { | ||||
| SmokeCollSettings *scs = smd2->coll; | SmokeCollSettings *scs = smd2->coll; | ||||
| obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt); | obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, num_obstacles, dt); | ||||
| } | } | ||||
| } | } | ||||
| if (collobjs) | if (collobjs) | ||||
| MEM_freeN(collobjs); | MEM_freeN(collobjs); | ||||
| /* obstacle cells should not contain any velocity from the smoke simulation */ | /* obstacle cells should not contain any velocity from the smoke simulation */ | ||||
| for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) | for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) | ||||
| Show All 9 Lines | if (obstacles[z]) | ||||
| flame[z] = 0; | flame[z] = 0; | ||||
| } | } | ||||
| if (r) { | if (r) { | ||||
| r[z] = 0; | r[z] = 0; | ||||
| g[z] = 0; | g[z] = 0; | ||||
| b[z] = 0; | b[z] = 0; | ||||
| } | } | ||||
| } | } | ||||
| /* average velocities from multiple obstacles in one cell */ | |||||
| if (num_obstacles[z]) { | |||||
| velx[z] /= num_obstacles[z]; | |||||
| vely[z] /= num_obstacles[z]; | |||||
| velz[z] /= num_obstacles[z]; | |||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(num_obstacles); | |||||
| } | |||||
| /********************************************************** | /********************************************************** | ||||
| * Flow emission code | * Flow emission code | ||||
| **********************************************************/ | **********************************************************/ | ||||
| typedef struct EmissionMap { | typedef struct EmissionMap { | ||||
| float *influence; | float *influence; | ||||
| float *influence_high; | float *influence_high; | ||||
| float *velocity; | float *velocity; | ||||
| ▲ Show 20 Lines • Show All 2,109 Lines • Show Last 20 Lines | |||||