Point density: Add utility function to sample density outside of render pipeline
Not currently used, it's a preparation for the further work. Should not be functional changes.
This commit is contained in:
@@ -59,6 +59,12 @@ void RE_free_sample_material(struct Material *mat);
|
||||
void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3],
|
||||
int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob);
|
||||
|
||||
/* pointdensity.c */
|
||||
|
||||
struct PointDensity;
|
||||
|
||||
void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, int resolution, float *values);
|
||||
|
||||
void RE_init_texture_rng(void);
|
||||
void RE_exit_texture_rng(void);
|
||||
#endif /* __RE_RENDER_EXT_H__ */
|
||||
|
@@ -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,12 +59,15 @@
|
||||
#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 */
|
||||
extern struct Render R;
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static ThreadMutex sample_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int point_data_used(PointDensity *pd)
|
||||
{
|
||||
@@ -456,14 +460,16 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *
|
||||
}
|
||||
|
||||
|
||||
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 turb, noise_fac;
|
||||
int num = 0;
|
||||
|
||||
@@ -524,7 +530,26 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres)
|
||||
mul_v3_fl(vec, 1.0f / num);
|
||||
}
|
||||
|
||||
if (r_age != NULL) {
|
||||
*r_age = age;
|
||||
}
|
||||
if (r_vec != NULL) {
|
||||
copy_v3_v3(r_vec, vec);
|
||||
}
|
||||
|
||||
texres->tin = density;
|
||||
|
||||
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);
|
||||
float col[4];
|
||||
|
||||
BRICONT;
|
||||
|
||||
if (pd->color_source == TEX_PD_COLOR_CONSTANT)
|
||||
@@ -578,3 +603,106 @@ 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);
|
||||
|
||||
BLI_mutex_lock(&sample_mutex);
|
||||
cache_pointdensity_ex(scene, pd, mat, mat, 1, 1);
|
||||
BLI_mutex_unlock(&sample_mutex);
|
||||
|
||||
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);
|
||||
|
||||
copy_v3_v3(&values[index*4 + 0], &texres.tr);
|
||||
values[index*4 + 3] = texres.tin;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_pointdensity(pd);
|
||||
}
|
||||
|
@@ -628,6 +628,7 @@ void RE_engine_update_memory_stats(struct RenderEngine *engine, float mem_used,
|
||||
struct RenderEngine *RE_engine_create(struct RenderEngineType *type) RET_NULL
|
||||
void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe) RET_NONE
|
||||
void RE_FreePersistentData(void) RET_NONE
|
||||
void RE_sample_point_density(struct Scene *scene, struct PointDensity *pd, int resolution, float *values) RET_NONE;
|
||||
void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3]) RET_NONE
|
||||
|
||||
/* python */
|
||||
|
Reference in New Issue
Block a user