
前田稔(Maeda Minoru)の超初心者のプログラム入門
![]()
![]()
/****************************************************/
/*★ Interpolator でティーポットを回転    前田 稔 ★*/
/****************************************************/
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D=Microsoft.DirectX.Direct3D;
using System.Collections;
namespace Anime
{
    public class Meshes : Form
    {
        Device device = null;       // Our rendering device
        Mesh mesh = null;           // Our mesh object in sysmem
        PresentParameters presentParams = new PresentParameters();
        bool pause = false;
        InterRot    interrot;       //Interpolator の定義
        //回転情報の定義
        InterRotDat[]   Rot =
        {   new InterRotDat(0,new Quaternion(0.0f,0.0f,0.0f,1.0f)),
            new InterRotDat(100,new Quaternion(0.0f,0.72f,0.0f,0.70f)),
            new InterRotDat(200,new Quaternion(0.0f,1.00f,0.0f,0.02f)),
            new InterRotDat(300,new Quaternion(0.0f,-0.71f,0.0f,0.70f)),
            new InterRotDat(400,new Quaternion(0.0f,0.0f,0.0f,1.0f))
        };
        int     tim= 0;
        Matrix  mat;
        //Constructor
        public Meshes()
        {   // Set the initial size of our form
            this.ClientSize = new System.Drawing.Size(400, 400);
            this.Text = "Direct3D Teapot";
            interrot = new InterRot(Rot);
        }
        //D3DDevice の取得
        bool InitializeGraphics()
        {
            try
            {   presentParams.Windowed = true;
                presentParams.SwapEffect = SwapEffect.Discard;
                presentParams.EnableAutoDepthStencil = true;
                presentParams.AutoDepthStencilFormat = DepthFormat.D16;
                // Create the D3DDevice
                device = new Device(0, DeviceType.Hardware, this,
                    CreateFlags.SoftwareVertexProcessing, presentParams);
                device.DeviceReset += new System.EventHandler(this.OnResetDevice);
                this.OnResetDevice(device, null);
                pause = false;
            }
            catch (DirectXException)
            {   return false;  }
            return true;
        }
        //Direct3D の初期化
        public void OnResetDevice(object sender, EventArgs e)
        {
            Device dev = (Device)sender;
            dev.RenderState.ZBufferEnable = true;  // Turn on the zbuffer
            device.RenderState.Lighting = true;    //make sure lighting is enabled
            //ティーポットの生成
            mesh = Mesh.Teapot(device);
        }
        //描画環境の設定
        void SetupMatrices()
        {
            mat= interrot.GetMat(tim);
            device.Transform.World = mat;
            device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f,2.0f,-5.0f),
                new Vector3(0.0f,0.0f,0.0f), new Vector3(0.0f,1.0f,0.0f));
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI/4),
                (float)this.Width / (float)this.Height, 1.0f, 500.0f);
        }
        //ライトの設定
        private void SetupLights()
        {
            System.Drawing.Color col = System.Drawing.Color.White;
            Direct3D.Material mtrl = new Direct3D.Material();
            mtrl.Diffuse = col;
            mtrl.Ambient = col;
            device.Material = mtrl;
            
            device.Lights[0].Type = LightType.Directional;
            device.Lights[0].Diffuse = System.Drawing.Color.FromArgb(0xF0F020);
            //ライトの座標
            device.Lights[0].Direction = new Vector3(50.0f, -40.0f, 100.0f);
            device.Lights[0].Enabled = true;
            device.RenderState.Ambient = System.Drawing.Color.FromArgb(0x202020);
        }
        //モデルの描画
        private void Render()
        {   if (device == null) return;
            if (pause)          return;
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Blue, 1.0f, 0);
            device.BeginScene();
            SetupLights();
            SetupMatrices();
            mesh.DrawSubset(0);
            device.EndScene();
            device.Present();
        }
        //マウスのクリックを検出
        protected override void OnMouseDown(MouseEventArgs e)
        //{   tim+= 100;  }       //アニメーションの間隔
        {   tim+= 20;  }        //アニメーションの間隔
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {   this.Render();  }
        protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
        {   if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)
                this.Dispose(); // Esc was pressed
        }
        protected override void OnResize(System.EventArgs e)
        {   pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible);  }
        //☆ Main() メソッド
        static void Main()
        {   using (Meshes frm = new Meshes())
            {   if (!frm.InitializeGraphics()) // Initialize Direct3D
                {   MessageBox.Show("Could not initialize Direct3D.  This tutorial will exit.");
                    return;
                }
                frm.Show();
                // While the form is still valid, render and process messages
                while (frm.Created)
                {   frm.Render();
                    Application.DoEvents();
                }
            }
        }
    }
}
 | 
/*******************************************/
/*★ Interpolator Class(回転)    前田 稔 ★*/
/*******************************************/
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D=Microsoft.DirectX.Direct3D;
using System.Collections;
namespace Anime
{
    //Rotation Interpolator Data
    class InterRotDat
    {
        public int  Tim;
        public Quaternion Qt;
        //InterRotDat Constructor
        public InterRotDat(int tim, Quaternion qt)
        {   Tim= tim;
            //Qt= Quaternion.Normalize(qt);
            Qt= qt;
        }
        public void Print()
        {
            Console.WriteLine("Time={0}  {1},{2},{3},{4}", Tim, Qt.X, Qt.Y, Qt.Z, Qt.W);
        }
    }
    //☆Interpolator Class
    class InterRot
    {
        InterRotDat[]   Rot;
        int         Leng;
        //InterRot Constructor
        public InterRot(InterRotDat[] rot)
        {   Rot= rot;
            Leng= Rot.GetLength(0)-1;
        }
        //tim の Matrix を計算
        public Matrix GetMat(int tim)
        {   int     wk,i;
            float   rate;
            Quaternion wqt;
            wk= tim % Rot[Leng].Tim;
            for(i=0; i<Leng && Rot[i].Tim<wk; i++);
            if (Rot[i].Tim==wk) return Matrix.RotationQuaternion(Rot[i].Qt);
            rate= (float)(wk-Rot[i-1].Tim)/(float)(Rot[i].Tim-Rot[i-1].Tim);
            wqt = Quaternion.Slerp(Rot[i-1].Qt, Rot[i].Qt, rate);
            return Matrix.RotationQuaternion(wqt);
        }
    }
}
 | 
    InterRot    interrot;       //Interpolator の定義
    //回転情報の定義
    InterRotDat[]   Rot =
    {   new InterRotDat(0,new Quaternion(0.0f,0.0f,0.0f,1.0f)),
        new InterRotDat(100,new Quaternion(0.0f,0.72f,0.0f,0.70f)),
        new InterRotDat(200,new Quaternion(0.0f,1.00f,0.0f,0.02f)),
        new InterRotDat(300,new Quaternion(0.0f,-0.71f,0.0f,0.70f)),
        new InterRotDat(400,new Quaternion(0.0f,0.01f,0.0f,1.00f))
    };
    int     tim= 0;
     | 
    //マウスのクリックを検出
    protected override void OnMouseDown(MouseEventArgs e)
    {   tim+= 20;  }    //アニメーションの間隔
     | 
    void SetupMatrices()
    {
        mat= interrot.GetMat(tim);
        device.Transform.World = mat;
        device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f,2.0f,-5.0f),
            new Vector3(0.0f,0.0f,0.0f), new Vector3(0.0f,1.0f,0.0f));
        device.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI/4),
            (float)this.Width / (float)this.Height, 1.0f, 500.0f);
    }
     | 
![]()
    class InterRotDat
    {
        public int  Tim;
        public Quaternion Qt;
        //InterRotDat Constructor
        public InterRotDat(int tim, Quaternion qt)
        {   Tim= tim;
            Qt= Quaternion.Normalize(qt);
        }
        public void Print()
        {
            Console.WriteLine("Time={0}  {1},{2},{3},{4}", Tim, Qt.X, Qt.Y, Qt.Z, Qt.W);
        }
    }
     | 
        ・・・
    public Matrix GetMat(int tim)
    {   int     wk,i;
        float   rate;
        Quaternion wqt;
        wk= tim % Rot[Leng].Tim;
        for(i=0; i<Leng && Rot[i].Tim<wk; i++);
        if (i==0 || Rot[i].Tim==wk)     return Matrix.RotationQuaternion(Rot[i].Qt);
        rate= (float)(wk-Rot[i-1].Tim)/(float)(Rot[i].Tim-Rot[i-1].Tim);
        wqt = Quaternion.Slerp(Rot[i-1].Qt, Rot[i].Qt, rate);
        return Matrix.RotationQuaternion(wqt);
    }
     | 
![]()
![]()