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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/source/pipeline.c11
-rw-r--r--source/blender/render/intern/source/pointdensity.c207
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);
+}