728x90
반응형
728x170
▶ MeshGeneratorBase.cs
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
namespace TestProject
{
/// <summary>
/// 메쉬 제너레이터 베이스
/// </summary>
[RuntimeNameProperty("Name")]
public abstract class MeshGeneratorBase : Animatable
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 도형 키
/// </summary>
private static DependencyPropertyKey GeometryKey = DependencyProperty.RegisterReadOnly
(
"Geometry",
typeof(MeshGeometry3D),
typeof(MeshGeneratorBase),
new PropertyMetadata(new MeshGeometry3D())
);
#endregion
//////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 명칭 속성
/// </summary>
public static readonly DependencyProperty NameProperty = DependencyProperty.Register
(
"Name",
typeof(string),
typeof(MeshGeneratorBase)
);
/// <summary>
/// 도형 속성
/// </summary>
public static readonly DependencyProperty GeometryProperty = GeometryKey.DependencyProperty;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 명칭 - Name
/// <summary>
/// 명칭
/// </summary>
public string Name
{
set
{
SetValue(NameProperty, value);
}
get
{
return (string)GetValue(NameProperty);
}
}
#endregion
#region 도형 - Geometry
/// <summary>
/// 도형
/// </summary>
public MeshGeometry3D Geometry
{
get
{
return (MeshGeometry3D)GetValue(GeometryProperty);
}
protected set
{
SetValue(GeometryKey, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MeshGeneratorBase()
/// <summary>
/// 생성자
/// </summary>
public MeshGeneratorBase()
{
Geometry = new MeshGeometry3D();
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Protected
#region 속성 변경시 처리하기 - PropertyChanged(d, e)
/// <summary>
/// 속성 변경시 처리하기
/// </summary>
/// <param name="d">의존 객체</param>
/// <param name="e">이벤트 인자</param>
protected static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MeshGeneratorBase).PropertyChanged(e);
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Protected
#region 삼각형 구성하기 - Triangulate(e, vertexCollection, normalCollection, indexCollection, textureCollection)
/// <summary>
/// 삼각형 구성하기
/// </summary>
/// <param name="e">이벤트 인자</param>
/// <param name="vertexCollection">꼭지점 컬렉션</param>
/// <param name="normalCollection">법선 컬렉션</param>
/// <param name="indexCollection">인덱스 컬렉션</param>
/// <param name="textureCollection">텍스쳐 컬렉션</param>
protected abstract void Triangulate(DependencyPropertyChangedEventArgs e, Point3DCollection vertexCollection,
Vector3DCollection normalCollection, Int32Collection indexCollection, PointCollection textureCollection);
#endregion
#region 속성 변경시 처리하기 - PropertyChanged(e)
/// <summary>
/// 속성 변경시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected virtual void PropertyChanged(DependencyPropertyChangedEventArgs e)
{
MeshGeometry3D mesh = Geometry;
Point3DCollection vertexCollection = mesh.Positions;
Vector3DCollection normalCollection = mesh.Normals;
Int32Collection indexCollection = mesh.TriangleIndices;
PointCollection textureCollection = mesh.TextureCoordinates;
mesh.Positions = null;
mesh.Normals = null;
mesh.TriangleIndices = null;
mesh.TextureCoordinates = null;
Triangulate(e, vertexCollection, normalCollection, indexCollection, textureCollection);
mesh.TextureCoordinates = textureCollection;
mesh.TriangleIndices = indexCollection;
mesh.Normals = normalCollection;
mesh.Positions = vertexCollection;
}
#endregion
}
}
728x90
▶ CylindricalMeshBase.cs
using System.Windows;
namespace TestProject
{
/// <summary>
/// 실린더 메쉬 베이스
/// </summary>
public abstract class CylindricalMeshBase : MeshGeneratorBase
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 길이 속성
/// </summary>
public static readonly DependencyProperty LengthProperty = DependencyProperty.Register
(
"Length",
typeof(double),
typeof(CylindricalMeshBase),
new PropertyMetadata(1.0, PropertyChanged)
);
/// <summary>
/// 반경
/// </summary>
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register
(
"Radius",
typeof(double),
typeof(CylindricalMeshBase),
new PropertyMetadata(1.0, PropertyChanged)
);
/// <summary>
/// 슬라이스 수 속성
/// </summary>
public static readonly DependencyProperty SliceCountProperty = DependencyProperty.Register
(
"SliceCount",
typeof(int),
typeof(CylindricalMeshBase),
new PropertyMetadata(36, PropertyChanged),
ValidateSliceCount
);
/// <summary>
/// 스택 수 속성
/// </summary>
public static readonly DependencyProperty StackCountProperty = DependencyProperty.Register
(
"StackCount",
typeof(int),
typeof(CylindricalMeshBase),
new PropertyMetadata(1, PropertyChanged),
ValidateStackCount
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 길이 - Length
/// <summary>
/// 길이
/// </summary>
public double Length
{
set
{
SetValue(LengthProperty, value);
}
get
{
return (double)GetValue(LengthProperty);
}
}
#endregion
#region 반경 - Radius
/// <summary>
/// 반경
/// </summary>
public double Radius
{
set
{
SetValue(RadiusProperty, value);
}
get
{
return (double)GetValue(RadiusProperty);
}
}
#endregion
#region 슬라이스 수 - SliceCount
/// <summary>
/// 슬라이스 수
/// </summary>
public int SliceCount
{
set
{
SetValue(SliceCountProperty, value);
}
get
{
return (int)GetValue(SliceCountProperty);
}
}
#endregion
#region 스택 수 - StackCount
/// <summary>
/// 스택 수
/// </summary>
public int StackCount
{
set
{
SetValue(StackCountProperty, value);
}
get
{
return (int)GetValue(StackCountProperty);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 슬라이스 수 무결성 체크하기 - ValidateSliceCount(sourceObject)
/// <summary>
/// 슬라이스 수 무결성 체크하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>처리 결과</returns>
private static bool ValidateSliceCount(object sourceObject)
{
return (int)sourceObject > 2;
}
#endregion
#region 스택 수 무결성 체크하기 - ValidateStackCount(sourceObject)
/// <summary>
/// 스택 수 무결성 체크하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>처리 결과</returns>
private static bool ValidateStackCount(object sourceObject)
{
return (int)sourceObject > 0;
}
#endregion
}
}
300x250
▶ SphereMesh.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
namespace TestProject
{
/// <summary>
/// 구체 메쉬
/// </summary>
public class SphereMesh : MeshGeneratorBase
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 중심점 속성
/// </summary>
public static readonly DependencyProperty CenterPointProperty = DependencyProperty.Register
(
"CenterPoint",
typeof(Point3D),
typeof(SphereMesh),
new PropertyMetadata(new Point3D(), PropertyChanged)
);
/// <summary>
/// 반경 속성
/// </summary>
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register
(
"Radius",
typeof(double),
typeof(SphereMesh),
new PropertyMetadata(1.0, PropertyChanged)
);
/// <summary>
/// 슬라이스 수 속성
/// </summary>
public static readonly DependencyProperty SliceCountProperty = DependencyProperty.Register
(
"SliceCount",
typeof(int),
typeof(SphereMesh),
new PropertyMetadata(36, PropertyChanged),
ValidateSliceCount
);
/// <summary>
/// 스택 수 속성
/// </summary>
public static readonly DependencyProperty StackCountProperty = DependencyProperty.Register
(
"StackCount",
typeof(int),
typeof(SphereMesh),
new PropertyMetadata(18, PropertyChanged),
ValidateStackCount
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 중심점 - CenterPoint
/// <summary>
/// 중심점
/// </summary>
public Point3D CenterPoint
{
set
{
SetValue(CenterPointProperty, value);
}
get
{
return (Point3D)GetValue(CenterPointProperty);
}
}
#endregion
#region 반경 - Radius
/// <summary>
/// 반경
/// </summary>
public double Radius
{
set
{
SetValue(RadiusProperty, value);
}
get
{
return (double)GetValue(RadiusProperty);
}
}
#endregion
#region 슬라이스 수 - SliceCount
/// <summary>
/// 슬라이스 수
/// </summary>
public int SliceCount
{
set
{
SetValue(SliceCountProperty, value);
}
get
{
return (int)GetValue(SliceCountProperty);
}
}
#endregion
#region 스택 수 - StackCount
/// <summary>
/// 스택 수
/// </summary>
public int StackCount
{
set
{
SetValue(StackCountProperty, value);
}
get
{
return (int)GetValue(StackCountProperty);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - SphereMesh()
/// <summary>
/// 생성자
/// </summary>
public SphereMesh()
{
PropertyChanged(new DependencyPropertyChangedEventArgs());
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 슬라이스 수 무결성 체크하기 - ValidateSliceCount(sourceObject)
/// <summary>
/// 슬라이스 수 무결성 체크하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>처리 결과</returns>
private static bool ValidateSliceCount(object sourceObject)
{
return (int)sourceObject > 2;
}
#endregion
#region 스택 수 무결성 체크하기 - ValidateStackCount(sourceObject)
/// <summary>
/// 스택 수 무결성 체크하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>처리 결과</returns>
private static bool ValidateStackCount(object sourceObject)
{
return (int)sourceObject > 1;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Protected
#region 삼각형 구성하기 - Triangulate(e, vertexCollection, normalCollection, indexCollection, textureCollection)
/// <summary>
/// 삼각형 구성하기
/// </summary>
/// <param name="e">이벤트 인자</param>
/// <param name="vertexCollection">꼭지점 컬렉션</param>
/// <param name="normalCollection">법선 컬렉션</param>
/// <param name="indexCollection">인덱스 컬렉션</param>
/// <param name="textureCollection">텍스처 컬렉션</param>
protected override void Triangulate(DependencyPropertyChangedEventArgs e, Point3DCollection vertexCollection,
Vector3DCollection normalCollection, Int32Collection indexCollection, PointCollection textureCollection)
{
vertexCollection.Clear();
normalCollection.Clear();
indexCollection.Clear();
textureCollection.Clear();
for(int stack = 0; stack <= StackCount; stack++)
{
double phi = Math.PI / 2 - stack * Math.PI / StackCount;
double y = Radius * Math.Sin(phi);
double scale = -Radius * Math.Cos(phi);
for(int slice = 0; slice <= SliceCount; slice++)
{
double theta = slice * 2 * Math.PI / SliceCount;
double x = scale * Math.Sin(theta);
double z = scale * Math.Cos(theta);
Vector3D normal = new Vector3D(x, y, z);
normalCollection.Add(normal);
vertexCollection.Add(normal + CenterPoint);
textureCollection.Add(new Point((double)slice / SliceCount, (double)stack / StackCount));
}
}
for(int stack = 0; stack < StackCount; stack++)
{
for(int slice = 0; slice < SliceCount; slice++)
{
if(stack != 0)
{
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice + 1);
}
if(stack != StackCount - 1)
{
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice + 1);
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice + 1);
}
}
}
}
#endregion
#region 인스턴스 생성하기 (코어) - CreateInstanceCore()
/// <summary>
/// 인스턴스 생성하기 (코어)
/// </summary>
/// <returns>인스턴스</returns>
protected override Freezable CreateInstanceCore()
{
return new SphereMesh();
}
#endregion
}
}
▶ HollowCylinderMesh.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
namespace TestProject
{
/// <summary>
/// 빈 실린더 메쉬
/// </summary>
public class HollowCylinderMesh : CylindricalMeshBase
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - HollowCylinderMesh()
/// <summary>
/// 생성자
/// </summary>
public HollowCylinderMesh()
{
PropertyChanged(new DependencyPropertyChangedEventArgs());
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 삼각형 구성하기 - Triangulate(e, vertexCollection, normalCollection, indexCollection, textureCollection)
/// <summary>
/// 삼각형 구성하기
/// </summary>
/// <param name="e">이벤트 인자</param>
/// <param name="vertexCollection">꼭지점 컬렉션</param>
/// <param name="normalCollection">법선 컬렉션</param>
/// <param name="indexCollection">인덱스 컬렉션</param>
/// <param name="textureCollection">텍스처 컬렉션</param>
protected override void Triangulate(DependencyPropertyChangedEventArgs e, Point3DCollection vertexCollection,
Vector3DCollection normalCollection, Int32Collection indexCollection, PointCollection textureCollection)
{
vertexCollection.Clear();
normalCollection.Clear();
indexCollection.Clear();
textureCollection.Clear();
for(int stack = 0; stack <= StackCount; stack++)
{
double y = Length - stack * Length / StackCount;
for(int slice = 0; slice <= SliceCount; slice++)
{
double theta = slice * 2 * Math.PI / SliceCount;
double x = -Radius * Math.Sin(theta);
double z = -Radius * Math.Cos(theta);
normalCollection.Add(new Vector3D(x, 0, z));
vertexCollection.Add(new Point3D(x, y, z));
textureCollection.Add(new Point((double)slice / SliceCount, (double)stack / StackCount));
}
}
for(int stack = 0; stack < StackCount; stack++)
{
for(int slice = 0; slice < SliceCount; slice++)
{
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice + 1);
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice + 1);
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice + 1);
}
}
}
#endregion
#region 인스턴스 생성하기 (코어) - CreateInstanceCore()
/// <summary>
/// 인스턴스 생성하기 (코어)
/// </summary>
/// <returns>인스턴스</returns>
protected override Freezable CreateInstanceCore()
{
return new HollowCylinderMesh();
}
#endregion
}
}
▶ TorusMesh.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
namespace TestProject
{
/// <summary>
/// 원환체 메쉬
/// </summary>
public class TorusMesh : MeshGeneratorBase
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 반경 속성
/// </summary>
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register
(
"Radius",
typeof(double),
typeof(TorusMesh),
new PropertyMetadata(1.0, PropertyChanged)
);
/// <summary>
/// 튜브 반경 속성
/// </summary>
public static readonly DependencyProperty TubeRadiusProperty = DependencyProperty.Register
(
"TubeRadius",
typeof(double),
typeof(TorusMesh),
new PropertyMetadata(0.25, PropertyChanged)
);
/// <summary>
/// 슬라이스 수 속성
/// </summary>
public static readonly DependencyProperty SliceCountProperty = DependencyProperty.Register
(
"SliceCount",
typeof(int),
typeof(TorusMesh),
new PropertyMetadata(18, PropertyChanged),
ValidateSliceCount
);
/// <summary>
/// 스택 수 속성
/// </summary>
public static readonly DependencyProperty StackCountProperty = DependencyProperty.Register
(
"StackCount",
typeof(int),
typeof(TorusMesh),
new PropertyMetadata(36, PropertyChanged),
ValidateStackCount
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 반경 - Radius
/// <summary>
/// 반경
/// </summary>
public double Radius
{
set
{
SetValue(RadiusProperty, value);
}
get
{
return (double)GetValue(RadiusProperty);
}
}
#endregion
#region 튜브 반경 - TubeRadius
/// <summary>
/// 튜브 반경
/// </summary>
public double TubeRadius
{
set
{
SetValue(TubeRadiusProperty, value);
}
get
{
return (double)GetValue(TubeRadiusProperty);
}
}
#endregion
#region 슬라이스 수 - SliceCount
/// <summary>
/// 슬라이스 수
/// </summary>
public int SliceCount
{
set
{
SetValue(SliceCountProperty, value);
}
get
{
return (int)GetValue(SliceCountProperty);
}
}
#endregion
#region 스택 수 - StackCount
/// <summary>
/// 스택 수
/// </summary>
public int StackCount
{
set
{
SetValue(StackCountProperty, value);
}
get
{
return (int)GetValue(StackCountProperty);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - TorusMesh()
/// <summary>
/// 생성자
/// </summary>
public TorusMesh()
{
PropertyChanged(new DependencyPropertyChangedEventArgs());
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 슬라이스 수 무결성 체크하기 - ValidateSliceCount(sourceObject)
/// <summary>
/// 슬라이스 수 무결성 체크하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>처리 결과</returns>
private static bool ValidateSliceCount(object sourceObject)
{
return (int)sourceObject > 2;
}
#endregion
#region 스택 수 무결성 체크하기 - ValidateStackCount(sourceObject)
/// <summary>
/// 스택 수 무결성 체크하기
/// </summary>
/// <param name="sourceObject">소스 객체</param>
/// <returns>처리 결과</returns>
private static bool ValidateStackCount(object sourceObject)
{
return (int)sourceObject > 2;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Protected
#region 삼각형 구성하기 - Triangulate(e, vertexCollection, normalCollection, indexCollection, textureCollection)
/// <summary>
/// 삼각형 구성하기
/// </summary>
/// <param name="e">이벤트 인자</param>
/// <param name="vertexCollection">꼭지점 컬렉션</param>
/// <param name="normalCollection">법선 컬렉션</param>
/// <param name="indexCollection">인덱스 컬렉션</param>
/// <param name="textureCollection">텍스처 컬렉션</param>
protected override void Triangulate(DependencyPropertyChangedEventArgs e, Point3DCollection vertexCollection,
Vector3DCollection normalCollection, Int32Collection indexCollection, PointCollection textureCollection)
{
vertexCollection.Clear();
normalCollection.Clear();
indexCollection.Clear();
textureCollection.Clear();
for(int stack = 0; stack <= StackCount; stack++)
{
double phi = stack * 2 * Math.PI / StackCount;
double xCenter = Radius * Math.Sin(phi);
double yCenter = Radius * Math.Cos(phi);
Point3D centerPoint = new Point3D(xCenter, yCenter, 0);
for(int slice = 0; slice <= SliceCount; slice++)
{
double theta = slice * 2 * Math.PI / SliceCount + Math.PI;
double x = (Radius + TubeRadius * Math.Cos(theta)) * Math.Sin(phi);
double y = (Radius + TubeRadius * Math.Cos(theta)) * Math.Cos(phi);
double z = -TubeRadius * Math.Sin(theta);
Point3D point = new Point3D(x, y, z);
vertexCollection.Add(point);
normalCollection.Add(point - centerPoint);
textureCollection.Add(new Point((double)slice / SliceCount, (double)stack / StackCount));
}
}
for(int stack = 0; stack < StackCount; stack++)
{
for(int slice = 0; slice < SliceCount; slice++)
{
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice + 1);
indexCollection.Add((stack + 0) * (SliceCount + 1) + slice + 1);
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice );
indexCollection.Add((stack + 1) * (SliceCount + 1) + slice + 1);
}
}
}
#endregion
#region 인스턴스 생성하기 (코어) - CreateInstanceCore()
/// <summary>
/// 인스턴스 생성하기 (코어)
/// </summary>
/// <returns>인스턴스</returns>
protected override Freezable CreateInstanceCore()
{
return new TorusMesh();
}
#endregion
}
}
▶ MainWindow.xaml
<Window x:Class="TestProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestProject"
Width="800"
Height="600"
Title="MeshGeometry3D 클래스 : 수레바퀴 만들기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Window.Resources>
<local:SphereMesh x:Key="hubSphereMeshKey"
Radius="0.2" />
<local:HollowCylinderMesh x:Key="spokeHollowCylinderMeshKey"
Radius="0.03"
Length="1" />
<local:TorusMesh x:Key="tireTorusMeshKey"
Radius="1"
TubeRadius="0.2"
SliceCount="144"
StackCount="96" />
<DiffuseMaterial x:Key="steelDiffuseMaterialKey"
Brush="SteelBlue" />
<DiffuseMaterial x:Key="tireDiffuseMaterialKey"
Brush="DarkGray" />
<Model3DGroup x:Key="spokeModel3DGroupKey">
<GeometryModel3D
Geometry="{Binding Source={StaticResource spokeHollowCylinderMeshKey}, Path=Geometry}"
Material="{StaticResource steelDiffuseMaterialKey}" />
<GeometryModel3D
Geometry="{Binding Source={StaticResource spokeHollowCylinderMeshKey}, Path=Geometry}"
Material="{StaticResource steelDiffuseMaterialKey}">
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 0 -1"
Angle="30" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
<GeometryModel3D
Geometry="{Binding Source={StaticResource spokeHollowCylinderMeshKey}, Path=Geometry}"
Material="{StaticResource steelDiffuseMaterialKey}">
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 0 -1"
Angle="60" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</Model3DGroup>
<Model3DGroup x:Key="wheelModel3DGroupKey">
<GeometryModel3D
Geometry="{Binding Source={StaticResource hubSphereMeshKey}, Path=Geometry}"
Material="{StaticResource steelDiffuseMaterialKey}" />
<StaticResource ResourceKey="spokeModel3DGroupKey" />
<Model3DGroup>
<StaticResource ResourceKey="spokeModel3DGroupKey" />
<Model3DGroup.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 0 -1"
Angle="90" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Model3DGroup.Transform>
</Model3DGroup>
<Model3DGroup>
<StaticResource ResourceKey="spokeModel3DGroupKey" />
<Model3DGroup.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 0 -1"
Angle="180" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Model3DGroup.Transform>
</Model3DGroup>
<Model3DGroup>
<StaticResource ResourceKey="spokeModel3DGroupKey" />
<Model3DGroup.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 0 -1"
Angle="270" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Model3DGroup.Transform>
</Model3DGroup>
<GeometryModel3D
Geometry="{Binding Source={StaticResource tireTorusMeshKey}, Path=Geometry}"
Material="{StaticResource tireDiffuseMaterialKey}" />
</Model3DGroup>
</Window.Resources>
<Viewport3D>
<ModelVisual3D Content="{StaticResource wheelModel3DGroupKey}">
<ModelVisual3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="axisAngleRotation3D"
Axis="0 0 -1" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</ModelVisual3D.Transform>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<AmbientLight Color="#404040" />
<DirectionalLight
Color="#C0C0C0"
Direction="2 -3 -1" />
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport3D.Camera>
<PerspectiveCamera
Position="-4 0 4"
LookDirection="4 0 -4"
UpDirection="0 1 0"
FieldOfView="45" />
</Viewport3D.Camera>
</Viewport3D>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="axisAngleRotation3D"
Storyboard.TargetProperty="Angle"
From="0"
To="360"
Duration="0:0:5"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
</Window>
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] Canvas 클래스 : 사용자 선 그리기 (0) | 2020.07.05 |
---|---|
[C#/WPF] WindowInteropHelper 클래스 : Handle 속성을 사용해 윈도우 핸들 구하기 (0) | 2020.05.20 |
[C#/WPF] Application 클래스 : Shutdown 메소드를 사용해 애플리케이션 종료하기 (0) | 2020.02.29 |
[C#/WPF] MeshGeometry3D 클래스 : 구체 애니메이션 만들기 (0) | 2019.09.08 |
[C#/WPF] NAUDIO 라이브러리를 사용해 음악 재생하기 (0) | 2019.09.08 |
[C#/WPF] ModelVisual3D 클래스 상속하기 (0) | 2019.09.01 |
[C#/WPF] object 객체에서 XAML 구하기 (0) | 2019.09.01 |
[C#/WPF] MeshGeometry3D 클래스 : 리소스 사용하기 (0) | 2019.09.01 |
[C#/WPF] MeshGeometry3D 클래스 : 리소스 사용하기 (0) | 2019.08.28 |
[C#/WPF] MeshGeometry3D 클래스 : 삼각측량법을 사용해 비치볼 만들기 (0) | 2019.08.27 |
댓글을 달아 주세요