Merge branch 'master' into sculpt-dev
This commit is contained in:
commit
c203de25db
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
@ -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,
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue