BoundingBody.cs
上传用户:lslight
上传日期:2022-01-10
资源大小:14248k
文件大小:18k
- ///////////////////////////////////////////////////////////////////////
- // ■■■■ ■■■■■ ■■■■ ■ ■ //
- // ■ ■ ■ ■ ■ //
- // ■ ■ ■ ■■■ ■ ■ //
- // ■ ■ ■ ■ ■ ■ //
- // ■■■■ ■ ■■■■ ■■■■ //
- // Copyright (c) 三峡大学水利与环境学院 肖泽云. All rights reserved. //
- ////////////////////////////////////////////////////////////////////////
- using System;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Windows.Forms;
- using Microsoft.DirectX;
- using Microsoft.DirectX.Direct3D;
- namespace 包围盒
- {
- public partial class BoundingBody : Form
- {
- Device device = null;//定义绘图设备
- private float angleY=0.01f;//定义绕Y轴旋转变量
- private Vector3 CamPostion = new Vector3(0, 30, -30);//定义摄像机位置
- private Vector3 CamTarget = new Vector3(0, 0, 0);//定义摄像机目标位置
- private int mouseLastX,mouseLastY;//记录鼠标按下时的坐标位置
- private bool isRotateByMouse=false;//记录是否由鼠标控制旋转
- private bool isMoveByMouse = false;//记录是否由鼠标控制移动
- private Material meshMaterials; //定义网格材质对象
- private Mesh meshObj;//定义网格对象
- private Mesh boundingBox;//定义包围盒对象
- private Vector3 minVector, maxVector;//定义包围盒最大和最小向量
- private Mesh boundingSphere;//定义包围球对象
- private Vector3 boundingSphereCenter;//定义包围球球心向量
- private float boundingSphereRadius;//定义包围球半径
- public BoundingBody()
- {
- this.ClientSize = new Size(800, 600);//指定窗体尺寸
- this.Text = "包围盒";//指定窗体标题
- }
- public bool InitializeDirect3D()
- {
- try
- {
- PresentParameters presentParams = new PresentParameters();
- presentParams.Windowed = true; //指定以Windows窗体形式显示
- presentParams.SwapEffect = SwapEffect.Discard; //当前屏幕绘制后它将自动从内存中删除
- presentParams.AutoDepthStencilFormat = DepthFormat.D16;
- presentParams.EnableAutoDepthStencil = true;
- presentParams.PresentationInterval = PresentInterval.Immediate;
- device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //实例化device对象
- //定义材质
- meshMaterials = new Material();
- meshMaterials.Diffuse = Color.White;
- meshMaterials.Ambient = Color.White;
- meshMaterials.Specular = Color.LightGray;
- meshMaterials.SpecularSharpness = 15.0F;
- meshObj = Mesh.Teapot(device);//定义茶壶对象
- //获取茶壶模型的包围盒
- /*
- VertexBuffer vertexBuffer=meshObj.VertexBuffer;
- GraphicsStream graphicsStream = vertexBuffer.Lock(0,0, LockFlags.None);
- //Vector3 minVector,maxVector;
- Geometry.ComputeBoundingBox(graphicsStream, meshObj.NumberVertices,meshObj.VertexFormat, out minVector, out maxVector);
- //boundingBox = GetBoundingBox(minVector, maxVector);
- boundingBox = Mesh.Box(device, maxVector.X - minVector.X, maxVector.Y - minVector.Y, maxVector.Z - minVector.Z);
- vertexBuffer.Unlock();
- */
- //获取茶壶模型的包围球
- VertexBuffer vertexBuffer = meshObj.VertexBuffer;
- GraphicsStream graphicsStream = vertexBuffer.Lock(0, 0, LockFlags.None);
- boundingSphereRadius = Geometry.ComputeBoundingSphere(graphicsStream, meshObj.NumberVertices, meshObj.VertexFormat, out boundingSphereCenter);
- boundingSphere = Mesh.Sphere(device, boundingSphereRadius, 20, 20);
- vertexBuffer.Unlock();
- return true;
- }
- catch (DirectXException e)
- {
- MessageBox.Show(e.ToString(), "Error"); //处理异常
- return false;
- }
- }
- //根据包围盒返回的min向量和max向量生成一个长方体包围盒网格
- private Mesh GetBoundingBox(Vector3 min,Vector3 max)
- {
- Mesh returnMeshObject;
- //定义顶点
- CustomVertex.PositionColored[] arrayVertices = new CustomVertex.PositionColored[8];
- //定义索引
- Int16[] arrayIndices = new Int16[36];
- //定义属性
- AttributeRange attributeRange = new AttributeRange();
- //实例化网格对象
- returnMeshObject = new Mesh(arrayIndices.Length / 3, arrayVertices.Length, MeshFlags.SystemMemory, CustomVertex.PositionColored.Format, device);
- //设置顶点坐标值
- arrayVertices[0].Position = new Vector3(min.X,max.Y,min.Z);
- arrayVertices[0].Color = Color.Yellow.ToArgb();
- arrayVertices[1].Position = new Vector3(min.X, max.Y, max.Z);
- arrayVertices[1].Color = Color.Red.ToArgb();
- arrayVertices[2].Position = new Vector3(max.X, max.Y, max.Z);
- arrayVertices[2].Color = Color.Green.ToArgb();
- arrayVertices[3].Position = new Vector3(max.X, max.Y, min.Z);
- arrayVertices[3].Color = Color.Gold.ToArgb();
- arrayVertices[4].Position = new Vector3(min.X, min.Y, min.Z);
- arrayVertices[4].Color = Color.GhostWhite.ToArgb();
- arrayVertices[5].Position = new Vector3(min.X, min.Y, max.Z);
- arrayVertices[5].Color = Color.LightPink.ToArgb();
- arrayVertices[6].Position = new Vector3(max.X, min.Y, max.Z);
- arrayVertices[6].Color = Color.Maroon.ToArgb();
- arrayVertices[7].Position = new Vector3(max.X, min.Y, min.Z);
- //设置索引,顶部三角形
- arrayIndices[0] = 0; arrayIndices[1] = 1; arrayIndices[2] = 3;
- arrayIndices[3] = 3; arrayIndices[4] = 1; arrayIndices[5] = 2;
- //周围三角形
- arrayIndices[6] = 4; arrayIndices[7] = 0; arrayIndices[8] = 7;
- arrayIndices[9] = 7; arrayIndices[10] = 0; arrayIndices[11] = 3;
- arrayIndices[12] = 7; arrayIndices[13] = 3; arrayIndices[14] = 6;
- arrayIndices[15] = 6; arrayIndices[16] = 3; arrayIndices[17] = 2;
- arrayIndices[18] = 6; arrayIndices[19] = 2; arrayIndices[20] = 5;
- arrayIndices[21] = 5; arrayIndices[22] = 2; arrayIndices[23] = 1;
- arrayIndices[24] = 5; arrayIndices[25] = 1; arrayIndices[26] = 4;
- arrayIndices[27] = 4; arrayIndices[28] = 1; arrayIndices[29] = 0;
- //底部三角形
- arrayIndices[30] = 5; arrayIndices[31] = 4; arrayIndices[32] = 7;
- arrayIndices[33] = 7; arrayIndices[34] = 6; arrayIndices[35] = 5;
- //设置属性
- attributeRange.AttributeId = 0;
- attributeRange.FaceStart = 0;
- attributeRange.FaceCount = arrayIndices.Length / 3;
- attributeRange.VertexStart = 0;
- attributeRange.VertexCount = arrayVertices.Length;
- //设置网格对象的索引缓冲和顶点缓冲数据
- returnMeshObject.VertexBuffer.SetData(arrayVertices, 0, LockFlags.None);
- returnMeshObject.IndexBuffer.SetData(arrayIndices, 0, LockFlags.None);
- returnMeshObject.SetAttributeTable(new AttributeRange[] { attributeRange });
- return returnMeshObject;
- }
- public void Render()
- {
- if (device == null) //如果device为空则不渲染
- {
- return;
- }
- SetUpCamera();
- device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkSlateBlue, 1.0f, 0); //清除windows界面为深蓝色
- device.BeginScene();
- //在此添加渲染图形代码
- //灯光设置
- device.RenderState.Lighting = true;
- device.Lights[0].Type = LightType.Directional;
- device.Lights[0].Diffuse = System.Drawing.Color.Red;
- device.Lights[0].Direction = new Vector3(-1.0f, 1.0f, 1.0f);
- device.Lights[0].Enabled = true; //打开灯光
- device.Lights[1].Type = LightType.Directional;
- device.Lights[1].Diffuse = System.Drawing.Color.Green;
- device.Lights[1].Direction = new Vector3(1f, -1.0f, 1.0f);
- device.Lights[1].Enabled = true; //打开灯光
- device.RenderState.Ambient = Color.SlateGray;
-
- device.RenderState.CullMode = Cull.None;
- //设置当前材质
- device.Material = meshMaterials;
- //以实体形式绘制茶壶模型
- device.RenderState.FillMode = FillMode.Solid;
- meshObj.DrawSubset(0);
- //以线框形式绘制茶壶包围盒模型
- /*
- device.RenderState.FillMode = FillMode.WireFrame;
- Matrix origiWorld = device.Transform.World;
- device.Transform.World = Matrix.Translation(Vector3.Scale(Vector3.Add(minVector, maxVector), 0.5f));
- boundingBox.DrawSubset(0);
- device.Transform.World = origiWorld;
- */
- //以线框形式绘制茶壶包围球模型
- device.RenderState.FillMode = FillMode.WireFrame;
- Matrix origiWorld = device.Transform.World;
- device.Transform.World = Matrix.Translation(boundingSphereCenter);
- boundingSphere.DrawSubset(0);
- device.Transform.World = origiWorld;
- device.EndScene();
- device.Present();
- }
- private void SetUpCamera()//摄像机
- {
- Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
- device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 0.3f, 500f);
- device.Transform.View = viewMatrix;
- }
- protected override void OnKeyDown(KeyEventArgs e)
- {
- Vector4 tempV4;
- Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
- switch (e.KeyCode)
- {
- case Keys.Left:
- CamPostion.Subtract(CamTarget);
- tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
- Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), -angleY)));
- CamPostion.X = tempV4.X + CamTarget.X;
- CamPostion.Y = tempV4.Y + CamTarget.Y;
- CamPostion.Z = tempV4.Z + CamTarget.Z;
- break;
- case Keys.Right:
- CamPostion.Subtract(CamTarget);
- tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
- Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), angleY)));
- CamPostion.X = tempV4.X + CamTarget.X;
- CamPostion.Y = tempV4.Y + CamTarget.Y;
- CamPostion.Z = tempV4.Z + CamTarget.Z;
- break;
- case Keys.Up:
- CamPostion.Subtract(CamTarget);
- tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
- Quaternion.RotationAxis(new Vector3(device.Transform.View.M11
- , device.Transform.View.M21, device.Transform.View.M31), -angleY)));
- CamPostion.X = tempV4.X + CamTarget.X;
- CamPostion.Y = tempV4.Y + CamTarget.Y;
- CamPostion.Z = tempV4.Z + CamTarget.Z;
- break;
- case Keys.Down:
- CamPostion.Subtract(CamTarget);
- tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
- Quaternion.RotationAxis(new Vector3(device.Transform.View.M11
- , device.Transform.View.M21, device.Transform.View.M31), angleY)));
- CamPostion.X = tempV4.X + CamTarget.X;
- CamPostion.Y = tempV4.Y + CamTarget.Y;
- CamPostion.Z = tempV4.Z + CamTarget.Z;
- break;
- case Keys.Add:
- CamPostion.Subtract(CamTarget);
- CamPostion.Scale(0.95f);
- CamPostion.Add(CamTarget);
- break;
- case Keys.Subtract:
- CamPostion.Subtract(CamTarget);
- CamPostion.Scale(1.05f);
- CamPostion.Add(CamTarget);
- break;
- }
- Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
- device.Transform.View = viewMatrix;
- }
- protected override void OnMouseDown(MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- mouseLastX = e.X;
- mouseLastY = e.Y;
- isRotateByMouse = true;
- }
- else if (e.Button == MouseButtons.Middle)
- {
- mouseLastX = e.X;
- mouseLastY = e.Y;
- isMoveByMouse=true;
- }
- }
-
- protected override void OnMouseUp(MouseEventArgs e)
- {
- isRotateByMouse = false;
- isMoveByMouse = false;
- }
- protected override void OnMouseMove(MouseEventArgs e)
- {
- if (isRotateByMouse)
- {
- Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
- float tempAngleY = 2 * (float)(e.X - mouseLastX) / this.Width;
- CamPostion.Subtract(CamTarget);
- Vector4 tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
- Quaternion.RotationAxis(new Vector3(currentView.M12, currentView.M22, currentView.M32), tempAngleY)));
- CamPostion.X = tempV4.X;
- CamPostion.Y = tempV4.Y;
- CamPostion.Z = tempV4.Z;
- float tempAngleX = 4 * (float)(e.Y - mouseLastY) / this.Height;
- tempV4 = Vector3.Transform(CamPostion, Matrix.RotationQuaternion(
- Quaternion.RotationAxis(new Vector3(currentView.M11, currentView.M21, currentView.M31), tempAngleX)));
- CamPostion.X = tempV4.X + CamTarget.X;
- CamPostion.Y = tempV4.Y + CamTarget.Y;
- CamPostion.Z = tempV4.Z + CamTarget.Z;
- Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
- device.Transform.View = viewMatrix;
- mouseLastX = e.X;
- mouseLastY = e.Y;
- }
- else if (isMoveByMouse)
- {
- Matrix currentView = device.Transform.View;//当前摄像机的视图矩阵
- float moveFactor=0.01f;
- CamTarget.X += -moveFactor * ((e.X - mouseLastX) * currentView.M11 - (e.Y - mouseLastY) * currentView.M12);
- CamTarget.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21 - (e.Y - mouseLastY) * currentView.M22);
- CamTarget.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31 - (e.Y - mouseLastY) * currentView.M32);
- CamPostion.X +=- moveFactor * ((e.X - mouseLastX) * currentView.M11 - (e.Y - mouseLastY) * currentView.M12);
- CamPostion.Y += -moveFactor * ((e.X - mouseLastX) * currentView.M21 - (e.Y - mouseLastY) * currentView.M22);
- CamPostion.Z += -moveFactor * ((e.X - mouseLastX) * currentView.M31 - (e.Y - mouseLastY) * currentView.M32);
-
- Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
- device.Transform.View = viewMatrix;
- mouseLastX = e.X;
- mouseLastY = e.Y;
- }
- }
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- float scaleFactor = -(float)e.Delta / 2000 + 1f;
- CamPostion.Subtract(CamTarget);
- CamPostion.Scale(scaleFactor);
- CamPostion.Add(CamTarget);
- Matrix viewMatrix = Matrix.LookAtLH(CamPostion, CamTarget, new Vector3(0, 1, 0));
- device.Transform.View = viewMatrix;
- }
- static void Main()
- {
- BoundingBody boundingBody = new BoundingBody(); //创建窗体对象
- if (boundingBody.InitializeDirect3D() == false) //检查Direct3D是否启动
- {
- MessageBox.Show("无法启动Direct3D!", "错误!");
- return;
- }
- boundingBody.Show(); //如果一切都初始化成功,则显示窗体
- while (boundingBody.Created) //设置一个循环用于实时更新渲染状态
- {
- boundingBody.Render(); //保持device渲染,直到程序结束
- Application.DoEvents(); //处理键盘鼠标等输入事件
- }
- }
- }
- }