C# 如何检查射线拾取圆柱体XNA
我正在使用XNA提供的原语绘制圆柱体,我想做的是,当鼠标悬停在圆柱体上时,我会检测到它。我尝试使用边界球体,但没有效果,因为它不准确。我不知道该怎么办。有什么帮助吗 我想做什么的总结。 1-为此圆柱体创建边界框 2-旋转此边界框。 可在此处找到绘制圆柱体的代码C# 如何检查射线拾取圆柱体XNA,c#,xna,drawing,primitive,bounding-box,C#,Xna,Drawing,Primitive,Bounding Box,我正在使用XNA提供的原语绘制圆柱体,我想做的是,当鼠标悬停在圆柱体上时,我会检测到它。我尝试使用边界球体,但没有效果,因为它不准确。我不知道该怎么办。有什么帮助吗 我想做什么的总结。 1-为此圆柱体创建边界框 2-旋转此边界框。 可在此处找到绘制圆柱体的代码 #区域文件说明 //----------------------------------------------------------------------------- //Cylinder.cs // //微软XNA社区游戏平台
#区域文件说明
//-----------------------------------------------------------------------------
//Cylinder.cs
//
//微软XNA社区游戏平台
//版权所有(C)微软公司。版权所有。
//-----------------------------------------------------------------------------
#端区
#区域使用语句
使用制度;
使用Microsoft.Xna.Framework;
使用Microsoft.Xna.Framework.Graphics;
#端区
将名称空间命名为proteinbundle
{
///
///用于绘制圆柱体的几何图元类。
///
公共类CylinderPrimitive:GeometricPrimitive
{
///
///使用默认设置构造新的圆柱体图元。
///
公共圆柱体原语(图形设备图形设备)
:此(图形设备,1,1,32)
{
}
///
///构造一个新的圆柱体基本体,
///具有指定的大小和细分级别。
///
公共圆柱体图元(图形设备图形设备、,
浮动高度、浮动直径、整数细分)
{
如果(细分<3)
抛出新ArgumentOutOfRangeException(“细分”);
高度/=2;
浮动半径=直径/2;
//围绕圆柱体外部创建一个三角形环。
对于(int i=0;i直径)
base.boundingSphere.Radius=高度;
其他的
base.boundingSphere.Radius=直径;
}
///
///辅助对象方法创建三角形风扇以闭合圆柱体的端点。
///
void CreateCap(整数细分、浮动高度、浮动半径、矢量3法线)
{
//创建cap指数。
对于(int i=0;i0)
{
AddIndex(当前顶点);
AddIndex(CurrentVertex+(i+1)%tessellation);
AddIndex(CurrentVertex+(i+2)%tessellation);
}
其他的
{
AddIndex(当前顶点);
AddIndex(CurrentVertex+(i+2)%tessellation);
AddIndex(CurrentVertex+(i+1)%tessellation);
}
}
//创建帽顶点。
对于(int i=0;i
使用这个类
#region File Description
//-----------------------------------------------------------------------------
// GeometricPrimitive.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace TheProteinBundle
{
/// <summary>
/// Base class for simple geometric primitive models. This provides a vertex
/// buffer, an index buffer, plus methods for drawing the model. Classes for
/// specific types of primitive (CubePrimitive, SpherePrimitive, etc.) are
/// derived from this common base, and use the AddVertex and AddIndex methods
/// to specify their geometry.
/// </summary>
public abstract class GeometricPrimitive : IDisposable
{
#region Fields
// During the process of constructing a primitive model, vertex
// and index data is stored on the CPU in these managed lists.
List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();
List<ushort> indices = new List<ushort>();
// Once all the geometry has been specified, the InitializePrimitive
// method copies the vertex and index data into these buffers, which
// store it on the GPU ready for efficient rendering.
VertexBuffer vertexBuffer;
IndexBuffer indexBuffer;
BasicEffect basicEffect;
public BoundingSphere boundingsphere2;
public BoundingSphere boundingSphere;
public Matrix world;
#endregion
#region Initialization
/// <summary>
/// Adds a new vertex to the primitive model. This should only be called
/// during the initialization process, before InitializePrimitive.
/// </summary>
protected void AddVertex(Vector3 position, Vector3 normal)
{
vertices.Add(new VertexPositionNormal(position, normal));
}
/// <summary>
/// Adds a new index to the primitive model. This should only be called
/// during the initialization process, before InitializePrimitive.
/// </summary>
protected void AddIndex(int index)
{
if (index > ushort.MaxValue)
throw new ArgumentOutOfRangeException("index");
indices.Add((ushort)index);
}
/// <summary>
/// Queries the index of the current vertex. This starts at
/// zero, and increments every time AddVertex is called.
/// </summary>
protected int CurrentVertex
{
get { return vertices.Count; }
}
/// <summary>
/// Once all the geometry has been specified by calling AddVertex and AddIndex,
/// this method copies the vertex and index data into GPU format buffers, ready
/// for efficient rendering.
protected void InitializePrimitive(GraphicsDevice graphicsDevice)
{
// Create a vertex declaration, describing the format of our vertex data.
// Create a vertex buffer, and copy our vertex data into it.
vertexBuffer = new VertexBuffer(graphicsDevice,
typeof(VertexPositionNormal),
vertices.Count, BufferUsage.None);
vertexBuffer.SetData(vertices.ToArray());
// Create an index buffer, and copy our index data into it.
indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
indices.Count, BufferUsage.None);
indexBuffer.SetData(indices.ToArray());
// Create a BasicEffect, which will be used to render the primitive.
basicEffect = new BasicEffect(graphicsDevice);
basicEffect.EnableDefaultLighting();
}
/// <summary>
/// Finalizer.
/// </summary>
~GeometricPrimitive()
{
Dispose(false);
}
/// <summary>
/// Frees resources used by this object.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Frees resources used by this object.
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (vertexBuffer != null)
vertexBuffer.Dispose();
if (indexBuffer != null)
indexBuffer.Dispose();
if (basicEffect != null)
basicEffect.Dispose();
}
}
#endregion
public void TransformBoundingSphere(Matrix TransformToWorld)
{
boundingSphere.Transform(ref TransformToWorld, out boundingsphere2);
}
public bool CheckRayIntersection(Ray ray)
{
if (ray.Intersects(boundingsphere2).HasValue) return true;
return false;
}
#region Draw
/// <summary>
/// Draws the primitive model, using the specified effect. Unlike the other
/// Draw overload where you just specify the world/view/projection matrices
/// and color, this method does not set any renderstates, so you must make
/// sure all states are set to sensible values before you call it.
/// </summary>
public void Draw(Effect effect)
{
GraphicsDevice graphicsDevice = effect.GraphicsDevice;
// Set our vertex declaration, vertex buffer, and index buffer.
graphicsDevice.SetVertexBuffer(vertexBuffer);
graphicsDevice.Indices = indexBuffer;
foreach (EffectPass effectPass in effect.CurrentTechnique.Passes)
{
effectPass.Apply();
int primitiveCount = indices.Count / 3;
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
vertices.Count, 0, primitiveCount);
}
}
/// <summary>
/// Draws the primitive model, using a BasicEffect shader with default
/// lighting. Unlike the other Draw overload where you specify a custom
/// effect, this method sets important renderstates to sensible values
/// for 3D model rendering, so you do not need to set these states before
/// you call it.
/// </summary>
public void Draw(Matrix world, Matrix view, Matrix projection, Color color)
{
// Set BasicEffect parameters.
basicEffect.World = world;
basicEffect.View = view;
basicEffect.Projection = projection;
basicEffect.DiffuseColor = color.ToVector3();
basicEffect.Alpha = color.A / 255.0f;
GraphicsDevice device = basicEffect.GraphicsDevice;
device.DepthStencilState = DepthStencilState.Default;
if (color.A < 255)
{
// Set renderstates for alpha blended rendering.
device.BlendState = BlendState.AlphaBlend;
}
else
{
// Set renderstates for opaque rendering.
device.BlendState = BlendState.Opaque;
}
// Draw the model, using BasicEffect.
Draw(basicEffect);
}
#endregion
}
}
#区域文件说明
//-----------------------------------------------------------------------------
//GeometricPrimitive.cs
//
//微软XNA社区游戏平台
//版权所有(C)微软公司。版权所有。
//-----------------------------------------------------------------------------
#端区
#区域使用语句
使用制度;
使用System.Collections.Generic;
使用Microsoft.Xna.Framework;
使用Microsoft.Xna.Framework.Graphics;
#端区
将名称空间命名为proteinbundle
{
///
///简单几何基元模型的基类。这提供了一个顶点
///缓冲区,索引缓冲区,以及用于绘制模型的方法
///特定类型的基元(立方基元、球面基元等)包括
///从该公共基派生,并使用AddVertex和AddIndex方法
///指定其几何图形。
///
公共抽象类GeometricPrimitive:IDisposable
{
#区域字段
//在构造基本模型的过程中,顶点
//索引数据存储在这些托管列表中的CPU上。
列表顶点=新列表();
列表索引=新列表();
//一旦指定了所有几何图形,则初始值Primitive
//方法将顶点和索引数据复制到这些缓冲区中
//将其存储在GPU上,以便高效渲染。
顶点缓冲区顶点缓冲区;
IndexBuffer IndexBuffer;
基本效果基本效果;
公共边界
#region File Description
//-----------------------------------------------------------------------------
// GeometricPrimitive.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace TheProteinBundle
{
/// <summary>
/// Base class for simple geometric primitive models. This provides a vertex
/// buffer, an index buffer, plus methods for drawing the model. Classes for
/// specific types of primitive (CubePrimitive, SpherePrimitive, etc.) are
/// derived from this common base, and use the AddVertex and AddIndex methods
/// to specify their geometry.
/// </summary>
public abstract class GeometricPrimitive : IDisposable
{
#region Fields
// During the process of constructing a primitive model, vertex
// and index data is stored on the CPU in these managed lists.
List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();
List<ushort> indices = new List<ushort>();
// Once all the geometry has been specified, the InitializePrimitive
// method copies the vertex and index data into these buffers, which
// store it on the GPU ready for efficient rendering.
VertexBuffer vertexBuffer;
IndexBuffer indexBuffer;
BasicEffect basicEffect;
public BoundingSphere boundingsphere2;
public BoundingSphere boundingSphere;
public Matrix world;
#endregion
#region Initialization
/// <summary>
/// Adds a new vertex to the primitive model. This should only be called
/// during the initialization process, before InitializePrimitive.
/// </summary>
protected void AddVertex(Vector3 position, Vector3 normal)
{
vertices.Add(new VertexPositionNormal(position, normal));
}
/// <summary>
/// Adds a new index to the primitive model. This should only be called
/// during the initialization process, before InitializePrimitive.
/// </summary>
protected void AddIndex(int index)
{
if (index > ushort.MaxValue)
throw new ArgumentOutOfRangeException("index");
indices.Add((ushort)index);
}
/// <summary>
/// Queries the index of the current vertex. This starts at
/// zero, and increments every time AddVertex is called.
/// </summary>
protected int CurrentVertex
{
get { return vertices.Count; }
}
/// <summary>
/// Once all the geometry has been specified by calling AddVertex and AddIndex,
/// this method copies the vertex and index data into GPU format buffers, ready
/// for efficient rendering.
protected void InitializePrimitive(GraphicsDevice graphicsDevice)
{
// Create a vertex declaration, describing the format of our vertex data.
// Create a vertex buffer, and copy our vertex data into it.
vertexBuffer = new VertexBuffer(graphicsDevice,
typeof(VertexPositionNormal),
vertices.Count, BufferUsage.None);
vertexBuffer.SetData(vertices.ToArray());
// Create an index buffer, and copy our index data into it.
indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
indices.Count, BufferUsage.None);
indexBuffer.SetData(indices.ToArray());
// Create a BasicEffect, which will be used to render the primitive.
basicEffect = new BasicEffect(graphicsDevice);
basicEffect.EnableDefaultLighting();
}
/// <summary>
/// Finalizer.
/// </summary>
~GeometricPrimitive()
{
Dispose(false);
}
/// <summary>
/// Frees resources used by this object.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Frees resources used by this object.
/// </summary>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (vertexBuffer != null)
vertexBuffer.Dispose();
if (indexBuffer != null)
indexBuffer.Dispose();
if (basicEffect != null)
basicEffect.Dispose();
}
}
#endregion
public void TransformBoundingSphere(Matrix TransformToWorld)
{
boundingSphere.Transform(ref TransformToWorld, out boundingsphere2);
}
public bool CheckRayIntersection(Ray ray)
{
if (ray.Intersects(boundingsphere2).HasValue) return true;
return false;
}
#region Draw
/// <summary>
/// Draws the primitive model, using the specified effect. Unlike the other
/// Draw overload where you just specify the world/view/projection matrices
/// and color, this method does not set any renderstates, so you must make
/// sure all states are set to sensible values before you call it.
/// </summary>
public void Draw(Effect effect)
{
GraphicsDevice graphicsDevice = effect.GraphicsDevice;
// Set our vertex declaration, vertex buffer, and index buffer.
graphicsDevice.SetVertexBuffer(vertexBuffer);
graphicsDevice.Indices = indexBuffer;
foreach (EffectPass effectPass in effect.CurrentTechnique.Passes)
{
effectPass.Apply();
int primitiveCount = indices.Count / 3;
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
vertices.Count, 0, primitiveCount);
}
}
/// <summary>
/// Draws the primitive model, using a BasicEffect shader with default
/// lighting. Unlike the other Draw overload where you specify a custom
/// effect, this method sets important renderstates to sensible values
/// for 3D model rendering, so you do not need to set these states before
/// you call it.
/// </summary>
public void Draw(Matrix world, Matrix view, Matrix projection, Color color)
{
// Set BasicEffect parameters.
basicEffect.World = world;
basicEffect.View = view;
basicEffect.Projection = projection;
basicEffect.DiffuseColor = color.ToVector3();
basicEffect.Alpha = color.A / 255.0f;
GraphicsDevice device = basicEffect.GraphicsDevice;
device.DepthStencilState = DepthStencilState.Default;
if (color.A < 255)
{
// Set renderstates for alpha blended rendering.
device.BlendState = BlendState.AlphaBlend;
}
else
{
// Set renderstates for opaque rendering.
device.BlendState = BlendState.Opaque;
}
// Draw the model, using BasicEffect.
Draw(basicEffect);
}
#endregion
}
}