Visão geral das transformações 3D
Este tópico descreve como aplicar transformações a modelos 3D no sistema de gráficos do WPF (Windows Presentation Foundation). As transformações permitem que o desenvolvedor reposicione, redimensione e reoriente modelos sem alterar os valores base que os definem.
Espaço de coordenada 3D
O conteúdo de elementos gráficos 3D no WPF (Windows Presentation Foundation) é encapsulado em um elemento, Viewport3D, que pode participar da estrutura de elementos bidimensionais. O sistema gráfico trata Viewport3D como um elemento visual bidimensional como muitos outros no WPF (Windows Presentation Foundation). O Viewport3D funciona como uma janela (um visor) em uma cena tridimensional. Mais precisamente, é uma superfície na qual uma cena 3D é projetada. Embora você possa usar Viewport3D com outros objetos de desenho 2D no mesmo grafo de cena, não é possível interpenetrar objetos 2D e 3D em um Viewport3D. Na discussão a seguir, o espaço de coordenadas descrito está contido no elemento Viewport3D.
O sistema de coordenadas WPF (Windows Presentation Foundation) para elementos gráficos 2D localiza a origem no canto superior esquerdo da superfície de renderização (normalmente a tela). No sistema 2D, os valores positivos do eixo x prossseguem para a direita e os valores positivos do eixo y prossseguem para baixo. No sistema de coordenadas 3D, no entanto, a origem está localizada no centro da tela, com os valores positivos do eixo x se deslocando para a direita, os valores positivos do eixo y se deslocando para cima, e os valores positivos do eixo z se deslocando para fora da origem, em direção ao observador.
Sistemas de coordenadas CoordSystem-1
Comparação do sistema de coordenadas
O espaço definido por esses eixos é o quadro estacionário de referência para objetos 3D no WPF (Windows Presentation Foundation). À medida que você cria modelos nesse espaço e cria luzes e câmeras para visualizá-los, é útil distinguir esse quadro de referência estacionário ou "espaço no mundo", do quadro de referência local que você cria para cada modelo ao aplicar transformações a ele. Lembre-se também de que os objetos no espaço mundial podem parecer totalmente diferentes ou não estar visíveis, dependendo das configurações de luz e câmera, mas a posição da câmera não altera o local dos objetos no espaço mundial.
Transformando modelos
Quando você cria modelos, eles têm uma posição específica na cena. Para mover esses modelos na cena, para girá-los ou para alterar seu tamanho, não é prático alterar os vértices que definem os próprios modelos. Em vez disso, assim como no 2D, você aplica transformações a modelos.
Cada objeto de modelo tem uma propriedade Transform com a qual você pode mover, orientar novamente ou redimensionar o modelo. Ao aplicar uma transformação, você efetivamente desloca todos os pontos do modelo por qualquer vetor ou valor especificado pela transformação. Em outras palavras, você transformou o espaço de coordenadas no qual o modelo é definido ("espaço de modelo"), mas não alterou os valores que compõem a geometria do modelo no sistema de coordenadas de toda a cena ("espaço mundial").
Transformações de tradução
As transformações 3D herdam da classe base abstrata Transform3D; elas incluem as classes de transformação affine TranslateTransform3D, ScaleTransform3De RotateTransform3D. O sistema WPF (Windows Presentation Foundation) 3D também fornece uma classe MatrixTransform3D que permite especificar as mesmas transformações em operações de matriz mais concisas.
TranslateTransform3D move todos os pontos no Model3D na direção do vetor de deslocamento especificado com as propriedades OffsetX, OffsetYe OffsetZ. Por exemplo, dado um vértice de um cubo em (2,2,2), um vetor de deslocamento de (0,1,6,1) moveria esse vértice (2,2,2) para (2,3,6,3). O vértice do cubo ainda está (2,2,2) no espaço do modelo, mas agora esse espaço de modelo mudou sua relação com o espaço mundial para que (2,2,2) no espaço de modelo seja (2,3,6,3) no espaço mundial.
Translação com deslocamento
Os exemplos de código a seguir mostram como aplicar uma tradução.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="600" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="600" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- This ModelVisual3D defines the light cast in the scene. Without light, the
3D object cannot be seen. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
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 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The OffsetX property is animated
in the Storyboard below. -->
<GeometryModel3D.Transform>
<TranslateTransform3D x:Name="myTranslateTransform3D" OffsetX="0" OffsetY="0" OffsetZ="0" />
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the TranslateTransform3D animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the OffsetX property of the TranslateTransform3D. -->
<DoubleAnimation
Storyboard.TargetName="myTranslateTransform3D"
Storyboard.TargetProperty="OffsetX"
To="-0.8"
AutoReverse="True" RepeatBehavior="Forever" />
<!-- If you want to animate OffsetY and/or OffsetZ, create similar DoubleAnimations
respectively. -->
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Transformações de escala
ScaleTransform3D altera a escala do modelo por um vetor de escala especificado com referência a um ponto central. Especifique uma escala uniforme, que dimensiona o modelo pelo mesmo valor nos eixos X, Y e Z, para alterar proporcionalmente o tamanho do modelo. Por exemplo, definir as propriedades ScaleX, ScaleYe ScaleZ da transformação como 0,5 reduz pela metade o tamanho do modelo; definir as mesmas propriedades como 2 dobra sua escala em todos os três eixos.
Exemplo de ScaleVector
Ao especificar uma transformação de escala não uniforme , uma transformação de escala cujos valores X, Y e Z não são todos iguais, você pode fazer com que um modelo estique ou contraia em uma ou duas dimensões sem afetar as outras. Por exemplo, definir ScaleX como 1, ScaleY para 2 e ScaleZ para 1 faria com que o modelo transformado dobrasse de altura, mas permanecesse inalterado ao longo dos eixos X e Z.
Por padrão, ScaleTransform3D faz com que os vértices expandam ou contraam sobre a origem (0,0,0). Se o modelo que você deseja transformar não for extraído da origem, no entanto, dimensionar o modelo da origem não dimensionará o modelo "in-loco". Em vez disso, quando os vértices do modelo forem multiplicados pelo vetor de escala, a operação de escala terá o efeito de traduzir o modelo, bem como dimensioná-lo.
Exemplo de centro de escala
Para dimensionar um modelo "no local", especifique o centro do modelo definindo as propriedades CenterX, CenterYe CenterZ do ScaleTransform3D. Isso garante que o sistema de elementos gráficos ajusta a escala do espaço do modelo e, em seguida, translada-o para o centro, no Point3D especificado. Por outro lado, se você tiver criado o modelo sobre a origem e especificar um ponto central diferente, observe que o modelo será movido para longe da origem.
Transformações de rotação
Você pode girar um modelo em 3D de várias maneiras diferentes. Uma transformação de rotação típica especifica um eixo e um ângulo de rotação em torno desse eixo. A classe RotateTransform3D permite que você defina um Rotation3D com sua propriedade Rotation. Em seguida, especifique as propriedades Axis e Angle do Rotation3D, nesse caso, um AxisAngleRotation3D, para definir a transformação. Os exemplos a seguir giram um modelo em 60 graus em torno do eixo Y.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="321" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="150" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- Two ModelVisual3D define the lights cast in the scene. Without light, the
3D object cannot be seen. Also, the direction of the lights affect shadowing. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
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 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Yellow" Offset="0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The properties of the
Rotation object are animated causing the 3D object to rotate and "wobble" (see Storyboard below).-->
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="myAngleRotation" Axis="0,3,0" Angle="40" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the rotation animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the Angle property of the AxisAngleRotation3D
making the 3D object rotate from -60 degrees to 60 degrees. -->
<DoubleAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Angle"
From="-60" To="60" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
<!-- This animation animates the Axis property of the AxisAngleRotation3D
making the 3D wobble as it rotates. -->
<Vector3DAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Axis"
From="0,3,0" To="1,0,1" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Observação: o 3D do WPF (Windows Presentation Foundation) é um sistema destro, o que significa que um valor positivo de ângulo para uma rotação resulta em uma rotação no sentido anti-horário sobre o eixo.
Rotações de ângulo de eixo pressupõem rotação sobre a origem se um valor não for especificado para as propriedades CenterX, CenterYe CenterZ em RotateTransform3D. Assim como no dimensionamento, é útil lembrar que a rotação transforma todo o espaço de coordenadas do modelo. Se o modelo não tiver sido criado em torno da origem ou tiver sido traduzido anteriormente, a rotação poderá "pivotar" em torno da origem em vez de girar no próprio lugar.
rotação com o novo ponto de centro
Rotação com o novo centro especificado
Para girar o modelo "no local," especifique o centro real do modelo como o centro de rotação. Como a geometria normalmente é modelada sobre a origem, você geralmente pode obter o resultado esperado de um conjunto de transformações dimensionando primeiro o modelo (dimensionando-o), depois definindo sua orientação (girando-o) e, finalmente, movendo-o para o local desejado (traduzindo-o).
Exemplo de rotação
As rotações de ângulo de eixo funcionam bem para transformações estáticas e algumas animações. No entanto, considere girar um modelo de cubo 60 graus em torno do eixo X e, em seguida, 45 graus em torno do eixo Z. Você pode descrever essa transformação como duas transformações de afim discretas ou como uma matriz. No entanto, pode ser difícil animar suavemente uma rotação definida dessa forma. Embora as posições inicial e final do modelo computadas por qualquer abordagem sejam as mesmas, as posições intermediárias tomadas pelo modelo são computacionalmente incertas. Quatérnios representam uma maneira alternativa de calcular a interpolação entre o início e o fim de uma rotação.
Um quatérnio representa um eixo no espaço 3D e uma rotação em torno desse eixo. Por exemplo, um quatérnio pode representar um eixo (1,1,2) e uma rotação de 50 graus. O poder dos quatérnios na definição de rotações vem das duas operações que você pode executar nelas: composição e interpolação. A composição de dois quatérnios aplicados a uma geometria significa "girar a geometria em torno do eixo2 por rotação2 e, em seguida, girá-la em torno do eixo1 por rotação1". Usando a composição, você pode combinar as duas rotações na geometria para obter um único quatérnio que represente o resultado. Como a interpolação de quatérnions pode calcular um caminho suave e razoável de um eixo e de uma orientação à outra, é possível interpolar do quatérnion original para o composto para alcançar uma transição suave de um para outro, permitindo que você anime a transformação. Para os modelos que você deseja animar, é possível especificar um destino Quaternion para a rotação usando um QuaternionRotation3D para a propriedade Rotation.
Usando coleções de transformações
Ao criar uma cena, é comum aplicar mais de uma transformação a um modelo. Adicione transformações à coleção Children da classe Transform3DGroup para agrupar transformações convenientemente para aplicar a vários modelos na cena. Geralmente, é conveniente reutilizar uma transformação em vários grupos diferentes, da mesma forma que você pode reutilizar um modelo aplicando um conjunto diferente de transformações a cada instância. Observe que a ordem na qual as transformações são adicionadas à coleção é significativa: as transformações na coleção são aplicadas do primeiro ao último.
Animando transformações
A implementação do WPF (Windows Presentation Foundation) 3D participa do mesmo sistema de tempo e animação que os gráficos 2D. Em outras palavras, para animar uma cena 3D, anime as propriedades dos modelos dela. É possível animar as propriedades dos primitivos diretamente, mas normalmente é mais fácil animar transformações que alteram a posição ou a aparência dos modelos. Como as transformações podem ser aplicadas a objetos Model3DGroup, bem como a modelos individuais, é possível aplicar um conjunto de animações aos filhos de um Model3Dgroup e outro conjunto de animações a um grupo de objetos. Para obter informações sobre o sistema de tempo e animação do WPF (Windows Presentation Foundation), consulte Visão geral da animação e Visão geral dos storyboards.
Para animar um objeto no WPF (Windows Presentation Foundation), criar uma linha do tempo, definir uma animação (que é realmente uma alteração em algum valor de propriedade ao longo do tempo) e especificar a propriedade à qual aplicar a animação. Essa propriedade deve ser uma propriedade de um FrameworkElement. Como todos os objetos em uma cena 3D são filhos do 3D, as propriedades direcionadas por qualquer animação que você deseja aplicar à cena são propriedades das propriedades do Viewport3D. É importante preparar o caminho da propriedade para a animação cuidadosamente, porque a sintaxe pode ser detalhada.
Suponha que você queira girar um objeto no local, mas também aplicar um movimento de oscilação para expor mais do objeto a ser exibido. Você pode optar por aplicar um RotateTransform3D ao modelo e animar o eixo de sua rotação de um vetor para outro. O exemplo de código a seguir demonstra a aplicação de uma Vector3DAnimation à propriedade do Eixo da Rotation3D da transformação, supondo que a RotateTransform3D seja uma das várias transformações aplicadas ao modelo com um TransformGroup.
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
'Define a rotation
Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
Use uma sintaxe semelhante para direcionar outras propriedades de transformação para mover ou dimensionar o objeto. Por exemplo, você pode aplicar um Point3DAnimation à propriedade ScaleCenter em uma transformação de escala para fazer com que um modelo distorça suavemente sua forma.
Embora os exemplos anteriores transformem as propriedades de GeometryModel3D, também é possível transformar as propriedades de outros modelos na cena. Ao animar traduções aplicadas a objetos Light, por exemplo, você pode criar efeitos de luz e sombra móveis que podem alterar drasticamente a aparência de seus modelos.
Como as câmeras também são modelos, também é possível transformar as propriedades da câmera. Embora você certamente possa alterar a aparência da cena transformando a localização da câmera ou as distâncias do plano, na verdade, transformando toda a projeção de cena, observe que muitos dos efeitos que você obtém dessa maneira podem não fazer tanto "sentido visual" para o visualizador quanto as transformações aplicadas ao local ou à posição dos modelos na cena.
Consulte também
- Visão geral dos gráficos 3D
- Visão geral de transformações
- Exemplo de Transformações 2D
.NET Desktop feedback