I have Viewport3D in the Window. it will change the size when the window size changed.
<Window>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition/>
<Grid.RowDefinitions>
<Label Grid.Row="0" Content="top label"/>
<Viewport3D Grid.Row="1" x:Name="vp3D" >
<Viewport3D.Camera >
<PerspectiveCamera x:Name="pCamera" LookDirection="0 0 -1" UpDirection="0 1 0" />
</Viewport3D.Camera>
<Viewport2DVisual3D x:Name="v2dv3d">
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D x:Name="mg3d" TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>
<Image Height="{Binding ElementName=vp3D, Path=ActualHeight}" Width="{Binding ElementName=vp3D, Path=ActualWidth}" Stretch="Fill"/>
</Viewport2DVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFFFF" Direction="0,0,-1"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
</Window
Now I want the image show on like it's the original 2d window(look like nothing changed, but actually the image is 3d).
But problem is If I want it looking same as the same as WPF original look at, I must change some Camera settings, like PerspectiveCamera.Position
or MeshGeometry3D.Position
. because the Viewport3D
will change the size dynamically when the window change size, I must dynamically calculate the Viewport3D
settings. Is there anyway to do ?
I've already tried this, but can't calculate correctly: WPF 3D: Fitting entire image to view with PerspectiveCamera
I'm not sure if that is what you want, but have you tried this?
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="top label"/>
<Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Stretch="Fill"/>
<Viewport3D Grid.Row="1" x:Name="vp3D">
<Viewport3D.Camera >
<PerspectiveCamera x:Name="pCamera" Position="0,0,1" LookDirection="0,0,-1" />
</Viewport3D.Camera>
<Viewport2DVisual3D x:Name="v2dv3d">
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D x:Name="mg3d" Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0" TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>
</Viewport2DVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFFFF" Direction="0,0,-1"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
I finish it by myself.
// get the Viewport3D size first, If you want to use .ActualWidth or .ActualHeight property get it, make sure your application loaded finish, otherwise it will return 0.
double height = ; // get the Viewport3D height or calculate the height first
double width = ; // get the Viewport3D width or calculate the width first
mg3d.Positions.Clear();
mg3d.Positions.Add(new Point3D(-width, height, 0.0));
mg3d.Positions.Add(new Point3D(-width, -height, 0.0));
mg3d.Positions.Add(new Point3D(width, -height, 0.0));
mg3d.Positions.Add(new Point3D(width, height, 0.0));
double fieldOfViewInRadians = pCamera.FieldOfView * (Math.PI / 180.0);
var z = (width) / Math.Tan(0.5 * fieldOfViewInRadians);
pCamera.Position = new Point3D(0.0, 0.0, z);
You also need to make sure calculate it again if your window size changed. After that, you could do any 3d animation which you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With