Skip to content

Commit

Permalink
Added support to attach a clip to another clip
Browse files Browse the repository at this point in the history
  • Loading branch information
BrennoCaldato committed Jan 27, 2021
1 parent a94f09d commit 3f11361
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
49 changes: 38 additions & 11 deletions src/Clip.cpp
Expand Up @@ -100,6 +100,10 @@ void Clip::init_settings()
has_audio = Keyframe(-1.0);
has_video = Keyframe(-1.0);

// Initialize the attached object and attached clip as null pointers
attachedObject = nullptr;
attachedClip = NULL;

// Init reader info struct and cache size
init_reader_settings();
}
Expand Down Expand Up @@ -245,22 +249,23 @@ Clip::~Clip()
}

// Attach clip to bounding box
void Clip::AttachToTracker(std::string tracked_id)
void Clip::AttachToObject(std::string object_id)
{
// Search for the tracked object on the timeline
Timeline* parentTimeline = (Timeline *) ParentTimeline();

// Check if the clip has a parent timeline
if (parentTimeline){

if (parentTimeline) {
// Create a smart pointer to the tracked object from the timeline
std::shared_ptr<openshot::TrackedObjectBase> trackedObject = parentTimeline->GetTrackedObject(tracked_id);

std::shared_ptr<openshot::TrackedObjectBase> trackedObject = parentTimeline->GetTrackedObject(object_id);
Clip* clipObject = parentTimeline->GetClip(object_id);

// Check for valid tracked object
if (trackedObject){
SetAttachedObject(trackedObject);
}

else if (clipObject) {
SetAttachedClip(clipObject);
}
}
return;
}
Expand All @@ -271,6 +276,12 @@ void Clip::SetAttachedObject(std::shared_ptr<openshot::TrackedObjectBase> tracke
return;
}

// Set the pointer to the clip this clip is attached to
void Clip::SetAttachedClip(Clip* clipObject){
attachedClip = clipObject;
return;
}

/// Set the current reader
void Clip::Reader(ReaderBase* new_reader)
{
Expand Down Expand Up @@ -979,13 +990,15 @@ void Clip::SetJsonValue(const Json::Value root) {
cache.Clear();

// Set data from Json (if key is found)
if (!root["attached_id"].isNull())
if (!root["attached_id"].isNull()){
attached_id = root["attached_id"].asString();
if (attached_id.size() > 0 && attached_id != "None"){
AttachToTracker(attached_id);
AttachToObject(attached_id);
} else{
attachedObject = nullptr;
attachedClip = NULL;
}
}
if (!root["gravity"].isNull())
gravity = (GravityType) root["gravity"].asInt();
if (!root["scale"].isNull())
Expand Down Expand Up @@ -1315,14 +1328,28 @@ void Clip::apply_keyframes(std::shared_ptr<Frame> frame, int width, int height)
break;
}
}

// Initialize attached object's properties values
float attached_location_x = 0.0;
float attached_location_y = 0.0;
float attached_scale_x = 1.0;
float attached_scale_y = 1.0;
float attached_rotation = 0.0;

if (attachedClip){

// Convert Clip's frame position to Timeline's frame position
long clip_start_position = round(Position() * info.fps.ToDouble()) + 1;
long clip_start_frame = (Start() * info.fps.ToDouble()) + 1;
double timeline_frame_number = frame->number + clip_start_position - clip_start_frame;

attached_location_x = attachedClip->location_x.GetValue(timeline_frame_number);
attached_location_y = attachedClip->location_y.GetValue(timeline_frame_number);
attached_scale_x = attachedClip->scale_x.GetValue(timeline_frame_number);
attached_scale_y = attachedClip->scale_y.GetValue(timeline_frame_number);
attached_rotation = attachedClip->rotation.GetValue(timeline_frame_number);
}

/* TRANSFORM CLIP TO ATTACHED OBJECT'S POSITION AND DIMENSION */
if (attachedObject){

Expand Down Expand Up @@ -1371,7 +1398,7 @@ void Clip::apply_keyframes(std::shared_ptr<Frame> frame, int width, int height)
float sy = scale_y.GetValue(frame->number); // percentage Y scale

// Compose clip's scale to attachedObject's scale
if(attached_scale_x > 0.0 && attached_scale_y > 0.0){
if(attached_scale_x != 0.0 && attached_scale_y != 0.0){
sx*= attached_scale_x;
sy*= attached_scale_y;
}
Expand Down
7 changes: 6 additions & 1 deletion src/Clip.h
Expand Up @@ -126,6 +126,7 @@ namespace openshot {
bool is_open; ///> Is Reader opened
std::string attached_id; ///< Id of the bounding box that this clip is attached to
std::shared_ptr<openshot::TrackedObjectBase> attachedObject;
Clip* attachedClip; ///< Clip object this clip is attached to

// Audio resampler (if time mapping)
openshot::AudioResampler *resampler;
Expand Down Expand Up @@ -203,12 +204,16 @@ namespace openshot {
void SetAttachedId(std::string value) { attached_id = value; };

/// Attach clip to bounding box
void AttachToTracker(std::string tracked_id);
void AttachToObject(std::string object_id);

/// Set the pointer to the trackedObject this clip is attached to
void SetAttachedObject(std::shared_ptr<openshot::TrackedObjectBase> trackedObject);
/// Set the pointer to the clip this clip is attached to
void SetAttachedClip(Clip* clipObject);
/// Return a pointer to the trackedObject this clip is attached to
std::shared_ptr<openshot::TrackedObjectBase> GetAttachedObject() const { return attachedObject; };
/// Return a pointer to the clip this clip is attached to
Clip* GetAttachedClip() const { return attachedClip; };

/// Return the type name of the class
std::string Name() override { return "Clip"; };
Expand Down
2 changes: 1 addition & 1 deletion tests/KeyFrame_Tests.cpp
Expand Up @@ -666,7 +666,7 @@ TEST(Attach_test){
// Attach childClip to tracked object
std::string tracked_id = trackedData->Id();
childClip.Open();
childClip.AttachToTracker(tracked_id);
childClip.AttachToObject(tracked_id);

std::shared_ptr<TrackedObjectBBox> trackedTest = std::static_pointer_cast<TrackedObjectBBox>(childClip.GetAttachedObject());

Expand Down

0 comments on commit 3f11361

Please sign in to comment.