Exemplo n.º 1
0
        /// <summary>
        /// Inserta el cuerpo con el volúmen especificado en la jerarquía
        /// </summary>
        /// <param name="newBody">Cuerpo</param>
        /// <param name="newVolume">Volúmen</param>
        public void Insert(RigidBody newBody, BoundingSphere newVolume)
        {
            if (this.IsLeaf)
            {
                // Si estamos en una rama final, la única opción es crear dos nuevos hijos y poner el nuevo cuerpo en uno de ellos

                // El primer hijo es una copia de este nodo
                this.FirstChildren = new BVHNode(this, Volume, Body);

                // El segundo hijo tiene la información del nuevo cuerpo
                this.LastChildren = new BVHNode(this, newVolume, newBody);

                // Limpiamos el cuerpo de esta rama, pues ahora está en el primer hijo
                this.Body = null;

                // Recalcular el volumen de este nodo
                this.RecalculateBoundingVolume();
            }
            else
            {
                // Si no somos rama final, hay que decidir qué hijo se quedará con el cuerpo
                if (this.GetGrowth(this.FirstChildren.Volume, newVolume) <
                    this.GetGrowth(this.LastChildren.Volume, newVolume))
                {
                    this.FirstChildren.Insert(newBody, newVolume);
                }
                else
                {
                    this.LastChildren.Insert(newBody, newVolume);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Busca los contactos potenciales entre este nodo y el nodo especificado, rellenando la lista de contactos potenciales facilitada, hasta el límite especificado
        /// </summary>
        /// <param name="other">Nodo con el que comparar</param>
        /// <param name="contacts">Lista de contactos poteciales</param>
        /// <param name="limit">Límite</param>
        /// <returns>Devuelve el número de contactos potenciales</returns>
        protected int GetPotentialContactsWith(ref BVHNode other, ref List <PotentialContact> contacts, int limit)
        {
            // Si no hay contacto entre los volúmenes superiores o el límite es 0, se termina el proceso
            if (!this.Overlaps(other) || limit == 0)
            {
                return(0);
            }

            // Si ambos son ramas finales, hay un contacto potencial
            if (this.IsLeaf && other.IsLeaf)
            {
                contacts.Add(new PotentialContact(this.Body, other.Body));

                return(1);
            }

            // Determinar por cual nodo descender
            // Si uno es rama final, se desciende por el otro
            // Si ambos son ramas intermedias, entonces se debe usar el más grande por ser el más probable
            if (other.IsLeaf || (!this.IsLeaf && this.Volume.Volume() >= other.Volume.Volume()))
            {
                // Bajar por nuestro primer hijo
                int count = this.FirstChildren.GetPotentialContactsWith(ref other, ref contacts, limit);

                // Comprobar si tenemos suficiente espacio para continuar añadiendo contactos parciales
                if (limit > count)
                {
                    return(count + this.LastChildren.GetPotentialContactsWith(ref other, ref contacts, limit - count));
                }
                else
                {
                    return(count);
                }
            }
            else
            {
                // Bajar por el primer hijo del otro
                int count = this.GetPotentialContactsWith(ref other.FirstChildren, ref contacts, limit);

                // Comprobar si queda espacio
                if (limit > count)
                {
                    return(count + this.GetPotentialContactsWith(ref other.LastChildren, ref contacts, limit - count));
                }
                else
                {
                    return(count);
                }
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="parent">Nodo superior</param>
 /// <param name="volume">Volumen</param>
 /// <param name="body">Cuerpo</param>
 public BVHNode(BVHNode parent, BoundingSphere volume, RigidBody body)
 {
     this.Parent = parent;
     this.Volume = volume;
     this.Body   = body;
 }
Exemplo n.º 4
0
 /// <summary>
 /// Busca contactos entre los nodos de la jerarquía y el nodo especificado
 /// </summary>
 /// <param name="other">Nodo con cuyo volúmen se compara</param>
 /// <returns>Devuelve verdadero si existe contacto</returns>
 protected bool Overlaps(BVHNode other)
 {
     return(this.Volume.Contains(other.Volume) != ContainmentType.Disjoint);
 }