A estrutura "BoundingSphere" define uma esfera e representa um espaço ocupado por ela. Benefícios no uso de “BoundingSphere” para detecção de colisão: - Checagem de colisão de esfera para esfera é muito rápida.
- Mover uma "BoundingSphere" não é um processo custoso; é preciso apenas atribuir um valor ao centro.
- Diferentemente de uma “BoundingBox”, uma “BoundingSphere” não precisa ser recriada se o modelo, textura, etc, for rotacionada. Em caso de aumento de “scale”, basta alterar o valor do raio.
- “BoundingSphere” é uma estrutura compacta, armazenando apenas um vetor representando seu centro e um raio.
Desvantagem em utilizar “BoundingSphere” para detecção de colisão: · A maioria dos modelos, das texturas, etc, não têm o formato esférico(como as que serão usadas na demonstração a seguir) implicando em espaços vazios acarretando resultados de intersecção inexistente. Supondo que em seu jogo, exista estes 2 bonecos: 
"BoundingSphere" não seria a opção mais adequada de detecção de colisão. Para checar colisão entre 2 esferas, o critério a seguir é levado em conta : Distância entre os centros é comparado com a soma dos raios de ambas as esferas. Se a Distância for menor que a soma dos 2 raios, significa que há colisão, caso a Distância seja maior ou igual a soma dos 2 raios, não há colisão; observe como poderia ficar isso no código: if(Vector3.Distance(this.boundingSphere1.Center, this.boundingSphere2.Center) <(this.boundingSphere1.Radius + this.boundingSphere2.Radius)) { //colidiu } else { //nao colidiu } Breve funcionamento da Estrutura BoundingSphere: A estrutura BoundingSphere possui 2 campos públicos: public Vector3 Center public float Radius
Center - define o ponto central da esfera; geralmente - em objetos móveis - será necessária a atualização do centro no método Update. Radius - define o raio da esfera; caso o "scale" do objeto sofra modificação será necessário a atualização do raio. Método Intersects da Estrutura BoundingSphere: O método Intersects da Estrutura BoundingSphere provê teste de intersecção com Classes que delimitam volumes ou nao. Bounding Volume: - BoundingBox
- BoundingFrustum
- BoundingSphere
Em "Bounding Volume" o método Intersects retorna true ou false. Non-Bounding Volume: Com as classes "Non-Bounding Volume" o método intersects nao retorna true ou false. O valor de retorna é bem especifico de cada tipo de estrtura e o abordamento fugiria do escopo do artigo. Fonte consultada(Collision Detection Overview): http://msdn2.microsoft.com/en-us/library/bb313876.aspx
Criando um simples protótipo para fixar e demonstrar os conhecimentos obtidos Serão utilizadas, no protótipo, as esferas:  
A esfera colorida(esfera1) ficará fixa em algum local pré-definido no método “Initialize”. A esfera azul(esfera2) ficará acompanhando a seta do mouse. Quando existir intersecção entre as esferas, a bola (guiada pelo mouse ) será tingida de vermelho. Código: public class Game1 : Microsoft.Xna.Framework.Game {//BoundingSphere atribuida a esfera1 BoundingSphere boundingSphere1; //BoundingSphere atribuida a esfera2 BoundingSphere boundingSphere2; Texture2D esfera1; // esfera que ficará fixa na tela Texture2D esfera2; // esfera que será guiada pelo Mouse Color corEsfera2; Vector2 posicaoEsfera1; Vector2 posicaoEsfera2; ...
protected override void Initialize() {... this.boundingSphere1 = new BoundingSphere(); //posicao, da esfera1, aonde será colocada na tela this.posicaoEsfera1 = new Vector2(250, 150); this.boundingSphere2 = new BoundingSphere(); this.corEsfera2 = Color.White; //Raio da esfera1 this.boundingSphere1.Radius = 150; //Raio da esfera2 this.boundingSphere2.Radius = 70; ...
} Obs.: Os raios escolhidos tanto para a boundingSphere1 e boundingSphere2 , foram escolhidos mediante a observações feitas em um editor de imagem. protected override void LoadContent() {... /*Ponto central da esfera. É a partir deste ponto, que *a esfera será definida mediante ao tamanho do raio */ /* Definindo o centro da esfera a partir de sua posicao(levando em conta que a sua posicao mostra a imagem com "origin" no canto superior mais a esquerda). */ this.boundingSphere1.Center = new Vector3( this.posicaoEsfera1.X + this.boundingSphere1.Radius, this.posicaoEsfera1.Y + this.boundingSphere1.Radius, 0);
} protected override void Update(GameTime gameTime) {... //Esfera2 sendo guiada pelo Mouse this.posicaoEsfera2 = new Vector2(Mouse.GetState().X, Mouse.GetState().Y); //Definindo o centro da esfera2 this.boundingSphere2.Center = new Vector3( this.posicaoEsfera2.X + (this.esfera2.Width / 2), this.posicaoEsfera2.Y + (this.esfera2.Height / 2), 0); /* * Caso nao existesse uma estrutura "BoundingSphere" ofericida pelo * framework do XNA, você utilizaria a teoria * passada no artigo(dita anteriormente), e implementaria algo semelhante * com isso: if(Vector3.Distance(this.boundingSphere1.Center, this.boundingSphere2.Center) < (this.boundingSphere1.Radius + this.boundingSphere2.Radius)) * * Teste todo o if de cima, trocando com Intersects aplicado abaixo. * E verá que a colisão funcionou da mesma maneira */ if (this.boundingSphere1.Intersects(this.boundingSphere2)) {//colidiu this.corEsfera2 = Color.Red;
} else {// nao colidiu this.corEsfera2 = Color.White;
} ...
} Projeto finalizado(construído com XNA 2.0): colisao_boundingsphere.zip 150557 bytes Confira um jogo utilizando a Estrutura BoundingSphere:
Dúvidas, Críticas e Sugestões são bem-vindas. Obrigado! |