Pages

Saturday 3 December 2011

3D VisualBrush and TextureCoordinates

This post starts with the last example from the 3D Towards a Solid post.
The previous examples all used a single colour for the Material applied to a surface.
This example replaces the Brush with a StackPanel containing a TextBlock and Button.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>

                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Front!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>

                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
At this point the front of the cube will be transparent and the TextBlock and Button will not appear. We need to add TextCoordinates to map the VisualBrush to the Mesh.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>

                     <MeshGeometry3D.TextureCoordinates>0,1 1,1 1,0 0,0</MeshGeometry3D.TextureCoordinates>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Front!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
To apply the texture to the "back" of the we need to "flip" the TextureCoordinates horizontally around the Y axis to match the way we previously changed the TriangleIndices.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>

                     <MeshGeometry3D.TextureCoordinates>1,1 0,1 0,0 1,0</MeshGeometry3D.TextureCoordinates>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Back!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                     <MeshGeometry3D.TextureCoordinates>0,1 1,1 1,0 0,0</MeshGeometry3D.TextureCoordinates>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Front!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>

No comments: