Search code examples
c#wpfimage3dhelix-3d-toolkit

How to add a proceduaraly generated billboard to helix 3D


I have a set of procedural images that I would like to add as billboards to my helix 3D application.

Currently my application looks as following:

public partial class _3DControl
{
    HelixViewport3D hVp3D;
    public _3DControl()
    {
        InitializeComponent();
        createView();
    }

    public void createView()
    {
        hVp3D = new HelixViewport3D();
        var lights = new SunLight();
        lights.Altitude=40;
        lights.Ambient=0.4;
        this.Content = hVp3D;
        hVp3D.Children.Add(lights);
        this.Show();
    }

    public void  UploadBillboard(BitmapImage im, System.Windows.Media.Media3D.Point3D position,double width,double height)
    { 
        //create material 
        var mat = MaterialHelper.CreateImageMaterial(im, 0);
        var bboard = new BillboardVisual3D();
        bboard.Material = mat;

        //set coordinates 
        bboard.Position = position;
        bboard.Width = width;
        bboard.Height = height;

        //add the billboard 
        hVp3D.Children.Add(bboard);
    }

However when I call the function to add a billboard:

           HelixLinker.GetHelix().UploadBillboard(((Bitmap)e).bitmapToBitmapImage(), 
new System.Windows.Media.Media3D.Point3D(0, 0, 0), 100, 100);

Then I see nothing being added, any idea what I' m doing wrong?

I also tried with the RectangleVisual3D class.

public void UploadRect(BitmapImage im, System.Windows.Media.Media3D.Point3D position, double width, double height)
        {
            var mat = MaterialHelper.CreateImageMaterial(im, 0);
            var bboard = new RectangleVisual3D ();
            bboard.Material = mat;
            bboard.Width = width;

            hVp3D.Children.Add(bboard);
        }

Which if execuded in the same way results in a (promising) image enter image description here however in this case the material appears not to be properly set.

Note: I hope that the BillboardVisual3D is the right class, I'm working on something that will allow me to put image "on the floor" so to speak, I want to have flat images that don't have a depth and allow for transparancy.


Solution

  • Why do you set the Opacity to 0? Then you wont see anything.

    Try this:

    //create material 
    var mat = MaterialHelper.CreateImageMaterial(im);
    

    See the documentation

    Edit:

    Sorry, my bad with the string. But this ist working for me:

    Code:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            CreateBilboard();
        }
    
        private void CreateBilboard()
        {
            BitmapImage im = new BitmapImage(new System.Uri(@"C:\Users\Public\Pictures\Sample Pictures\Lighthouse.jpg"));
    
            var mat = MaterialHelper.CreateImageMaterial(im, 1);
            var bboard = new BillboardVisual3D();
            bboard.Material = mat;
    
            var position = new System.Windows.Media.Media3D.Point3D(0, 0, 0);
            var width = 100;
            var height = 100;
    
    
            //set coordinates 
            bboard.Position = position;
            bboard.Width = width;
            bboard.Height = height;
    
            //add the billboard 
            viewPort.Children.Add(bboard);
        }
    }
    

    XAML:

    <Window x:Class="BillboardImageMaterialDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ht="clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf" 
            Title="BillboardImageMaterialDemo" Height="480" Width="640">
        <Grid>
            <ht:HelixViewport3D x:Name="viewPort" ZoomExtentsWhenLoaded="True">
                <!-- Remember to add some lights -->
                <ht:SunLight/>
            </ht:HelixViewport3D>
        </Grid>
    </Window>
    

    Result:

    Bildboard with the lighthouse