를 메쉬, 내 원하는 동작은 다음과 같습니다XNA 모델 구가
는- 구가 무대의 중앙에서 시작
- 는 그것의 4 개의 벽 중 하나와 충돌 할 때
- 은 0과 45도
간의 임의의 각도에서 반대 방향으로 다시 반송하는 임의의 방향으로 이동 Enter 키를 누르면 아래 그림에 나와 있지 않은 문제는 충돌하거나 튀는 대신 벽을 통과하는 것입니다.
볼 구형의 모델 위치를 업데이트 해 보았지만 여전히 절단하지 않았습니다. 나는 공의 반경을 100과 같이 큰 숫자로 설정하려고 시도했다. 그러나 움직임이 시작되어 벽에 부딪 치고 진동하기 전에 충돌한다.
소스 코드 (Ball.cs) : 나는 충돌 감지 문제를 해결할 때까지
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace _3D_Pong
{
class Ball
{
private Model model;
private Vector3 modelpos;
private Random random = new Random();
public Vector3 ModelPosition { get; set; }
private Vector3 FowardDirection { get; set; }
private float randomangle;
private int direction = 0;
private bool start = false;
private int v;
public Ball(Model m, Vector3 initial_position, int velocity = 30)
{
v = velocity;
model = m;
modelpos = initial_position;
randomangle = MathHelper.ToRadians(random.Next(0, 45));
direction = random.Next(1);
FowardDirection = Matrix.CreateRotationY(randomangle).Forward;
}
public void BeginMoving()
{
start = true;
}
private BoundingSphere BallsBounds()
{
Matrix worldTransform = Matrix.CreateTranslation(modelpos);
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
ModelMesh mesh = model.Meshes[0];
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
float[] vertexData = new float[vertexBufferSize/sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
for (int i = 0; i < vertexBufferSize/sizeof(float); i += vertexStride/sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), worldTransform);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
BoundingSphere sphere = BoundingSphere.CreateFromBoundingBox(new BoundingBox(min, max));
return sphere;
}
public void Draw(Camera camera, ArenaRenderer arena)
{
if (start)
{
bool predicate1, predicate2, predicate3, predicate4;
predicate1 = BallsBounds().Intersects(arena.FirstWall());
predicate2 = BallsBounds().Intersects(arena.SecondWall());
predicate3 = BallsBounds().Intersects(arena.ThirdWall());
predicate4 = BallsBounds().Intersects(arena.FourthWall());
if (predicate1 || predicate2 || predicate3 || predicate4)
{
if (direction == 0)
{
direction = 1;
randomangle = MathHelper.ToRadians(random.Next(0, 45));
FowardDirection = Matrix.CreateRotationY(randomangle).Forward;
}
else if (direction == 1)
{
direction = 0;
randomangle = MathHelper.ToRadians(random.Next(0, 45));
FowardDirection = Matrix.CreateRotationY(randomangle).Forward;
}
}
if (direction == 1)
{
modelpos += FowardDirection * v;
}
else
{
modelpos -= FowardDirection * v;
}
}
model.Draw(Matrix.CreateTranslation(modelpos), camera.View, camera.Projection);
}
}
}
소스 (Arena.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace _3D_Pong
{
class ArenaRenderer
{
private Model model;
public ArenaRenderer(Model m)
{
model = m;
}
public BoundingBox FirstWall()
{
Matrix worldTransform = Matrix.CreateTranslation(Vector3.Zero);
// Initialize minimum and maximum corners of the bounding box to max and min values
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
ModelMesh mesh = model.Meshes[0];
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
// Vertex buffer parameters
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
// Get vertex data as float
float[] vertexData = new float[vertexBufferSize/sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
// Iterate through vertices (possibly) growing bounding box, all calculations are done in world space
for (int i = 0; i < vertexBufferSize/sizeof(float); i += vertexStride/sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), worldTransform);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
// Create and return bounding box
return new BoundingBox(min, max);
}
public BoundingBox SecondWall()
{
Matrix worldTransform = Matrix.CreateTranslation(Vector3.Zero);
// Initialize minimum and maximum corners of the bounding box to max and min values
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
ModelMesh mesh = model.Meshes[1];
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
// Vertex buffer parameters
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
// Get vertex data as float
float[] vertexData = new float[vertexBufferSize/sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
// Iterate through vertices (possibly) growing bounding box, all calculations are done in world space
for (int i = 0; i < vertexBufferSize/sizeof(float); i += vertexStride/sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), worldTransform);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
// Create and return bounding box
return new BoundingBox(min, max);
}
public BoundingBox ThirdWall()
{
Matrix worldTransform = Matrix.CreateTranslation(Vector3.Zero);
// Initialize minimum and maximum corners of the bounding box to max and min values
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
ModelMesh mesh = model.Meshes[2];
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
// Vertex buffer parameters
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
// Get vertex data as float
float[] vertexData = new float[vertexBufferSize/sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
// Iterate through vertices (possibly) growing bounding box, all calculations are done in world space
for (int i = 0; i < vertexBufferSize/sizeof(float); i += vertexStride/sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), worldTransform);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
// Create and return bounding box
return new BoundingBox(min, max);
}
public BoundingBox FourthWall()
{
Matrix worldTransform = Matrix.CreateTranslation(Vector3.Zero);
// Initialize minimum and maximum corners of the bounding box to max and min values
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
ModelMesh mesh = model.Meshes[3];
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
// Vertex buffer parameters
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
// Get vertex data as float
float[] vertexData = new float[vertexBufferSize/sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
// Iterate through vertices (possibly) growing bounding box, all calculations are done in world space
for (int i = 0; i < vertexBufferSize/sizeof(float); i += vertexStride/sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), worldTransform);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
// Create and return bounding box
return new BoundingBox(min, max);
}
public void Draw(Camera camera)
{
model.Draw(Matrix.CreateTranslation(Vector3.Zero), camera.View, camera.Projection);
}
}
}
은 내가 패를 구현하지 않은 . 정보가 누락 된 경우 의견을 남기십시오. 나는 내가 생각할 수있는 모든 것을 시도했습니다.
각 벽의 경계에 대해 하나의 기능이 있으므로 변경했습니다.
이1) 번 이상 동일한 기능 이상을 작성해야 두 번째 중지하고 재고 :)
팁,
public BoundingBox GetWallBounds(int index)
{
Matrix worldTransform = Matrix.CreateTranslation(Vector3.Zero);
// Initialize minimum and maximum corners of the bounding box to max and min values
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
ModelMesh mesh = model.Meshes[index];
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
// Vertex buffer parameters
int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
int vertexBufferSize = meshPart.NumVertices * vertexStride;
// Get vertex data as float
float[] vertexData = new float[vertexBufferSize/sizeof(float)];
meshPart.VertexBuffer.GetData<float>(vertexData);
// Iterate through vertices (possibly) growing bounding box, all calculations are done in world space
for (int i = 0; i < vertexBufferSize/sizeof(float); i += vertexStride/sizeof(float))
{
Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), worldTransform);
min = Vector3.Min(min, transformedPosition);
max = Vector3.Max(max, transformedPosition);
}
}
// Create and return bounding box
return new BoundingBox(min, max);
}
좋은 서면 답변에 대한 제안 +1. –