Программирование >>  Расширенный wf 

1 ... 10 11 12 [ 13 ] 14 15


<LinearGradientBrush StartPoint= 0,0 EndPoint= 1,1 > <GradientStop Color= Yellow Offset= 0 /> <GradientStop Color= Orange Offset= 0.25 /> <GradientStop Color= Red Offset= 0.50 /> <GradientStop Color= Blue Offset= 0.75 /> <GradientStop Color= Violet Offset= 1 /> </LinearGradientBrush> </DiffuseMaterial.Brush> </DiffuseMaterial>

</MaterialGroup>

</GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> </ModelVisual3D>

Вы можете добавить к материалам текст или другие элементы управления аналогичнкм образом. Чтобы сделать это, нужно просто создать VisualBrush с элементами, которсе вы хотите нарисовать. VisualBrush обсуждается в главе 34.

Трехмерный объект

Теперь обратимся к реальному трехмерному объекту - ящику. Ящик сделан из пяти прямоугольников: задней, передней, левой, правой стенок и дна. Каждый прямоугольник состоит из двух треугольников, потому что именно треугольник - основа сетки. В WPF и 3-D термин сетка (mesh) используется для описания треугольных примитивов, используемых для построения трехмерных фигур.

Ниже приведен код прямоугольника передней стенки ящика, состоящей из двух треугольников. Позиции углов треугольников устанавливаются в порядке против часовой стрелки, как определено в TriangleIndices. Фронтальная поверхность прямоугольника рисуется красной кистью; задняя сторона - серой кистью. Обе эти кисти относятся к типу SolidColorBrush и определены в ресурсах Window.

<!-- Передняя стенка <GeometryModel3D>

<GeometryModel3D.Geometry> <MeshGeometry3D

Positions= -1 -1 1, 1 -1 1, 1 1 1, 1 1 1,

-1 1 1, -1 -1 1

TriangleIndices= 0 1 2, 3 4 5 />

</GeometryModel3D.Geometry> <GeometryModel3D.Material>

<DiffuseMaterial Brush= {StaticResource redBrush} /> </GeometryModel3D.Material> <GeometryModel3D.BackMaterial>

<DiffuseMaterial Brush= {StaticResource grayBrush} />

</GeometryModel3D.BackMaterial> </GeometryModel3D>

Другой прямоугольник очень похож - отличаются только координаты вершин. Ниже показан код XAML левой стенки ящика:

<!-- Левая стенка <GeometryModel3D>

<GeometryModel3D.Geometry> <MeshGeometry3D

Positions= -1 -1 1, -1 1 1, -1 -1 -1, -1 -1 -1, -1 1 1, -1 1 -1

TriangleIndices= 0 1 2, 3 4 5 />

</GeometryModel3D.Geometry>



<GeometryModel3D.Material>

<DiffuseMaterial Brush= {StaticResource redBrush} /> </GeometryModel3D.Material> <GeometryModel3D.BackMaterial>

<DiffuseMaterial Brush= {StaticResource grayBrush} />

</GeometryModel3D.BackMaterial> </GeometryModel3D>

Код примера определяет отдельный объект GeometryModel3D для каждой стенки ящика. Это сделано лишь для того, чтобы код был понятнее. До тех пор, пока один и тот же материал используется для каждой стороны, можно определить сетку, содержащую все 10 треугольников для всех сторон ящика.

Все треугольники комбинируются внутри одной группы Model3DGroup, так что одна трансформация может быть выполнена для всех сторон ящика:

<! - Модель --> <ModelVisual3D>

<ModelVisual3D.Content>

<Model3DGroup>

<!- Элементы GeometryModel3D для каждой стенки ящика -> </Model3DGroup>

Со свойством Transform элемента Model3DGroup все геометрии внутри группы могут быть трансформированы совместно. Ниже приведен пример применения трансформации RotateTransform3D, определенной как AxisAngleRotation3D. Чтобы вращать ящик во время выполнения, свойство Angle привязывается к значению элемента управления Slider.

<!-- Трансформация завершенной модели --> <Model3DGroup.Transform>

<RotateTransform3D CenterX= 0 CenterY= 0 CenterZ= 0 > <RotateTransform3D.Rotation> <AxisAngleRotation3D x:Name= axisRotation Axis= 0, 0, 0

Angle= {Binding Path=Value,

ElementName=axisAngle} />

</RotateTransform3D.Rotation> </RotateTransform3D> </Model3DGroup.Transform>

Чтобы увидеть наш ящик, понадобится камера. Мы используем здесь камеру PerspectiveCamera, чтобы ящик уменьшался по мере удаления от нее. Позиция и ориентация камеры могут быть установлены во время выполнения.

<! - Камера -> <Viewport3D.Camera>

<PerspectiveCamera x:Name= camera Position= {Binding Path=Text,

ElementName=textCameraPosition} LookDirection= {Binding Path=Text,

ElementName=textCameraDirection} /> </Viewport3D.Camera>

Приложение использует два разных источника света. Один из них -DirectionalLight:

<!-- Направленный свет -->

<ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color= White x:Name= directionalLight > <DirectionalLight.Direction> <Vector3D X= 1 Y= 2 Z= 3 />



</DirectionalLight.Direction> </DirectionalLight> </ModelVisual3D.Content> </ModelVisual3D>

Другой источник света - SpotLight. С этим источников света можно подсветить определенную часть ящика. SpotLight определяет свойства InnerConeAngle и OuterConeAngle для задания освещенной области:

<!- Точечн1й свет -->

<ModelVisual3D> <ModelVisual3D.Content>

<SpotLight x:Name= spotLight InnerConeAngle= {Binding Path=Value,

ElementName=spotInnerCone} OuterConeAngle= {Binding Path=Value,

ElementName=spotOuterCone} Color= #FFFFFF

Direction= {Binding Path=Text, ElementName=spotDirection} Position= {Binding Path=Text, ElementName=spotPosition} Range= {Binding Path=Value, ElementName=spotRange} />

</ModelVisual3D.Content> </ModelVisual3D>

При запуске приложения вы можете изменять угол поворота ящика, камеры и источников света, как показано на рис. 35.27.

Создать трехмерную модель, состоящую только из прямоугольников и треугольников, довольно просто. Но более сложные модели вам не придется создавать вручную - для этого можно использовать один из нескольких инструментов. Инструменты 3-D для WPF вы найдете по адресу www.codeplex/3DTools.


Рис. 35.27. Пример приложения с ящиком



1 ... 10 11 12 [ 13 ] 14 15

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика