libobs: Allow scene items to use legacy absolute mode

This is to keep old collections running in relative mode until they
can be migrated.
This commit is contained in:
derrod
2024-08-27 23:58:51 +02:00
committed by Rodney
parent 1565ca8eb1
commit ddd586ae03
2 changed files with 190 additions and 77 deletions
+188 -77
View File
@@ -178,6 +178,9 @@ static void *scene_create(obs_data_t *settings, struct obs_source *source)
goto fail;
}
scene->absolute_coordinates = obs_data_get_bool(obs->data.private_data,
"AbsoluteCoordinates");
UNUSED_PARAMETER(settings);
return scene;
@@ -469,7 +472,11 @@ static void calculate_bounds_data(struct obs_scene_item *item,
uint32_t *cx, uint32_t *cy)
{
struct vec2 bounds;
size_to_absolute(&bounds, &item->bounds, item);
if (item->absolute_coordinates)
vec2_copy(&bounds, &item->bounds);
else
size_to_absolute(&bounds, &item->bounds, item);
float width = (float)(*cx) * fabsf(scale->x);
float height = (float)(*cy) * fabsf(scale->y);
float item_aspect = width / height;
@@ -659,8 +666,13 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex)
vec2_zero(&base_origin);
vec2_zero(&origin);
item_canvas_scale(&scale, item);
pos_to_absolute(&position, &item->pos, item);
if (!item->absolute_coordinates) {
item_canvas_scale(&scale, item);
pos_to_absolute(&position, &item->pos, item);
} else {
scale = item->scale;
position = item->pos;
}
/* ----------------------- */
@@ -694,7 +706,10 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex)
/* ----------------------- */
if (item->bounds_type != OBS_BOUNDS_NONE) {
size_to_absolute(&scale, &item->bounds, item);
if (!item->absolute_coordinates)
size_to_absolute(&scale, &item->bounds, item);
else
vec2_copy(&scale, &item->bounds);
} else {
scale.x *= (float)width;
scale.y *= (float)height;
@@ -1257,7 +1272,8 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
visible = obs_data_get_bool(item_data, "visible");
lock = obs_data_get_bool(item_data, "locked");
if (obs_data_has_user_value(item_data, "pos_rel") &&
if (!item->absolute_coordinates &&
obs_data_has_user_value(item_data, "pos_rel") &&
obs_data_has_user_value(item_data, "scale_rel") &&
obs_data_has_user_value(item_data, "scale_ref")) {
obs_data_get_vec2(item_data, "pos_rel", &item->pos);
@@ -1265,7 +1281,8 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
obs_data_get_vec2(item_data, "scale_ref", &item->scale_ref);
} else {
obs_data_get_vec2(item_data, "pos", &item->pos);
pos_from_absolute(&item->pos, &item->pos, item);
if (!item->absolute_coordinates)
pos_from_absolute(&item->pos, &item->pos, item);
obs_data_get_vec2(item_data, "scale", &item->scale);
}
@@ -1285,11 +1302,13 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
item->crop_to_bounds = obs_data_get_bool(item_data, "bounds_crop");
obs_data_get_vec2(item_data, "bounds", &item->bounds);
if (obs_data_has_user_value(item_data, "bounds_rel")) {
if (!item->absolute_coordinates &&
obs_data_has_user_value(item_data, "bounds_rel")) {
obs_data_get_vec2(item_data, "bounds_rel", &item->bounds);
} else {
obs_data_get_vec2(item_data, "bounds", &item->bounds);
size_from_absolute(&item->bounds, &item->bounds, item);
if (!item->absolute_coordinates)
size_from_absolute(&item->bounds, &item->bounds, item);
}
item->crop.left = (uint32_t)obs_data_get_int(item_data, "crop_left");
@@ -1374,6 +1393,9 @@ static void scene_load(void *data, obs_data_t *settings)
if (obs_data_has_user_value(settings, "id_counter"))
scene->id_counter = obs_data_get_int(settings, "id_counter");
scene->absolute_coordinates = obs_data_get_bool(obs->data.private_data,
"AbsoluteCoordinates");
if (!items)
return;
@@ -1408,29 +1430,16 @@ static void scene_save_item(obs_data_array_t *array,
get_ungrouped_transform(backup_group, &pos, &scale, &rot);
}
/* For backwards compatibility, also store absolute values. */
struct vec2 tmp_abs;
obs_data_set_string(item_data, "name", name);
obs_data_set_string(item_data, "source_uuid", src_uuid);
obs_data_set_bool(item_data, "visible", item->user_visible);
obs_data_set_bool(item_data, "locked", item->locked);
obs_data_set_double(item_data, "rot", rot);
pos_to_absolute(&tmp_abs, &pos, item);
obs_data_set_vec2(item_data, "pos", &tmp_abs);
obs_data_set_vec2(item_data, "pos_rel", &pos);
item_canvas_scale(&tmp_abs, item);
obs_data_set_vec2(item_data, "scale", &tmp_abs);
obs_data_set_vec2(item_data, "scale_rel", &scale);
obs_data_set_vec2(item_data, "scale_ref", &item->scale_ref);
obs_data_set_int(item_data, "align", (int)item->align);
obs_data_set_int(item_data, "bounds_type", (int)item->bounds_type);
obs_data_set_int(item_data, "bounds_align", (int)item->bounds_align);
obs_data_set_bool(item_data, "bounds_crop", item->crop_to_bounds);
obs_data_set_vec2(item_data, "bounds", &item->bounds);
size_to_absolute(&tmp_abs, &item->bounds, item);
obs_data_set_vec2(item_data, "bounds", &tmp_abs);
obs_data_set_vec2(item_data, "bounds_rel", &item->bounds);
obs_data_set_int(item_data, "crop_left", (int)item->crop.left);
obs_data_set_int(item_data, "crop_top", (int)item->crop.top);
obs_data_set_int(item_data, "crop_right", (int)item->crop.right);
@@ -1438,6 +1447,27 @@ static void scene_save_item(obs_data_array_t *array,
obs_data_set_int(item_data, "id", item->id);
obs_data_set_bool(item_data, "group_item_backup", !!backup_group);
if (!item->absolute_coordinates) {
/* For backwards compatibility, also store absolute values. */
struct vec2 tmp_abs;
pos_to_absolute(&tmp_abs, &pos, item);
obs_data_set_vec2(item_data, "pos", &tmp_abs);
obs_data_set_vec2(item_data, "pos_rel", &pos);
item_canvas_scale(&tmp_abs, item);
obs_data_set_vec2(item_data, "scale", &tmp_abs);
obs_data_set_vec2(item_data, "scale_rel", &scale);
size_to_absolute(&tmp_abs, &item->bounds, item);
obs_data_set_vec2(item_data, "bounds", &tmp_abs);
obs_data_set_vec2(item_data, "bounds_rel", &item->bounds);
} else {
obs_data_set_vec2(item_data, "pos", &pos);
obs_data_set_vec2(item_data, "scale", &scale);
obs_data_set_vec2(item_data, "bounds", &item->bounds);
}
if (item->is_group) {
obs_scene_t *group_scene = item->source->context.data;
obs_sceneitem_t *group_item;
@@ -2520,6 +2550,7 @@ static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene,
item->is_scene = strcmp(source->info.id, scene_info.id) == 0;
item->private_settings = obs_data_create();
item->toggle_visibility = OBS_INVALID_HOTKEY_PAIR_ID;
item->absolute_coordinates = scene->absolute_coordinates;
os_atomic_set_long(&item->active_refs, 1);
vec2_set(&item->scale, 1.0f, 1.0f);
vec2_set(&item->scale_ref, (float)scene_getwidth(scene),
@@ -2904,7 +2935,11 @@ bool obs_sceneitem_selected(const obs_sceneitem_t *item)
void obs_sceneitem_set_pos(obs_sceneitem_t *item, const struct vec2 *pos)
{
if (item) {
pos_from_absolute(&item->pos, pos, item);
if (!item->absolute_coordinates)
pos_from_absolute(&item->pos, pos, item);
else
vec2_copy(&item->pos, pos);
do_update_transform(item);
}
}
@@ -2913,7 +2948,11 @@ void obs_sceneitem_set_relative_pos(obs_sceneitem_t *item,
const struct vec2 *pos)
{
if (item) {
vec2_copy(&item->pos, pos);
if (!item->absolute_coordinates)
vec2_copy(&item->pos, pos);
else
pos_to_absolute(&item->pos, pos, item);
do_update_transform(item);
}
}
@@ -2929,7 +2968,11 @@ void obs_sceneitem_set_rot(obs_sceneitem_t *item, float rot)
void obs_sceneitem_set_scale(obs_sceneitem_t *item, const struct vec2 *scale)
{
if (item) {
item_relative_scale(&item->scale, scale, item);
if (!item->absolute_coordinates)
item_relative_scale(&item->scale, scale, item);
else
vec2_copy(&item->scale, scale);
do_update_transform(item);
}
}
@@ -3093,7 +3136,11 @@ void obs_sceneitem_set_bounds_crop(obs_sceneitem_t *item, bool crop)
void obs_sceneitem_set_bounds(obs_sceneitem_t *item, const struct vec2 *bounds)
{
if (item) {
size_from_absolute(&item->bounds, bounds, item);
if (!item->absolute_coordinates)
size_from_absolute(&item->bounds, bounds, item);
else
vec2_copy(&item->bounds, bounds);
do_update_transform(item);
}
}
@@ -3102,22 +3149,36 @@ void obs_sceneitem_set_relative_bounds(obs_sceneitem_t *item,
const struct vec2 *bounds)
{
if (item) {
vec2_copy(&item->bounds, bounds);
if (!item->absolute_coordinates)
vec2_copy(&item->bounds, bounds);
else
size_to_absolute(&item->bounds, bounds, item);
do_update_transform(item);
}
}
void obs_sceneitem_get_pos(const obs_sceneitem_t *item, struct vec2 *pos)
{
if (item)
if (!item)
return;
if (!item->absolute_coordinates)
pos_to_absolute(pos, &item->pos, item);
else
vec2_copy(pos, &item->pos);
}
void obs_sceneitem_get_relative_pos(const obs_sceneitem_t *item,
struct vec2 *pos)
{
if (item)
if (!item)
return;
if (!item->absolute_coordinates)
vec2_copy(pos, &item->pos);
else
pos_from_absolute(pos, &item->pos, item);
}
float obs_sceneitem_get_rot(const obs_sceneitem_t *item)
@@ -3127,8 +3188,13 @@ float obs_sceneitem_get_rot(const obs_sceneitem_t *item)
void obs_sceneitem_get_scale(const obs_sceneitem_t *item, struct vec2 *scale)
{
if (item)
if (!item)
return;
if (!item->absolute_coordinates)
item_canvas_scale(scale, item);
else
vec2_copy(scale, &item->scale);
}
uint32_t obs_sceneitem_get_alignment(const obs_sceneitem_t *item)
@@ -3153,29 +3219,50 @@ bool obs_sceneitem_get_bounds_crop(const obs_sceneitem_t *item)
void obs_sceneitem_get_bounds(const obs_sceneitem_t *item, struct vec2 *bounds)
{
if (item)
if (!item)
return;
if (!item->absolute_coordinates)
size_to_absolute(bounds, &item->bounds, item);
else
vec2_copy(bounds, &item->bounds);
}
void obs_sceneitem_get_relative_bounds(const obs_sceneitem_t *item,
struct vec2 *bounds)
{
if (item)
if (!item)
return;
if (!item->absolute_coordinates)
vec2_copy(bounds, &item->bounds);
else
size_from_absolute(bounds, &item->bounds, item);
}
static inline void scene_item_get_info_internal(const obs_sceneitem_t *item,
struct obs_transform_info *info)
{
if (!item->absolute_coordinates) {
pos_to_absolute(&info->pos, &item->pos, item);
item_canvas_scale(&info->scale, item);
size_to_absolute(&info->bounds, &item->bounds, item);
} else {
info->pos = item->pos;
info->scale = item->scale;
info->bounds = item->bounds;
}
info->rot = item->rot;
info->alignment = item->align;
info->bounds_type = item->bounds_type;
info->bounds_alignment = item->bounds_align;
}
void obs_sceneitem_get_info(const obs_sceneitem_t *item,
struct obs_transform_info *info)
{
if (item && info) {
pos_to_absolute(&info->pos, &item->pos, item);
info->rot = item->rot;
item_canvas_scale(&info->scale, item);
info->alignment = item->align;
info->bounds_type = item->bounds_type;
info->bounds_alignment = item->bounds_align;
size_to_absolute(&info->bounds, &item->bounds, item);
info->bounds = item->bounds;
scene_item_get_info_internal(item, info);
}
}
@@ -3183,14 +3270,7 @@ void obs_sceneitem_get_info2(const obs_sceneitem_t *item,
struct obs_transform_info *info)
{
if (item && info) {
pos_to_absolute(&info->pos, &item->pos, item);
info->rot = item->rot;
item_canvas_scale(&info->scale, item);
info->alignment = item->align;
info->bounds_type = item->bounds_type;
info->bounds_alignment = item->bounds_align;
size_to_absolute(&info->bounds, &item->bounds, item);
info->bounds = item->bounds;
scene_item_get_info_internal(item, info);
info->crop_to_bounds = item->crop_to_bounds;
}
}
@@ -3199,30 +3279,52 @@ void obs_sceneitem_get_info3(const obs_sceneitem_t *item,
struct obs_transform_info *info)
{
if (item && info) {
info->pos = item->pos;
if (!item->absolute_coordinates) {
info->pos = item->pos;
item_canvas_scale(&info->scale, item);
info->bounds = item->bounds;
} else {
pos_from_absolute(&info->pos, &item->pos, item);
item_relative_scale(&info->scale, &item->scale, item);
size_from_absolute(&info->bounds, &item->bounds, item);
}
info->rot = item->rot;
item_canvas_scale(&info->scale, item);
info->alignment = item->align;
info->bounds_type = item->bounds_type;
info->bounds_alignment = item->bounds_align;
info->bounds = item->bounds;
info->crop_to_bounds = item->crop_to_bounds;
}
}
static inline void
scene_item_set_info_internal(obs_sceneitem_t *item,
const struct obs_transform_info *info)
{
if (!item->absolute_coordinates) {
pos_from_absolute(&item->pos, &info->pos, item);
size_from_absolute(&item->bounds, &info->bounds, item);
if (isfinite(info->scale.x) && isfinite(info->scale.y)) {
item_relative_scale(&item->scale, &info->scale, item);
}
} else {
item->pos = info->pos;
item->bounds = info->bounds;
if (isfinite(info->scale.x) && isfinite(info->scale.y)) {
item->scale = info->scale;
}
}
item->rot = info->rot;
item->align = info->alignment;
item->bounds_type = info->bounds_type;
item->bounds_align = info->bounds_alignment;
}
void obs_sceneitem_set_info(obs_sceneitem_t *item,
const struct obs_transform_info *info)
{
if (item && info) {
pos_from_absolute(&item->pos, &info->pos, item);
item->rot = info->rot;
if (isfinite(info->scale.x) && isfinite(info->scale.y)) {
item_relative_scale(&item->scale, &info->scale, item);
}
item->align = info->alignment;
item->bounds_type = info->bounds_type;
item->bounds_align = info->bounds_alignment;
size_from_absolute(&item->bounds, &info->bounds, item);
item->bounds = info->bounds;
scene_item_set_info_internal(item, info);
do_update_transform(item);
}
}
@@ -3231,16 +3333,7 @@ void obs_sceneitem_set_info2(obs_sceneitem_t *item,
const struct obs_transform_info *info)
{
if (item && info) {
pos_from_absolute(&item->pos, &info->pos, item);
item->rot = info->rot;
if (isfinite(info->scale.x) && isfinite(info->scale.y)) {
item_relative_scale(&item->scale, &info->scale, item);
}
item->align = info->alignment;
item->bounds_type = info->bounds_type;
item->bounds_align = info->bounds_alignment;
size_from_absolute(&item->bounds, &info->bounds, item);
item->bounds = info->bounds;
scene_item_set_info_internal(item, info);
item->crop_to_bounds = info->crop_to_bounds;
do_update_transform(item);
}
@@ -3250,15 +3343,28 @@ void obs_sceneitem_set_info3(obs_sceneitem_t *item,
const struct obs_transform_info *info)
{
if (item && info) {
item->pos = info->pos;
item->rot = info->rot;
if (isfinite(info->scale.x) && isfinite(info->scale.y)) {
item_relative_scale(&item->scale, &info->scale, item);
if (!item->absolute_coordinates) {
item->pos = info->pos;
item->bounds = info->bounds;
if (isfinite(info->scale.x) &&
isfinite(info->scale.y)) {
item_relative_scale(&item->scale, &info->scale,
item);
}
} else {
pos_to_absolute(&item->pos, &info->pos, item);
size_to_absolute(&item->bounds, &info->bounds, item);
if (isfinite(info->scale.x) &&
isfinite(info->scale.y)) {
item_canvas_scale(&item->scale, item);
}
}
item->rot = info->rot;
item->align = info->alignment;
item->bounds_type = info->bounds_type;
item->bounds_align = info->bounds_alignment;
item->bounds = info->bounds;
item->crop_to_bounds = info->crop_to_bounds;
do_update_transform(item);
}
}
@@ -3733,7 +3839,10 @@ static bool resize_scene_base(obs_scene_t *scene, struct vec2 *minv,
item = scene->first_item;
if (item) {
struct vec2 minv_rel;
size_from_absolute(&minv_rel, minv, item);
if (!item->absolute_coordinates)
size_from_absolute(&minv_rel, minv, item);
else
vec2_copy(&minv_rel, minv);
while (item) {
vec2_sub(&item->pos, &item->pos, &minv_rel);
@@ -3788,7 +3897,9 @@ static void resize_group(obs_sceneitem_t *group, bool scene_resize)
new_pos.y = (maxv.y - minv.y) * 0.5f + minv.y;
transform_val(&new_pos, &group->draw_transform);
pos_from_absolute(&new_pos, &new_pos, group);
if (!group->absolute_coordinates)
pos_from_absolute(&new_pos, &new_pos, group);
vec2_copy(&group->pos, &new_pos);
}
+2
View File
@@ -51,6 +51,7 @@ struct obs_scene_item {
gs_texrender_t *item_render;
struct obs_sceneitem_crop crop;
bool absolute_coordinates;
struct vec2 pos;
struct vec2 scale;
struct vec2 scale_ref;
@@ -112,6 +113,7 @@ struct obs_scene {
uint32_t cx;
uint32_t cy;
bool absolute_coordinates;
uint32_t last_width;
uint32_t last_height;