diff options
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 11 | ||||
-rw-r--r-- | source/blender/render/intern/source/pointdensity.c | 207 |
2 files changed, 195 insertions, 23 deletions
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 31efdb95ac1..4fa942eac99 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2812,6 +2812,8 @@ static bool check_valid_camera_multiview(Scene *scene, Object *camera, ReportLis static int check_valid_camera(Scene *scene, Object *camera_override, ReportList *reports) { + const char *err_msg = "No camera found in scene \"%s\""; + if (camera_override == NULL && scene->camera == NULL) scene->camera = BKE_scene_camera_find(scene); @@ -2823,14 +2825,17 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList Sequence *seq = scene->ed->seqbase.first; while (seq) { - if (seq->type == SEQ_TYPE_SCENE && seq->scene) { + if ((seq->type == SEQ_TYPE_SCENE) && + ((seq->flag & SEQ_SCENE_STRIPS) == 0) && + (seq->scene != NULL)) + { if (!seq->scene_camera) { if (!seq->scene->camera && !BKE_scene_camera_find(seq->scene)) { /* camera could be unneeded due to composite nodes */ Object *override = (seq->scene == scene) ? camera_override : NULL; if (!check_valid_compositing_camera(seq->scene, override)) { - BKE_reportf(reports, RPT_ERROR, "No camera found in scene \"%s\"", seq->scene->id.name+2); + BKE_reportf(reports, RPT_ERROR, err_msg, seq->scene->id.name + 2); return false; } } @@ -2844,7 +2849,7 @@ static int check_valid_camera(Scene *scene, Object *camera_override, ReportList } } else if (!check_valid_compositing_camera(scene, camera_override)) { - BKE_report(reports, RPT_ERROR, "No camera found in scene"); + BKE_reportf(reports, RPT_ERROR, err_msg, scene->id.name + 2); return false; } diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 3a1f1fbb744..5cd8a739125 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -45,6 +45,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_lattice.h" #include "BKE_main.h" +#include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" #include "BKE_texture.h" @@ -58,6 +59,8 @@ #include "texture.h" #include "pointdensity.h" +#include "RE_render_ext.h" + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ /* only to be used here in this file, it's for speed */ @@ -83,6 +86,10 @@ static int point_data_used(PointDensity *pd) { pd_bitflag |= POINT_DATA_LIFE; } + if ((pd->color_source == TEX_PD_COLOR_PARTTEX)) + { + pd_bitflag |= POINT_DATA_COLOR; + } } return pd_bitflag; @@ -104,6 +111,10 @@ static void alloc_point_data(PointDensity *pd, int total_particles, int point_da /* store 1 channel of lifetime data */ data_size += 1; } + if (point_data_used & POINT_DATA_COLOR) { + /* store 3 channels of color data */ + data_size += 3; + } if (data_size) { pd->point_data = MEM_mallocN(sizeof(float) * data_size * total_particles, @@ -111,6 +122,19 @@ static void alloc_point_data(PointDensity *pd, int total_particles, int point_da } } +/* offset of age and color data in the common point data array */ +static void point_data_get_offset(int total_particles, int point_data_used, int *offset_life, int *offset_color) +{ + *offset_life = *offset_color = 0; + if (point_data_used & POINT_DATA_VEL) { + *offset_life += total_particles * 3; + *offset_color += total_particles * 3; + } + if (point_data_used & POINT_DATA_LIFE) { + *offset_color += total_particles; + } +} + static void pointdensity_cache_psys(Scene *scene, PointDensity *pd, Object *ob, @@ -126,7 +150,7 @@ static void pointdensity_cache_psys(Scene *scene, ParticleData *pa = NULL; float cfra = BKE_scene_frame_get(scene); int i /*, childexists*/ /* UNUSED */; - int total_particles, offset = 0; + int total_particles, offset_life = 0, offset_color = 0; int data_used = point_data_used(pd); float partco[3]; @@ -148,6 +172,7 @@ static void pointdensity_cache_psys(Scene *scene, sim.scene = scene; sim.ob = ob; sim.psys = psys; + sim.psmd = psys_get_modifier(ob, psys); /* in case ob->imat isn't up-to-date */ invert_m4_m4(ob->imat, ob->obmat); @@ -158,9 +183,7 @@ static void pointdensity_cache_psys(Scene *scene, pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6); alloc_point_data(pd, total_particles, data_used); pd->totpoints = total_particles; - if (data_used & POINT_DATA_VEL) { - offset = pd->totpoints * 3; - } + point_data_get_offset(total_particles, data_used, &offset_life, &offset_color); #if 0 /* UNUSED */ if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) @@ -223,7 +246,12 @@ static void pointdensity_cache_psys(Scene *scene, pd->point_data[i * 3 + 2] = state.vel[2]; } if (data_used & POINT_DATA_LIFE) { - pd->point_data[offset + i] = state.time; + pd->point_data[offset_life + i] = state.time; + } + if (data_used & POINT_DATA_COLOR) { + ParticleTexture ptex; + psys_get_texture(&sim, pa, &ptex, PAMAP_COLOR, cfra); + copy_v3_v3(&pd->point_data[offset_color + i * 3], ptex.color); } } @@ -385,8 +413,9 @@ typedef struct PointDensityRangeData { short falloff_type; short noise_influence; float *age; + float *col; int point_data_used; - int offset; + int offset_life, offset_color; struct CurveMapping *density_curve; float velscale; } PointDensityRangeData; @@ -403,7 +432,10 @@ static void accum_density(void *userdata, int index, float squared_dist) pdr->vec[2] += pdr->point_data[index * 3 + 2]; // * density; } if (pdr->point_data_used & POINT_DATA_LIFE) { - *pdr->age += pdr->point_data[pdr->offset + index]; // * density; + *pdr->age += pdr->point_data[pdr->offset_life + index]; // * density; + } + if (pdr->point_data_used & POINT_DATA_COLOR) { + add_v3_v3(pdr->col, &pdr->point_data[pdr->offset_color + index]); // * density; } if (pdr->falloff_type == TEX_PD_FALLOFF_STD) @@ -418,7 +450,7 @@ static void accum_density(void *userdata, int index, float squared_dist) density = sqrtf(dist); else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE) { if (pdr->point_data_used & POINT_DATA_LIFE) - density = dist * MIN2(pdr->point_data[pdr->offset + index], 1.0f); + density = dist * MIN2(pdr->point_data[pdr->offset_life + index], 1.0f); else density = dist; } @@ -439,7 +471,7 @@ static void accum_density(void *userdata, int index, float squared_dist) static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr, - float *density, float *vec, float *age, struct CurveMapping *density_curve, float velscale) + float *density, float *vec, float *age, float *col, struct CurveMapping *density_curve, float velscale) { pdr->squared_radius = pd->radius * pd->radius; pdr->density = density; @@ -447,23 +479,26 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData * pdr->falloff_type = pd->falloff_type; pdr->vec = vec; pdr->age = age; + pdr->col = col; pdr->softness = pd->falloff_softness; pdr->noise_influence = pd->noise_influence; pdr->point_data_used = point_data_used(pd); - pdr->offset = (pdr->point_data_used & POINT_DATA_VEL) ? pd->totpoints * 3 : 0; + point_data_get_offset(pd->totpoints, pdr->point_data_used, &pdr->offset_life, &pdr->offset_color); pdr->density_curve = density_curve; pdr->velscale = velscale; } -int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) +static int pointdensity(PointDensity *pd, + const float texvec[3], + TexResult *texres, + float *r_age, + float r_vec[3]) { int retval = TEX_INT; - PointDensity *pd = tex->pd; PointDensityRangeData pdr; float density = 0.0f, age = 0.0f, time = 0.0f; - float vec[3] = {0.0f, 0.0f, 0.0f}, co[3]; - float col[4]; + float vec[3] = {0.0f, 0.0f, 0.0f}, color[3] = {0.0f, 0.0f, 0.0f}, co[3]; float turb, noise_fac; int num = 0; @@ -472,7 +507,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) if ((!pd) || (!pd->point_tree)) return 0; - init_pointdensityrangedata(pd, &pdr, &density, vec, &age, + init_pointdensityrangedata(pd, &pdr, &density, vec, &age, color, (pd->flag & TEX_PD_FALLOFF_CURVE ? pd->falloff_curve : NULL), pd->falloff_speed_scale * 0.001f); noise_fac = pd->noise_fac * 0.5f; /* better default */ @@ -525,11 +560,24 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) } texres->tin = density; - BRICONT; + texres->tr = color[0]; + texres->tg = color[1]; + texres->tb = color[2]; + if (r_age != NULL) { + *r_age = age; + } + if (r_vec != NULL) { + copy_v3_v3(r_vec, vec); + } - if (pd->color_source == TEX_PD_COLOR_CONSTANT) - return retval; + return retval; +} +static int pointdensity_color(PointDensity *pd, TexResult *texres, float age, const float vec[3]) +{ + int retval = 0; + float col[4]; + retval |= TEX_RGB; switch (pd->color_source) { @@ -559,8 +607,12 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) } case TEX_PD_COLOR_PARTVEL: texres->talpha = true; - mul_v3_fl(vec, pd->speed_scale); - copy_v3_v3(&texres->tr, vec); + mul_v3_v3fl(&texres->tr, vec, pd->speed_scale); + texres->ta = texres->tin; + break; + case TEX_PD_COLOR_PARTTEX: + /* texres already has the particle color */ + texres->talpha = true; texres->ta = texres->tin; break; case TEX_PD_COLOR_CONSTANT: @@ -568,6 +620,20 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) texres->tr = texres->tg = texres->tb = texres->ta = 1.0f; break; } + + return retval; +} + +int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) +{ + PointDensity *pd = tex->pd; + float age = 0.0f; + float vec[3] = {0.0f, 0.0f, 0.0f}; + int retval = pointdensity(pd, texvec, texres, &age, vec); + + BRICONT; + + retval |= pointdensity_color(pd, texres, age, vec); BRICONTRGB; return retval; @@ -578,3 +644,104 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) } #endif } + +static void sample_dummy_point_density(int resolution, float *values) +{ + memset(values, 0, sizeof(float) * 4 * resolution * resolution * resolution); +} + +static void particle_system_minmax(Object *object, + ParticleSystem *psys, + float radius, + float min[3], float max[3]) +{ + ParticleSettings *part = psys->part; + float imat[4][4]; + float size[3] = {radius, radius, radius}; + PARTICLE_P; + INIT_MINMAX(min, max); + if (part->type == PART_HAIR) { + /* TOOD(sergey): Not supported currently. */ + return; + } + invert_m4_m4(imat, object->obmat); + LOOP_PARTICLES { + float co_object[3], co_min[3], co_max[3]; + mul_v3_m4v3(co_object, imat, pa->state.co); + sub_v3_v3v3(co_min, co_object, size); + add_v3_v3v3(co_max, co_object, size); + minmax_v3v3_v3(min, max, co_min); + minmax_v3v3_v3(min, max, co_max); + } +} + +void RE_sample_point_density(Scene *scene, PointDensity *pd, + int resolution, float *values) +{ + const size_t resolution2 = resolution * resolution; + Object *object = pd->object; + size_t x, y, z; + float min[3], max[3], dim[3], mat[4][4]; + + if (object == NULL) { + sample_dummy_point_density(resolution, values); + return; + } + + if (pd->source == TEX_PD_PSYS) { + ParticleSystem *psys; + if (pd->psys == 0) { + sample_dummy_point_density(resolution, values); + return; + } + psys = BLI_findlink(&object->particlesystem, pd->psys - 1); + if (psys == NULL) { + sample_dummy_point_density(resolution, values); + return; + } + particle_system_minmax(object, psys, pd->radius, min, max); + } + else { + float radius[3] = {pd->radius, pd->radius, pd->radius}; + float *loc, *size; + BKE_object_obdata_texspace_get(pd->object, NULL, &loc, &size, NULL); + sub_v3_v3v3(min, loc, size); + add_v3_v3v3(max, loc, size); + /* Adjust texture space to include density points on the boundaries. */ + sub_v3_v3(min, radius); + add_v3_v3(max, radius); + } + + sub_v3_v3v3(dim, max, min); + if (dim[0] <= 0.0f || dim[1] <= 0.0f || dim[2] <= 0.0f) { + sample_dummy_point_density(resolution, values); + return; + } + + /* Same matricies/resolution as dupli_render_particle_set(). */ + unit_m4(mat); + cache_pointdensity_ex(scene, pd, mat, mat, 1, 1); + + for (z = 0; z < resolution; ++z) { + for (y = 0; y < resolution; ++y) { + for (x = 0; x < resolution; ++x) { + size_t index = z * resolution2 + y * resolution + x; + float texvec[3]; + float age, vec[3]; + TexResult texres; + + copy_v3_v3(texvec, min); + texvec[0] += dim[0] * (float)x / (float)resolution; + texvec[1] += dim[1] * (float)y / (float)resolution; + texvec[2] += dim[2] * (float)z / (float)resolution; + + pointdensity(pd, texvec, &texres, &age, vec); + pointdensity_color(pd, &texres, age, vec); + + copy_v3_v3(&values[index*4 + 0], &texres.tr); + values[index*4 + 3] = texres.tin; + } + } + } + free_pointdensity(pd); +} |