Can't get script to assign media to fixed X Center & Y Center, help...

TAGyerit wrote on 10/14/2024, 10:59 AM

I'm pasting in two scripts: The first one works and takes highlighted media and adjusts the X Center and Y Center by a specific amount relative to where they started out, here's the working script:
 

using System;
using System.Windows.Forms; // Required for MessageBox
using ScriptPortal.Vegas;

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        // Assigning variables for X and Y position adjustments
        float xAdjustment = 38.0f;  // Change this value for X position adjustment
        float yAdjustment = -189.0f; // Change this value for Y position adjustment

        bool isMediaSelected = false;

        foreach (Track track in vegas.Project.Tracks)
        {
            if (track.IsVideo())
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        isMediaSelected = true; // At least one media is selected

                        VideoEvent vEvent = (VideoEvent)evnt;
                        VideoMotionKeyframes vKeyframes = vEvent.VideoMotion.Keyframes;

                        // Remove all keyframes except the first one
                        for (int i = vKeyframes.Count - 1; i > 0; i--)
                        {
                            vKeyframes.Remove(vKeyframes[i]);
                        }

                        // Adjust the first keyframe's X and Y position
                        VideoMotionKeyframe firstKeyframe = vKeyframes[0];

                        // Create the amount to move using the assigned X and Y adjustments
                        VideoMotionVertex moveByAmount = new VideoMotionVertex(xAdjustment, yAdjustment);

                        // Apply the movement to the keyframe
                        firstKeyframe.MoveBy(moveByAmount);
                    }
                }
            }
        }

        // If no media was selected, show a message box
        if (!isMediaSelected)
        {
            MessageBox.Show("Highlight the clip you want to move first", "No Clip Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
}

I'd think that creating a similar script that does the same thing but just assigns the X Center and Y Center to a fixed number (not a relative number based on where the media was previously) would be a simple change but it's giving errors, here's what I tried to do:
 

using System;
using System.Windows.Forms; // Required for MessageBox
using ScriptPortal.Vegas;

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        // Assigning fixed values for X and Y center positions
        float fixedXCenter = 1911.8f;
        float fixedYCenter = 1481.3f;

        bool isMediaSelected = false;

        foreach (Track track in vegas.Project.Tracks)
        {
            if (track.IsVideo())
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        isMediaSelected = true; // At least one media is selected

                        VideoEvent vEvent = (VideoEvent)evnt;
                        VideoMotionKeyframes vKeyframes = vEvent.VideoMotion.Keyframes;

                        // Remove all keyframes except the first one
                        for (int i = vKeyframes.Count - 1; i > 0; i--)
                        {
                            vKeyframes.Remove(vKeyframes[i]);
                        }

                        // Adjust the first keyframe's X and Y position
                        VideoMotionKeyframe firstKeyframe = vKeyframes[0];

                        // Move the keyframe to the fixed X and Y positions
                        VideoMotionVertex moveByAmount = new VideoMotionVertex(fixedXCenter - firstKeyframe.Position.X, fixedYCenter - firstKeyframe.Position.Y);
                        firstKeyframe.MoveBy(moveByAmount);
                    }
                }
            }
        }

        // If no media was selected, show a message box
        if (!isMediaSelected)
        {
            MessageBox.Show("Highlight the clip you want to adjust first", "No Clip Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
}

Is there a different method I can use to set a fixed position for highlighted media versus relative position? I'm actually trying to assign all four of these variables to a fixed position, but was trying to get the X Center and Y Center to work first before trying to add in the Width and Height. Here are the four fixed variables I want to assign in the script:

Width: 3,401.8
Height: 2362.3
X Center: 1911.8
Y Center: 1481.3

Thanks for any help you can provide, yay! :-)

(PS - I'm using Vegas Pro 20, I'm not aware that scripts behave any differently whether it's 19, 20, 21, 22, but if they do please let me know.)

Comments

zzzzzz9125 wrote on 10/14/2024, 12:14 PM

@TAGyerit Your mistake is:

VideoMotionVertex moveByAmount = new VideoMotionVertex(fixedXCenter - firstKeyframe.Position.X, fixedYCenter - firstKeyframe.Position.Y);

VideoMotionKeyframe.Position is a Timecode value, rather than VideoMotionVertex, and has no XY values.

Do you want to use the X&Y value of the rectangle's center? Use (TopLeft + BottomRight) / 2 to figure them out separately.

Using VEGAS Pro 22 build 248 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

jetdv wrote on 10/14/2024, 12:33 PM

The problem is on this line:

VideoMotionVertex moveByAmount = new VideoMotionVertex(fixedXCenter - firstKeyframe.Position.X, fixedYCenter - firstKeyframe.Position.Y);

firstKeyframe.Position is a TIMECODE and, therefore, does not have an "X" or "Y". You're assuming "Position" is a location when, in fact, it's a timecode stating where on the timeline the keyframe is "positioned."

Could I see what the end result should be? You're just wanting to change the "X Center" and "Y Center"? Then try this instead:

                        // Move the keyframe to the fixed X and Y positions
                        VideoMotionVertex cv = new VideoMotionVertex(fixedXCenter, fixedYCenter);
                        firstKeyframe.Center = cv;

Or are you wanting to change the actual "position" of the image? To do that, you're going to need to calculate the difference and then "moveby" half that amount.

                        // Move the keyframe to the fixed X and Y positions
                        float xCenter = Math.Abs(firstKeyframe.TopRight.X - firstKeyframe.TopLeft.X);
                        float yCenter = Math.Abs(firstKeyframe.BottomLeft.Y - firstKeyframe.TopLeft.Y);
                        VideoMotionVertex moveByAmount = new VideoMotionVertex((fixedXCenter + (fixedXCenter - xCenter))/2f, (fixedYCenter + (fixedYCenter - yCenter))/2f);
                        firstKeyframe.MoveBy(moveByAmount);

TAGyerit wrote on 10/14/2024, 1:11 PM

Thank you so so much for the help! Here's my finished working script, all it does is recreate what could be done with an Event Pan/Crop Preset set to the same X Y Width Height settings, but I'm trying to set up everything script-based and this did the trick, thank you thank you!! (Script now works, is fixed, /DONE)

using System;
using System.Windows.Forms; // Required for MessageBox
using ScriptPortal.Vegas;

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        // Assigning fixed values for X, Y, Width, and Height
        float fixedXCenter = 1911.8f;
        float fixedYCenter = 1481.3f;
        float fixedWidth = 3401.8f;
        float fixedHeight = 2362.3f;

        bool isMediaSelected = false;

        foreach (Track track in vegas.Project.Tracks)
        {
            if (track.IsVideo())
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        isMediaSelected = true; // At least one media is selected

                        VideoEvent vEvent = (VideoEvent)evnt;
                        VideoMotionKeyframes vKeyframes = vEvent.VideoMotion.Keyframes;

                        // Remove all keyframes except the first one
                        for (int i = vKeyframes.Count - 1; i > 0; i--)
                        {
                            vKeyframes.Remove(vKeyframes[i]);
                        }

                        // Adjust the first keyframe's X, Y, Width, and Height
                        VideoMotionKeyframe firstKeyframe = vKeyframes[0];

                        // Calculate the current center of the bounding rectangle
                        float currentXCenter = (firstKeyframe.TopLeft.X + firstKeyframe.BottomRight.X) / 2;
                        float currentYCenter = (firstKeyframe.TopLeft.Y + firstKeyframe.BottomRight.Y) / 2;

                        // Move to the fixed X and Y center
                        VideoMotionVertex moveByAmount = new VideoMotionVertex(fixedXCenter - currentXCenter, fixedYCenter - currentYCenter);
                        firstKeyframe.MoveBy(moveByAmount);

                        // Set the width and height by adjusting the bounds
                        float currentWidth = Math.Abs(firstKeyframe.BottomRight.X - firstKeyframe.TopLeft.X);
                        float currentHeight = Math.Abs(firstKeyframe.BottomRight.Y - firstKeyframe.TopLeft.Y);

                        // Calculate the scale factors for width and height
                        float widthScale = fixedWidth / currentWidth;
                        float heightScale = fixedHeight / currentHeight;

                        // Apply the scaling to the keyframe to adjust width and height
                        VideoMotionVertex scaleFactor = new VideoMotionVertex(widthScale, heightScale);
                        firstKeyframe.ScaleBy(scaleFactor);
                    }
                }
            }
        }

        // If no media was selected, show a message box
        if (!isMediaSelected)
        {
            MessageBox.Show("Highlight the clip you want to adjust first", "No Clip Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
    }
}

 

Jack S wrote on 10/15/2024, 5:42 AM

@TAGyerit It’s customary to mark the comment that gave you the result as the solution. It’s up to you which one you think is the one.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE