All pastes #946950 Raw Edit

GoatCheez.View3DControl.cs

public text v1 · immutable
·published 2008-03-18 01:46 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Drawing;

namespace GoatCheez_KO_Private_Server_Map_Editor
{
    public partial class View3DControl : UserControl
    {
        public enum SpatialPlane
        {
            PlaneXZ,
            PlaneXY,
            PlaneZY
        }

        private Device d3dDevice = null;
        private bool valid = false;
        private PresentParameters presentParameters;

        private Single cameraX = 50f;
        private Single cameraY = 50f;
        private Single cameraZ = -50f;
        private Single lookAtX = 0f;
        private Single lookAtY = 0f;
        private Single lookAtZ = 0f;
        private Single upX = 0f;
        private Single upY = 1f;
        private Single upZ = 0f;
        private Single fov = ((Single)(Math.PI / 4)); //45 degrees
        private Single clipNear = 0;
        private Single clipFar = 1000f;
        private string labelText = "";
        private Microsoft.DirectX.Direct3D.Font labelStyle;
        private Int32 labelX = 2;
        private Int32 labelY = 2;
        private bool showGrid = true;
        private VertexBuffer gridLineBuffer;
        private SpatialPlane gridPlane = SpatialPlane.PlaneXZ;
        private Single gridSize = 500f;
        private Single gridSpacing = 25f;
        private Int32 gridLineCount = 0;
        private CreateFlags createFlags;
        private VertexBuffer userDataBuffer;
        CustomVertex.PositionColored[] userDataVertices;

        #region construction and initialization

        public View3DControl()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
        }

        ~View3DControl()
        {            
            valid = false;
            if (d3dDevice != null)
                d3dDevice.Dispose();
            if (gridLineBuffer != null)
                gridLineBuffer.Dispose();
            if (labelStyle != null)
                labelStyle.Dispose();

        }

        private bool InitializeDirect3D()
        {
            try
            {
                presentParameters = new PresentParameters();
                presentParameters.BackBufferFormat = Format.Unknown;
                presentParameters.Windowed = true;
                presentParameters.SwapEffect = SwapEffect.Discard;
                presentParameters.EnableAutoDepthStencil = true;
                presentParameters.AutoDepthStencilFormat = DepthFormat.D16;
                presentParameters.PresentationInterval = PresentInterval.Immediate;                

                Caps caps = Manager.GetDeviceCaps(Manager.Adapters.Default.Adapter,
                                               DeviceType.Hardware);

                if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
                {
                    createFlags = CreateFlags.HardwareVertexProcessing;
                }
                else
                {
                    createFlags = CreateFlags.SoftwareVertexProcessing;
                }

                d3dDevice = CreateD3DDevice();

                d3dDevice.DeviceReset += new EventHandler(this.d3dDevice_DeviceReset);                

                return true;
            }
            catch (Exception eX)
            {
                MessageBox.Show("Unable to initialize Direct3D." + Environment.NewLine + eX.Message);
                return false;
            }
        }        

        private Device CreateD3DDevice()
        {
            Device device = new Device(0, DeviceType.Hardware, this, createFlags, presentParameters);
            SetupTransformMatrices(device);
            SetupRenderState(device);
            return device;
        }

        private void SetupRenderState(Device device)
        {   
            device.RenderState.ZBufferEnable = true;
            device.RenderState.CullMode = Cull.None;
            device.RenderState.Lighting = false;            
            device.RenderState.PointSize = 4.0f;
            device.RenderState.FillMode = FillMode.Solid;           
        }

        private void SetupTransformMatrices(Device device)
        {
            device.Transform.World = Matrix.Identity;
            device.Transform.Projection = Matrix.PerspectiveFovLH(fov, ((Single)(this.Width)) / ((Single)(this.Height)), clipNear, clipFar);
            device.Transform.View = Matrix.LookAtLH(
                    new Vector3(cameraX, cameraY, cameraZ),
                    new Vector3(lookAtX, lookAtY, lookAtZ),
                    new Vector3(upX, upY, upZ));
        }

        #endregion

        #region data creation methods

        private void CreateDeviceObjects(Device device)
        {
            CreateLabel(device);
            CreateGridLines(device);
            CreateUserData(device);
        }
                
        private void CreateGridLines(Device device)
        {
            if (valid && device != null)
            {
                List<CustomVertex.PositionColored> newGridVertices = new List<CustomVertex.PositionColored>();
                if (gridPlane == SpatialPlane.PlaneXZ)
                {
                    newGridVertices.Add(new CustomVertex.PositionColored(-1 * gridSize, 0f, 0f, Color.White.ToArgb()));
                    newGridVertices.Add(new CustomVertex.PositionColored(gridSize, 0f, 0f, Color.White.ToArgb()));                    

                    newGridVertices.Add(new CustomVertex.PositionColored(0f, 0f, -1 * gridSize, Color.White.ToArgb()));
                    newGridVertices.Add(new CustomVertex.PositionColored(0f, 0f, gridSize, Color.White.ToArgb()));

                    for (float marker = 0; marker <= gridSize; marker += gridSpacing)
                    {
                        newGridVertices.Add(new CustomVertex.PositionColored(marker, 0f, -1 * gridSize, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(marker, 0f, gridSize, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(-marker, 0f, -1 * gridSize, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(-marker, 0f, gridSize, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(-1 * gridSize, 0f, marker, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(gridSize, 0f, marker, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(-1 * gridSize, 0f, -marker, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(gridSize, 0f, -marker, Color.White.ToArgb()));
                    }
                }
                else if (gridPlane == SpatialPlane.PlaneXY)
                {
                    newGridVertices.Add(new CustomVertex.PositionColored(-1 * gridSize, 0f, 0f, Color.White.ToArgb()));
                    newGridVertices.Add(new CustomVertex.PositionColored(gridSize, 0f, 0f, Color.White.ToArgb()));

                    newGridVertices.Add(new CustomVertex.PositionColored(0f, -1 * gridSize, 0f, Color.White.ToArgb()));
                    newGridVertices.Add(new CustomVertex.PositionColored(0f, gridSize, 0f, Color.White.ToArgb()));

                    for (float marker = 0; marker <= gridSize; marker += gridSpacing)
                    {
                        newGridVertices.Add(new CustomVertex.PositionColored(marker, -1 * gridSize, 0f, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(marker, gridSize, 0f, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(-marker, -1 * gridSize, 0f, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(-marker, gridSize, 0f, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(-1 * gridSize, marker, 0f, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(gridSize, marker, 0f, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(-1 * gridSize, -marker, 0f, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(gridSize, -marker, 0f, Color.White.ToArgb()));
                    }
                }
                else if (gridPlane == SpatialPlane.PlaneZY)
                {
                    newGridVertices.Add(new CustomVertex.PositionColored(0f, -1 * gridSize, 0f, Color.White.ToArgb()));
                    newGridVertices.Add(new CustomVertex.PositionColored(0f, gridSize, 0f, Color.White.ToArgb()));

                    newGridVertices.Add(new CustomVertex.PositionColored(0f, 0f, -1 * gridSize, Color.White.ToArgb()));
                    newGridVertices.Add(new CustomVertex.PositionColored(0f, 0f, gridSize, Color.White.ToArgb()));

                    for (float marker = 0; marker <= gridSize; marker += gridSpacing)
                    {
                        newGridVertices.Add(new CustomVertex.PositionColored(0f, marker, -1 * gridSize, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(0f, marker, gridSize, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(0f, -marker, -1 * gridSize, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(0f, -marker, gridSize, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(0f, -1 * gridSize, marker, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(0f, gridSize, marker, Color.White.ToArgb()));

                        newGridVertices.Add(new CustomVertex.PositionColored(0f, -1 * gridSize, -marker, Color.White.ToArgb()));
                        newGridVertices.Add(new CustomVertex.PositionColored(0f, gridSize, -marker, Color.White.ToArgb()));
                    }
                }
                if (gridLineBuffer != null)
                    gridLineBuffer.Dispose();
                gridLineBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored), newGridVertices.Count, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
                using (GraphicsStream graphicsStream = gridLineBuffer.Lock(0, 0, 0))
                {
                    CustomVertex.PositionColored[] verts = newGridVertices.ToArray();
                    graphicsStream.Write(verts);                    
                }
                gridLineBuffer.Unlock();
                gridLineCount = newGridVertices.Count / 2;
            }
        }

        private void CreateLabel(Device device)
        {
            if (valid && device != null)
            {
                if (labelStyle != null)
                    labelStyle.Dispose();
                labelStyle = new Microsoft.DirectX.Direct3D.Font(device, this.Font);
            }
        }

        private void CreateUserData(Device device)
        {
            if (valid && (device != null) && (userDataVertices != null))
            {
                if (userDataBuffer != null)
                    userDataBuffer.Dispose();
                userDataBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored), userDataVertices.Length, device, Usage.WriteOnly | Usage.Dynamic, CustomVertex.PositionColored.Format, Pool.Default);
                using (GraphicsStream graphicsStream = userDataBuffer.Lock(0, 0, 0))
                {
                    graphicsStream.Write(userDataVertices);
                }
                userDataBuffer.Unlock();                
            }
        }

        #endregion

        #region paint methods

        private void PaintLabel()
        {
            if (valid && (labelStyle != null) && (d3dDevice != null))
            {
                labelStyle.DrawText(null, labelText, labelX, labelY, this.ForeColor);
            }
        }

        private void PaintAxisGrid()
        {
            if (valid && (d3dDevice != null) && (gridLineBuffer != null) && (gridLineCount > 0))
            {                
                d3dDevice.VertexFormat = CustomVertex.PositionColored.Format;
                d3dDevice.SetStreamSource(0, gridLineBuffer, 0);
                d3dDevice.DrawPrimitives(PrimitiveType.LineList, 0, gridLineCount);        
            }
        }

        private void PaintUserData()
        {
            if (valid && (d3dDevice != null) && (userDataBuffer != null) && (userDataVertices != null))
            {
                d3dDevice.VertexFormat = CustomVertex.PositionColored.Format;
                d3dDevice.SetStreamSource(0, userDataBuffer, 0);
                d3dDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, userDataVertices.Length / 3);                
            }
        }

        #endregion

        #region Public Properties

        public Single CameraX
        {
            get { return cameraX; }
            set { cameraX = value; }
        }

        public Single CameraY
        {
            get { return cameraY; }
            set { cameraY = value; }
        }

        public Single CameraZ
        {
            get { return cameraZ; }
            set { cameraZ = value; }
        }

        public Single LookAtX
        {
            get { return lookAtX; }
            set { lookAtX = value; }
        }

        public Single LookAtY
        {
            get { return lookAtY; }
            set { lookAtY = value; }
        }

        public Single LookAtZ
        {
            get { return lookAtZ; }
            set { lookAtZ = value; }
        }

        public Single UpX
        {
            get { return upX; }
            set { upX = value; }
        }

        public Single UpY
        {
            get { return upY; }
            set { upY = value; }
        }

        public Single UpZ
        {
            get { return upZ; }
            set { upZ = value; }
        }

        public Single FieldOfView
        {
            get { return fov; }
            set { fov = value; }
        }

        public Single ClippingPlaneNear
        {
            get { return clipNear; }
            set { clipNear = value; }
        }

        public Single ClippingPlaneFar
        {
            get { return clipFar; }
            set { clipFar = value; }
        }

        public string Label
        {
            get { return labelText; }
            set { labelText = value; this.Refresh(); }
        }

        public Int32 LabelX
        {
            get { return labelX; }
            set { labelX = value; }
        }

        public Int32 LabelY
        {
            get { return labelY; }
            set { labelY = value; }
        }

        public bool ShowAxisGrid
        {
            get { return showGrid; }
            set { showGrid = value; CreateGridLines(d3dDevice); this.Refresh(); }
        }

        public SpatialPlane GridPlane
        {
            get { return gridPlane; }
            set { gridPlane = value; CreateGridLines(d3dDevice); this.Refresh(); }
        }

        public Single GridSize
        {
            get { return gridSize; }
            set { gridSize = value; CreateGridLines(d3dDevice); this.Refresh(); }
        }

        public Single GridSpacing
        {
            get { return gridSpacing; }
            set { gridSpacing = value; CreateGridLines(d3dDevice); this.Refresh(); }
        }
        
        #endregion

        #region events

        void d3dDevice_DeviceReset(object sender, EventArgs e)
        {
            SetupTransformMatrices((Device)sender);
            SetupRenderState((Device)sender);
            CreateDeviceObjects((Device)sender);
            valid = true;
        }    

        private void View3DControl_Paint(object sender, PaintEventArgs e)
        {
            if (valid)
            {
                d3dDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);

                d3dDevice.BeginScene();

                SetupTransformMatrices(d3dDevice);

                PaintAxisGrid();

                PaintUserData();

                PaintLabel();

                d3dDevice.EndScene();

                d3dDevice.Present();
            }
        }       

        private void View3DControl_Load(object sender, EventArgs e)
        {
            valid = InitializeDirect3D();
            CreateDeviceObjects(d3dDevice);            
        }

        private void View3DControl_FontChanged(object sender, EventArgs e)
        {
            this.Refresh();
        }

        private void View3DControl_ForeColorChanged(object sender, EventArgs e)
        {
            this.Refresh();
        }

        private void View3DControl_Resize(object sender, EventArgs e)
        {
            valid = false;
        }

        private void View3DControl_MouseMove(object sender, MouseEventArgs e)
        {

        }
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            base.OnMouseWheel(e);
            if (e.Delta != 0)
            {
                Vector3 cameraVector = new Vector3(cameraX, cameraY, CameraZ);
                Vector3 lookAtVector = new Vector3(lookAtX, lookAtY, lookAtZ);
                cameraVector.Subtract(lookAtVector);
                cameraVector.X *= -1f * (gridSpacing * e.Delta / 12000f);
                cameraVector.Y *= -1f * (gridSpacing * e.Delta / 12000f);
                cameraVector.Z *= -1f * (gridSpacing * e.Delta / 12000f);
                cameraX += cameraVector.X;
                cameraY += cameraVector.Y;
                cameraZ += cameraVector.Z;
                lookAtX += cameraVector.X;
                lookAtY += cameraVector.Y;
                lookAtZ += cameraVector.Z;
            }
            this.Refresh();
        }
        private void View3DControl_MouseDown(object sender, MouseEventArgs e)
        {
            
        }

        private void View3DControl_MouseHover(object sender, EventArgs e)
        {
            this.Focus();
        }

        private void View3DControl_MouseEnter(object sender, EventArgs e)
        {
            this.Focus();
        }

        #endregion events                        

        #region public methods

        public void SetData(CustomVertex.PositionColored[] vertices)
        {
            userDataVertices = vertices;
            CreateUserData(d3dDevice);
        }

        #endregion

    }
}