mshvern23
Topic Author
Posts: 35
Joined: 22 May 2023, 02:00

Populating a PointCollection from Blueprint in Unreal Engine

10 Jun 2023, 06:04

How would I go about doing this in Unreal Engine? I'd like to set-up a {Binding Points} for a PolyBezierSegment. List (TArray) of Vector2D exposed in the View (UNoesisInstance) doesn't work for this binding.

I attempted to resolve this by creating a converter from a list of points into a point collection and failed.

XAML:
    <UserControl.Resources>
        <local:PointsConverter x:Key="PointsConverter"/>
        ...
                <Canvas>
                    <Path Stroke="Black" StrokeThickness="10">
                        <Path.Data>
                            <PathGeometry>
                                <PathGeometry.Figures>
                                    <PathFigureCollection>
                                        <PathFigure StartPoint="100,80">
                                            <PathFigure.Segments>
                                                <PathSegmentCollection>
                                                    <PolyBezierSegment Points="{Binding PolyPoints, Converter={StaticResource PointsConverter}}">
	...
                                                    
CPP:
    bool TryConvert(Noesis::ArrayRef<Noesis::BaseComponent*> values, const Noesis::Type*, Noesis::BaseComponent*,
        Noesis::Ptr<Noesis::BaseComponent>& result) override
    {
        // NS_ASSERT(values.Size() == 3);
        Noesis::PointCollection PointCollection;
        for(uint32_t i = 0; i < values.Size(); i++)
        {
            PointCollection.Add( Noesis::Boxing::Unbox<Noesis::Point>(values[i]));
        }
        result = PointCollection;
        return true;
    }

    NS_IMPLEMENT_INLINE_REFLECTION_(PointsConverter, BaseMultiValueConverter,
        "Converters.PointsConverter");
       
This yielded me a:
LogNoesis: Warning: /Game;component/NoesisGUI/GameMap.xaml(40,72): Cannot set value for 'Binding.Converter', invalid value type 'AstrokillerNoesis.PointsConverter' for property type 'IValueConverter'
I attempted it in another way:
                                                    <PolyBezierSegment>
                                                        <MultiBinding Converter="{StaticResource PointsConverter}">
                                                            <Binding Path="PolyPoints" />
                                                        </MultiBinding>
                                                    </PolyBezierSegment>
But this lead to a crash with no useful log message.

My guess is that I'm doing something wrong.

Ideally, I'd like to be able to expose a point collection directly, but a workaround like a converter would help me a ton as well.

Thank you.
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: Populating a PointCollection from Blueprint in Unreal Engine

12 Jun 2023, 18:10

Hi,

The Points property in PolyBezierSegment is expecting specifically for a PointCollection object, and Unreal TArray<Vector2D> is exposed just as an IList to Noesis.
So you should be using an IValueConverter (inheriting from BaseValueConverter). What happens in your code is that you are inheriting from BaseMultiValueConverter, which is the base class for MultiBinding converters, but not for simple Bindings. I just tried with the following code and it works as expected:
class PointsConverter final: public Noesis::BaseValueConverter
{
public:
    bool TryConvert(Noesis::BaseComponent* value, const Noesis::Type* targetType,
        Noesis::BaseComponent* parameter, Noesis::Ptr<Noesis::BaseComponent>& result) override
    {
        IList* list = DynamicCast<IList*>(value);
        if (list != nullptr)
        {
            Noesis::Ptr<Noesis::PointCollection> points = Noesis::MakePtr<Noesis::PointCollection>();
            int numPoints = list->Count();
            for (int i = 0; i < numPoints; ++i)
            {
                points->AddComponent(list->GetComponent(i));
            }

            result.Reset(points);
            return true;
        }

        return false;
    }

    NS_IMPLEMENT_INLINE_REFLECTION_(PointsConverter, BaseValueConverter, "Converters.PointsConverter");
};
Regarding the crash, it is due to a bug in the xaml parser related to using a MultiBinding as the content of another object, instead of using it in a property. I reported it in our bugtracker #2624 to keep track of this.

Cheers.
 
mshvern23
Topic Author
Posts: 35
Joined: 22 May 2023, 02:00

Re: Populating a PointCollection from Blueprint in Unreal Engine

14 Jun 2023, 01:19

Thanks!

Who is online

Users browsing this forum: No registered users and 12 guests