Fórum Sharpgames
 
 
  Forum  Criação de Jogo...  Gráficos 2D/3D  Rotacionar BoundingBox
Anterior Anterior
 
Próximo Próximo
Nova Entrada 28/8/2009 23:33
Não-resolvido
  brunoonline
9 tópicos
Sem Ranking


Rotacionar BoundingBox 
Olá pessoal,

    Alguém tem algum exemplo de como rotacionar uma BoundingBox  "corretamente" ?

Desde já agradeço
Bruno Gallego

Bruno Gallego
 
Nova Entrada 29/8/2009 2:44
  lcolnaghi
32 tópicos
8th Level Poster


Re: Rotacionar BoundingBox 
Modificado Por lcolnaghi  em 29/8/2009 0:35:50)
Bounding boxes no XNA são axis-aligned , isto é, tu não consegue rotacionar elas, devido elas serem alinhadas aos 3 eixos. tu só consegue transladar elas - isto evita custos mais pesados para checagem de interseção, principalmente.
Agora se tu quiser criar uma bounding box não alinhada, tu vai querer ou importar um modelo  ou criar as 6 faces do cubo na mão ( definir os pontos em relação a origem, ter uma matrix de transformação deste cubo, Texturas, etc... e implementar os métodos intersects, etc... ) =P
Já coloco uma classe implementando um cubo, usando vertex declaration.

EDIT:
Código-exemplo de como criar um cubo, criando vértice por vértice sem ser "alinhado ao eixo".

    class SimpleDrawableBox : DrawableGameComponent
    {

        VertexBuffer vb;

        VertexDeclaration vertexDecl;

        Matrix worldMatrix;

        Matrix viewMatrix;

        Matrix projMatrix;

        BasicEffect basicEffect;


        public Matrix WorldMatrix
        {

            get { return worldMatrix; }

            set { worldMatrix = value; }

        }
 
        public Matrix ViewMatrix
        {

            get { return viewMatrix; }

            set { viewMatrix = value; }

        }
 
        public Matrix ProjMatrix
        {

            get { return projMatrix; }

            set { projMatrix = value; }

        }
 

        public SimpleDrawableBox(Game game)

            : base(game)
        {
       
        }
 

        protected override void LoadContent()

        {

            GraphicsDevice device =

                ((GraphicsDeviceManager)Game.Services.GetService(
                    typeof(IGraphicsDeviceService))).GraphicsDevice;
 

            vertexDecl = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);

 

            vb = new VertexBuffer(device, VertexPositionNormalTexture.SizeInBytes * 24,

                                    BufferUsage.None);
 

            VertexPositionNormalTexture[] verts = new VertexPositionNormalTexture[24];

 
 
            //face 1

            verts[0] = new VertexPositionNormalTexture( new Vector3(-1, 1, -1), new Vector3(0, 1, 0), new Vector2(0, 0));

            verts[1] = new VertexPositionNormalTexture(new Vector3(1, 1, -1), new Vector3(0, 1, 0), new Vector2(1, 0));

            verts[2] = new VertexPositionNormalTexture(new Vector3(1, 1, 1), new Vector3(0, 1, 0),new Vector2(1, 1));

            verts[3] = new VertexPositionNormalTexture(new Vector3(-1, 1, 1), new Vector3(0, 1, 0), new Vector2(0, 1));

 
            //face 2

            verts[4] = new VertexPositionNormalTexture(

                new Vector3(1, -1, -1), new Vector3(1, 0, 0), new Vector2(0, 0));

            verts[5] = new VertexPositionNormalTexture(

                new Vector3(1, -1, 1), new Vector3(1, 0, 0), new Vector2(1, 0));

            verts[6] = new VertexPositionNormalTexture(

                new Vector3(1, 1, 1), new Vector3(1, 0, 0), new Vector2(1, 1));

            verts[7] = new VertexPositionNormalTexture(

                new Vector3(1, 1, -1), new Vector3(1, 0, 0), new Vector2(0, 1));

 
            //face 3

            verts[8] = new VertexPositionNormalTexture(

                new Vector3(1, -1, 1), new Vector3(0, 0, 1), new Vector2(0, 0));

            verts[9] = new VertexPositionNormalTexture(

                new Vector3(-1, -1, 1), new Vector3(0, 0, 1), new Vector2(1, 0));

            verts[10] = new VertexPositionNormalTexture(

                new Vector3(-1, 1, 1), new Vector3(0, 0, 1), new Vector2(1, 1));

            verts[11] = new VertexPositionNormalTexture(

                new Vector3(1, 1, 1), new Vector3(0, 0, 1), new Vector2(0, 1));

 
            //face 4
            verts[12] = new VertexPositionNormalTexture(

                new Vector3(-1, -1, -1), new Vector3(0, 0, -1), new Vector2(0, 0));

            verts[13] = new VertexPositionNormalTexture(

                new Vector3(1, -1, -1), new Vector3(0, 0, -1), new Vector2(1, 0));

            verts[14] = new VertexPositionNormalTexture(

                new Vector3(1, 1, -1), new Vector3(0, 0, -1), new Vector2(1, 1));

            verts[15] = new VertexPositionNormalTexture(

                new Vector3(-1, 1, -1), new Vector3(0, 0, -1), new Vector2(0, 1));

 
 
 
           //face 5
            verts[16] = new VertexPositionNormalTexture(

                new Vector3(-1, -1, 1), new Vector3(-1, 0, 0), new Vector2(0, 0));

            verts[17] = new VertexPositionNormalTexture(

                new Vector3(-1, -1, -1), new Vector3(-1, 0, 0), new Vector2(1, 0));

            verts[18] = new VertexPositionNormalTexture(

                new Vector3(-1, 1, -1), new Vector3(-1, 0, 0), new Vector2(1, 1));

            verts[19] = new VertexPositionNormalTexture(

               new Vector3(-1, 1, 1), new Vector3(-1, 0, 0), new Vector2(0, 1));

 
 
 
            //face 6
            verts[20] = new VertexPositionNormalTexture(

                new Vector3(1, -1, -1), new Vector3(0, -1, 0), new Vector2(0, 0));

            verts[21] = new VertexPositionNormalTexture(

                new Vector3(-1, -1, -1), new Vector3(0, -1, 0), new Vector2(1, 0));

            verts[22] = new VertexPositionNormalTexture(

                new Vector3(-1, -1, 1), new Vector3(0, -1, 0), new Vector2(1, 1));

            verts[23] = new VertexPositionNormalTexture(

                new Vector3(1, -1, 1), new Vector3(0, -1, 0), new Vector2(0, 1));

 
 
            vb.SetData(verts);
 
            worldMatrix = Matrix.Identity;
 
 

            //load basic effect

            basicEffect = new BasicEffect(device, null);

            basicEffect.Alpha = 1.0f;

            basicEffect.DiffuseColor = new Vector3(0.5f, 0.3f, 0.7f);

            basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);

            basicEffect.SpecularPower = 5.0f;

            basicEffect.AmbientLightColor = new Vector3(0.75f, 0.75f, 0.75f);

 

            basicEffect.DirectionalLight0.Enabled = true;

            basicEffect.DirectionalLight0.DiffuseColor = Vector3.One;

            basicEffect.DirectionalLight0.Direction =

                Vector3.Normalize(new Vector3(1.0f, -1.0f, -1.0f));

            basicEffect.DirectionalLight0.SpecularColor = Vector3.One;

 

            basicEffect.DirectionalLight1.Enabled = true;

            basicEffect.DirectionalLight1.DiffuseColor =

                new Vector3(0.5f, 0.5f, 0.5f);

            basicEffect.DirectionalLight1.Direction =

                Vector3.Normalize(new Vector3(-1.0f, -1.0f, 1.0f));

            basicEffect.DirectionalLight1.SpecularColor =

                new Vector3(0.5f, 0.5f, 0.5f);

 
            basicEffect.LightingEnabled = true;
 
            basicEffect.World = worldMatrix;
            basicEffect.View = viewMatrix;

            basicEffect.Projection = projMatrix;

 
 
 
 
            base.LoadContent();
        }
 
 
        public override void Update(GameTime gameTime)
        {
 

            //updates your world matrix

            //transformation sequence is always I.S.R.O.T. ( identity, scale, rotation, orbit, translation )

            worldMatrix = Matrix.CreateRotationY((float)gameTime.TotalRealTime.TotalSeconds) *    Matrix.CreateRotationZ((float)gameTime.TotalRealTime.TotalSeconds);

 
            base.Update(gameTime);
        }
 
        public override void Draw(GameTime gameTime)
        {

            GraphicsDevice device =

                ((GraphicsDeviceManager)Game.Services.GetService(
                    typeof(IGraphicsDeviceService))).GraphicsDevice;
 

            //device.RenderState.CullMode = CullMode.CullCounterClockwiseFace;

            device.VertexDeclaration = vertexDecl;

            device.Vertices[0].SetSource(vb, 0, VertexPositionNormalTexture.SizeInBytes);

 
            basicEffect.World = worldMatrix;
            basicEffect.View = viewMatrix;

            basicEffect.Projection = projMatrix;

 
            basicEffect.Begin();

            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)

            {
                pass.Begin();
 

            for (int x = 0; x < 6; x++)

            {
            
                        device.DrawPrimitives(PrimitiveType.TriangleFan, x * 4, 2);
 
            }
 
            pass.End();
            }
            basicEffect.End();
 
            base.Draw(gameTime);
        }
 
 
    }

 
Nova Entrada 30/8/2009 17:43
  brunoonline
9 tópicos
Sem Ranking


Re: Rotacionar BoundingBox 
Entendo icolnagi,

mas mesmo assim gostaria de "rotacionar" a boundingbox, no caso seria uma rotação escalando a bounding box.
Que dá eu sei que dá. Só que essa matemática vai ser pouco complicada pra mim.

Mesmo assim obrigado.

Para não perder mto tempo com isso, fiz o seguinte (Isso vai me servir temporáriamente, o problema é o desemepnho disso):

        public static BoundingBox GetBoundingBox( this Model model , Matrix worldMatrix )
        {
            var Max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            var Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int stride = part.VertexStride;
                    int numberv = part.NumVertices;
                    byte[] vertexData = new byte[stride * numberv];

                    mesh.VertexBuffer.GetData(vertexData);

                    for (int ndx = 0; ndx < vertexData.Length; ndx += stride)
                    {
                        float floatvaluex = BitConverter.ToSingle(vertexData, ndx);
                        float floatvaluey = BitConverter.ToSingle(vertexData, ndx + 4);
                        float floatvaluez = BitConverter.ToSingle(vertexData, ndx + 8);

                        Vector3 vectCurrentVertex = new Vector3(floatvaluex, floatvaluey, floatvaluez);
                        Vector3 vectWorldVertex = Vector3.Transform(vectCurrentVertex, worldMatrix);

                        if (vectWorldVertex.X < Min.X) Min.X = vectWorldVertex.X;
                        if (vectWorldVertex.Y < Min.Y) Min.Y = vectWorldVertex.Y;
                        if (vectWorldVertex.Z < Min.Z) Min.Z = vectWorldVertex.Z;

                        if (vectWorldVertex.X > Max.X) Max.X = vectWorldVertex.X;
                        if (vectWorldVertex.Y > Max.Y) Max.Y = vectWorldVertex.Y;
                        if (vectWorldVertex.Z > Max.Z) Max.Z = vectWorldVertex.Z;
                    }
                }
            }

            return new BoundingBox(Min, Max);
        }

Bruno Gallego
 
Nova Entrada 31/8/2009 0:15
  lcolnaghi
32 tópicos
8th Level Poster


Re: Rotacionar BoundingBox 
Modificado Por lcolnaghi  em 30/8/2009 21:31:04)

Opa. Agora entendi. o que tu quer não é rotacionar uma bounding box, mas sim escalonar ela, de acordo com o vetor min e max do teu modelo. Tu realmente não precisa calcular eles, uma vez que a própria classe bounding box do xna faz isso. tu vai querer usar algo do tipo assim :

public BoundingBox GetBoundingBoxFromModel(Model model)
{
  BoundingBox boundingBox = new BoundingBox()


  foreach (ModelMesh mesh in model.Meshes)
  {
    VertexPositionNormalTexture[] vertices =
      new VertexPositionNormalTexture[mesh.VertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes];

    mesh.VertexBuffer.GetData<VertexPositionNormalTexture>(vertices);

    Vector3[] vertexs = new Vector3[vertices.Length];

    for (int index = 0; index < vertexs.Length; index++)
    {
      vertexs[index] = vertices[index].Position;
    }

    boundingBox = BoundingBox.CreateMerged(boundingBox,
      BoundingBox.CreateFromPoints(vertexs));
  }

  return boundingBox;
}
Achei um artigo bem interessante sobre isso. Acho que é exatamente isso que tu estava procurando:

http://www.toymaker.info/Games/html/collisions.html


 
Anterior Anterior
 
Próximo Próximo
  Forum  Criação de Jogo...  Gráficos 2D/3D  Rotacionar BoundingBox
Logos do XBox 360, XNA e Games For Windows
Copyright 2006-2012 por SharpgamesPolítica de Privacidade  |  Termos de Uso