Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2020-12-24 16:30:33 +01:00
commit c203de25db
16 changed files with 784 additions and 624 deletions

View File

@ -72,6 +72,9 @@ protected:
/// The channel mapper reader in between.
std::shared_ptr<ChannelMapperReader> m_mapper;
/// Whether the source is being read for the first time.
bool m_first_reading;
/// Whether to keep the source if end of it is reached.
bool m_keep;

View File

@ -78,7 +78,7 @@ bool SoftwareDevice::SoftwareHandle::pause(bool keep)
}
SoftwareDevice::SoftwareHandle::SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep) :
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_first_reading(true), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
m_flags(RENDER_CONE), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING), m_device(device)
@ -106,6 +106,14 @@ void SoftwareDevice::SoftwareHandle::update()
if(m_pitch->getSpecs().channels != CHANNELS_MONO)
{
m_volume = m_user_volume;
// we don't know a previous volume if this source has never been read before
if(m_first_reading)
{
m_old_volume = m_volume;
m_first_reading = false;
}
m_pitch->setPitch(m_user_pitch);
return;
}
@ -214,6 +222,13 @@ void SoftwareDevice::SoftwareHandle::update()
m_volume *= m_user_volume;
}
// we don't know a previous volume if this source has never been read before
if(m_first_reading)
{
m_old_volume = m_volume;
m_first_reading = false;
}
// 3D Cue
Quaternion orientation;
@ -754,6 +769,8 @@ void SoftwareDevice::mix(data_t* buffer, int length)
{
m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
sound->m_old_volume = sound->m_volume;
pos += len;
if(sound->m_loopcount > 0)

View File

@ -22,6 +22,7 @@
#include <mutex>
#define KEEP_TIME 10
#define POSITION_EPSILON (1.0 / static_cast<double>(RATE_48000))
AUD_NAMESPACE_BEGIN
@ -64,7 +65,7 @@ bool SequenceHandle::updatePosition(double position)
if(m_handle.get())
{
// we currently have a handle, let's check where we are
if(position >= m_entry->m_end)
if(position - POSITION_EPSILON >= m_entry->m_end)
{
if(position >= m_entry->m_end + KEEP_TIME)
// far end, stopping
@ -76,7 +77,7 @@ bool SequenceHandle::updatePosition(double position)
return true;
}
}
else if(position >= m_entry->m_begin)
else if(position + POSITION_EPSILON >= m_entry->m_begin)
{
// inside, resuming
m_handle->resume();
@ -98,7 +99,7 @@ bool SequenceHandle::updatePosition(double position)
else
{
// we don't have a handle, let's start if we should be playing
if(position >= m_entry->m_begin && position <= m_entry->m_end)
if(position + POSITION_EPSILON >= m_entry->m_begin && position - POSITION_EPSILON <= m_entry->m_end)
{
start();
return m_valid;

View File

@ -1969,9 +1969,11 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
if rd.bake_type == 'DISPLACEMENT':
layout.prop(rd, "use_bake_lores_mesh")
else:
layout.prop(cbk, "target")
layout.prop(cbk, "margin")
layout.prop(cbk, "use_clear", text="Clear Image")
if cbk.target == 'IMAGE_TEXTURES':
layout.prop(cbk, "margin")
layout.prop(cbk, "use_clear", text="Clear Image")
class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):

View File

@ -1248,6 +1248,12 @@ class OptiXDevice : public CUDADevice {
void build_bvh(BVH *bvh, Progress &progress, bool refit) override
{
if (bvh->params.bvh_layout == BVH_LAYOUT_BVH2) {
/* For baking CUDA is used, build appropriate BVH for that. */
Device::build_bvh(bvh, progress, refit);
return;
}
BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh);
progress.set_substatus("Building OptiX acceleration structure");

View File

@ -214,13 +214,6 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd
#endif
}
/* Total surface area of object */
ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
{
return kernel_tex_fetch(__objects, object).surface_area;
}
/* Color of the object */
ccl_device_inline float3 object_color(KernelGlobals *kg, int object)
@ -328,7 +321,7 @@ ccl_device_inline float object_volume_density(KernelGlobals *kg, int object)
return 1.0f;
}
return kernel_tex_fetch(__objects, object).surface_area;
return kernel_tex_fetch(__objects, object).volume_density;
}
ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)

View File

@ -1461,7 +1461,7 @@ typedef struct KernelObject {
Transform tfm;
Transform itfm;
float surface_area;
float volume_density;
float pass_id;
float random_number;
float color[3];

View File

@ -109,7 +109,7 @@ static void shaderdata_to_shaderglobals(
globals->dvdy = sd->dv.dy;
globals->dPdu = TO_VEC3(sd->dPdu);
globals->dPdv = TO_VEC3(sd->dPdv);
globals->surfacearea = (sd->object == OBJECT_NONE) ? 1.0f : object_surface_area(kg, sd->object);
globals->surfacearea = 1.0f;
globals->time = sd->time;
/* booleans */

View File

@ -55,12 +55,6 @@ struct UpdateObjectTransformState {
*/
map<ParticleSystem *, int> particle_offset;
/* Mesh area.
* Used to avoid calculation of mesh area multiple times. Used for both
* read and write. Acquire surface_area_lock to keep it all thread safe.
*/
map<Mesh *, float> surface_area_map;
/* Motion offsets for each object. */
array<uint> motion_offset;
@ -76,12 +70,8 @@ struct UpdateObjectTransformState {
bool have_curves;
/* ** Scheduling queue. ** */
Scene *scene;
/* Some locks to keep everything thread-safe. */
thread_spin_lock surface_area_lock;
/* First unused object index in the queue. */
int queue_start_object;
};
@ -379,80 +369,17 @@ ObjectManager::~ObjectManager()
{
}
static float object_surface_area(UpdateObjectTransformState *state,
const Transform &tfm,
Geometry *geom)
static float object_volume_density(const Transform &tfm, Geometry *geom)
{
if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) {
return 0.0f;
}
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->has_volume || geom->geometry_type == Geometry::VOLUME) {
if (geom->geometry_type == Geometry::VOLUME) {
/* Volume density automatically adjust to object scale. */
if (geom->geometry_type == Geometry::VOLUME &&
static_cast<Volume *>(geom)->get_object_space()) {
if (static_cast<Volume *>(geom)->get_object_space()) {
const float3 unit = normalize(make_float3(1.0f, 1.0f, 1.0f));
return 1.0f / len(transform_direction(&tfm, unit));
}
else {
return 1.0f;
}
}
/* Compute surface area. for uniform scale we can do avoid the many
* transform calls and share computation for instances.
*
* TODO(brecht): Correct for displacement, and move to a better place.
*/
float surface_area = 0.0f;
float uniform_scale;
if (transform_uniform_scale(tfm, uniform_scale)) {
map<Mesh *, float>::iterator it;
/* NOTE: This isn't fully optimal and could in theory lead to multiple
* threads calculating area of the same mesh in parallel. However, this
* also prevents suspending all the threads when some mesh's area is
* not yet known.
*/
state->surface_area_lock.lock();
it = state->surface_area_map.find(mesh);
state->surface_area_lock.unlock();
if (it == state->surface_area_map.end()) {
size_t num_triangles = mesh->num_triangles();
for (size_t j = 0; j < num_triangles; j++) {
Mesh::Triangle t = mesh->get_triangle(j);
float3 p1 = mesh->get_verts()[t.v[0]];
float3 p2 = mesh->get_verts()[t.v[1]];
float3 p3 = mesh->get_verts()[t.v[2]];
surface_area += triangle_area(p1, p2, p3);
}
state->surface_area_lock.lock();
state->surface_area_map[mesh] = surface_area;
state->surface_area_lock.unlock();
}
else {
surface_area = it->second;
}
surface_area *= uniform_scale;
}
else {
size_t num_triangles = mesh->num_triangles();
for (size_t j = 0; j < num_triangles; j++) {
Mesh::Triangle t = mesh->get_triangle(j);
float3 p1 = transform_point(&tfm, mesh->get_verts()[t.v[0]]);
float3 p2 = transform_point(&tfm, mesh->get_verts()[t.v[1]]);
float3 p3 = transform_point(&tfm, mesh->get_verts()[t.v[2]]);
surface_area += triangle_area(p1, p2, p3);
}
}
return surface_area;
return 1.0f;
}
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
@ -476,7 +403,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.tfm = tfm;
kobject.itfm = itfm;
kobject.surface_area = object_surface_area(state, tfm, geom);
kobject.volume_density = object_volume_density(tfm, geom);
kobject.color[0] = color.x;
kobject.color[1] = color.y;
kobject.color[2] = color.z;

File diff suppressed because it is too large Load Diff

View File

@ -558,8 +558,9 @@ typedef struct BakeData {
char normal_swizzle[3];
char normal_space;
char target;
char save_mode;
char _pad[7];
char _pad[6];
struct Object *cage_object;
} BakeData;
@ -574,6 +575,12 @@ typedef enum eBakeNormalSwizzle {
R_BAKE_NEGZ = 5,
} eBakeNormalSwizzle;
/* BakeData.target (char) */
typedef enum eBakeTarget {
R_BAKE_TARGET_IMAGE_TEXTURES = 0,
R_BAKE_TARGET_VERTEX_COLORS = 1,
} eBakeTarget;
/* BakeData.save_mode (char) */
typedef enum eBakeSaveMode {
R_BAKE_SAVE_INTERNAL = 0,

View File

@ -83,6 +83,7 @@ extern const EnumPropertyItem rna_enum_image_generated_type_items[];
extern const EnumPropertyItem rna_enum_normal_space_items[];
extern const EnumPropertyItem rna_enum_normal_swizzle_items[];
extern const EnumPropertyItem rna_enum_bake_save_mode_items[];
extern const EnumPropertyItem rna_enum_bake_target_items[];
extern const EnumPropertyItem rna_enum_views_format_items[];
extern const EnumPropertyItem rna_enum_views_format_multilayer_items[];

View File

@ -433,6 +433,20 @@ const EnumPropertyItem rna_enum_normal_swizzle_items[] = {
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_bake_target_items[] = {
{R_BAKE_TARGET_IMAGE_TEXTURES,
"IMAGE_TEXTURES",
0,
"Image Textures",
"Bake to image data-blocks associated with active image texture nodes in materials"},
{R_BAKE_TARGET_VERTEX_COLORS,
"VERTEX_COLORS",
0,
"Vertex Colors",
"Bake to active vertex color layer on meshes"},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_bake_save_mode_items[] = {
{R_BAKE_SAVE_INTERNAL,
"INTERNAL",
@ -5166,10 +5180,15 @@ static void rna_def_bake_data(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ImageFormatSettings");
RNA_def_property_ui_text(prop, "Image Format", "");
prop = RNA_def_property(srna, "target", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_bake_target_items);
RNA_def_property_ui_text(prop, "Target", "Where to output the baked map");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "save_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "save_mode");
RNA_def_property_enum_items(prop, rna_enum_bake_save_mode_items);
RNA_def_property_ui_text(prop, "Save Mode", "Choose how to save the baking map");
RNA_def_property_ui_text(prop, "Save Mode", "Where to save baked image textures");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* flags */

View File

@ -39,11 +39,23 @@ typedef struct BakeImage {
size_t offset;
} BakeImage;
typedef struct BakeImages {
BakeImage *data; /* all the images of an object */
int *lookup; /* lookup table from Material to BakeImage */
int size;
} BakeImages;
typedef struct BakeTargets {
/* All images of the object. */
BakeImage *images;
int num_images;
/* Lookup table from Material number to BakeImage. */
int *material_to_image;
int num_materials;
/* Pixel buffer to bake to. */
float *result;
int num_pixels;
int num_channels;
/* Baking to non-color data image. */
bool is_noncolor;
} BakeTargets;
typedef struct BakePixel {
int primitive_id, object_id;
@ -70,8 +82,7 @@ bool RE_bake_engine(struct Render *re,
struct Object *object,
const int object_id,
const BakePixel pixel_array[],
const BakeImages *bake_images,
const int depth,
const BakeTargets *targets,
const eScenePassType pass_type,
const int pass_filter,
float result[]);
@ -95,7 +106,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
void RE_bake_pixels_populate(struct Mesh *me,
struct BakePixel *pixel_array,
const size_t num_pixels,
const struct BakeImages *bake_images,
const struct BakeTargets *targets,
const char *uv_layer);
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, char *mask);

View File

@ -691,7 +691,7 @@ static void bake_differentials(BakeDataZSpan *bd,
void RE_bake_pixels_populate(Mesh *me,
BakePixel pixel_array[],
const size_t num_pixels,
const BakeImages *bake_images,
const BakeTargets *targets,
const char *uv_layer)
{
const MLoopUV *mloopuv;
@ -709,7 +709,7 @@ void RE_bake_pixels_populate(Mesh *me,
BakeDataZSpan bd;
bd.pixel_array = pixel_array;
bd.zspan = MEM_callocN(sizeof(ZSpan) * bake_images->size, "bake zspan");
bd.zspan = MEM_callocN(sizeof(ZSpan) * targets->num_images, "bake zspan");
/* initialize all pixel arrays so we know which ones are 'blank' */
for (int i = 0; i < num_pixels; i++) {
@ -717,8 +717,8 @@ void RE_bake_pixels_populate(Mesh *me,
pixel_array[i].object_id = 0;
}
for (int i = 0; i < bake_images->size; i++) {
zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height);
for (int i = 0; i < targets->num_images; i++) {
zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height);
}
const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
@ -731,13 +731,13 @@ void RE_bake_pixels_populate(Mesh *me,
const MPoly *mp = &me->mpoly[lt->poly];
float vec[3][2];
int mat_nr = mp->mat_nr;
int image_id = bake_images->lookup[mat_nr];
int image_id = targets->material_to_image[mat_nr];
if (image_id < 0) {
continue;
}
bd.bk_image = &bake_images->data[image_id];
bd.bk_image = &targets->images[image_id];
bd.primitive_id = i;
for (int a = 0; a < 3; a++) {
@ -755,7 +755,7 @@ void RE_bake_pixels_populate(Mesh *me,
zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel);
}
for (int i = 0; i < bake_images->size; i++) {
for (int i = 0; i < targets->num_images; i++) {
zbuf_free_span(&bd.zspan[i]);
}

View File

@ -663,8 +663,7 @@ bool RE_bake_engine(Render *re,
Object *object,
const int object_id,
const BakePixel pixel_array[],
const BakeImages *bake_images,
const int depth,
const BakeTargets *targets,
const eScenePassType pass_type,
const int pass_filter,
float result[])
@ -707,14 +706,14 @@ bool RE_bake_engine(Render *re,
type->update(engine, re->main, engine->depsgraph);
}
for (int i = 0; i < bake_images->size; i++) {
const BakeImage *image = bake_images->data + i;
for (int i = 0; i < targets->num_images; i++) {
const BakeImage *image = targets->images + i;
engine->bake.pixels = pixel_array + image->offset;
engine->bake.result = result + image->offset * depth;
engine->bake.result = result + image->offset * targets->num_channels;
engine->bake.width = image->width;
engine->bake.height = image->height;
engine->bake.depth = depth;
engine->bake.depth = targets->num_channels;
engine->bake.object_id = object_id;
type->bake(