첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ SphereMeshGenerator.cs

using System;
using System.Windows;
using System.Windows.Media.Media3D;

namespace TestProject
{
    /// <summary>
    /// 구체 메시 제너레이터
    /// </summary>
    public class SphereMeshGenerator
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 슬라이스 수
        /// </summary>
        private int sliceCount = 32;

        /// <summary>
        /// 스택 수
        /// </summary>
        private int stackCount = 16;

        /// <summary>
        /// 중심점
        /// </summary>
        private Point3D centerPoint = new Point3D();

        /// <summary>
        /// 반경
        /// </summary>
        private double radius = 1;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 슬라이스 수 - SliceCount

        /// <summary>
        /// 슬라이스 수
        /// </summary>
        public int SliceCount
        {
            get
            {
                return this.sliceCount;
            }
            set
            {
                this.sliceCount = value;
            }
        }

        #endregion
        #region 스택 수 - StackCount

        /// <summary>
        /// 스택 수
        /// </summary>
        public int StackCount
        {
            set
            {
                this.stackCount = value;
            }
            get
            {
                return this.stackCount;
            }
        }

        #endregion
        #region 중심점 - CenterPoint

        /// <summary>
        /// 중심점
        /// </summary>
        public Point3D CenterPoint
        {
            get
            {
                return this.centerPoint;
            }
            set
            {
                this.centerPoint = value;
            }
        }

        #endregion
        #region 반경 - Radius

        /// <summary>
        /// 반경
        /// </summary>
        public double Radius
        {
            get
            {
                return this.radius;
            }
            set
            {
                this.radius = value;
            }
        }

        #endregion

        #region 도형 - Geometry

        /// <summary>
        /// 도형
        /// </summary>
        public MeshGeometry3D Geometry
        {
            get
            {
                MeshGeometry3D mesh = new MeshGeometry3D();

                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 normalVector = new Vector3D(x, y, z);

                        mesh.Normals.Add(normalVector);

                        mesh.Positions.Add(normalVector + CenterPoint);

                        mesh.TextureCoordinates.Add
                        (
                            new Point
                            (
                                (double)slice / SliceCount,
                                (double)stack / StackCount
                            )
                        );
                    }
                }

                for(int stack = 0; stack < StackCount; stack++)
                {
                    int top    = (stack + 0) * (SliceCount + 1);
                    int bottom = (stack + 1) * (SliceCount + 1);

                    for(int slice = 0; slice < SliceCount; slice++)
                    {
                        if(stack != 0)
                        {
                            mesh.TriangleIndices.Add(top    + slice    );
                            mesh.TriangleIndices.Add(bottom + slice    );
                            mesh.TriangleIndices.Add(top    + slice + 1);
                        }

                        if(stack != StackCount - 1)
                        {
                            mesh.TriangleIndices.Add(top    + slice + 1);
                            mesh.TriangleIndices.Add(bottom + slice    );
                            mesh.TriangleIndices.Add(bottom + slice + 1);
                        }
                    }
                }

                return mesh;
            }
        }

        #endregion
    }
}

 

728x90

 

▶ 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:SphereMeshGenerator x:Key="SphereMeshGeneratorKey"
            CenterPoint="1 0 0"
            Radius="0.5" />
    </Window.Resources>
    <Viewport3D>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup>
                    <GeometryModel3D 
                        Geometry="{Binding Source={StaticResource SphereMeshGeneratorKey}, Path=Geometry}">
                        <GeometryModel3D.Material>
                            <DiffuseMaterial>
                                <DiffuseMaterial.Brush>
                                    <ImageBrush ImageSource="sample.jpg" />
                                </DiffuseMaterial.Brush>
                            </DiffuseMaterial>
                        </GeometryModel3D.Material>
                        <GeometryModel3D.Transform>
                            <RotateTransform3D>
                                <RotateTransform3D.Rotation>
                                    <AxisAngleRotation3D x:Name="axisAngleRotation3D"
                                        Axis="0 1 0" />
                                </RotateTransform3D.Rotation>
                            </RotateTransform3D>
                        </GeometryModel3D.Transform>
                    </GeometryModel3D>
                    <AmbientLight Color="White" />
                </Model3DGroup>
            </ModelVisual3D.Content>
        </ModelVisual3D>
        <Viewport3D.Camera>
            <PerspectiveCamera
                Position="0 0 4"
                LookDirection="0 0 -1"
                UpDirection="0 1 0"
                FieldOfView="45" />
        </Viewport3D.Camera>
    </Viewport3D>
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard
                    TargetName="axisAngleRotation3D"
                    TargetProperty="Angle">
                    <DoubleAnimation
                        From="0"
                        To="360"
                        Duration="0:0:5" 
                        RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
</Window>
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요