Example #1
0
        public OctreeNode crearOctree(List <TgcMesh> modelos, TgcBoundingBox sceneBounds)
        {
            OctreeNode rootNode = new OctreeNode();

            Vector3 pMax = sceneBounds.PMax;
            Vector3 pMin = sceneBounds.PMin;

            //Calcular punto medio y centro
            Vector3 midSize = sceneBounds.calculateAxisRadius();
            Vector3 center  = sceneBounds.calculateBoxCenter();

            //iniciar generacion recursiva de octree
            doSectorOctreeX(rootNode, center, midSize, 0, modelos);

            //podar nodos innecesarios
            deleteEmptyNodes(rootNode.children);

            //eliminar hijos que subdividen sin necesidad
            //deleteSameMeshCountChilds(rootNode);

            //imprimir por consola el octree
            //printDebugOctree(rootNode);

            //imprimir estadisticas de debug
            //printEstadisticasOctree(rootNode);

            return(rootNode);
        }
Example #2
0
        public QuadtreeNode crearQuadtree(List <TgcMesh> TgcMeshs, TgcBoundingBox sceneBounds)
        {
            QuadtreeNode rootNode = new QuadtreeNode();

            //Calcular punto medio y centro
            Vector3 midSize = sceneBounds.calculateAxisRadius();
            Vector3 center  = sceneBounds.calculateBoxCenter();

            //iniciar generacion recursiva de octree
            doSectorQuadtreeX(rootNode, center, midSize, 0, TgcMeshs);

            //podar nodos innecesarios
            optimizeSectorQuadtree(rootNode.children);

            //imprimir por consola el octree
            //printDebugQuadtree(rootNode);

            //imprimir estadisticas de debug
            //printEstadisticasQuadtree(rootNode);

            return(rootNode);
        }
Example #3
0
        /// <summary>
        /// Colisiona un BoundingSphere en movimiento contra el BoundingBox.
        /// Si hay colision devuelve el instante t de colision mas proximo y el punto q de colision mas cercano
        /// </summary>
        /// <param name="sphere">BoundingSphere</param>
        /// <param name="movementVector">movimiento del BoundingSphere</param>
        /// <param name="t">Menor instante de colision</param>
        /// <param name="q">Punto mas cercano de colision</param>
        /// <param name="n">Normal de la cara colisionada</param>
        /// <returns>True si hay colision</returns>
        public override bool intersectMovingSphere(TgcBoundingSphere sphere, Vector3 movementVector, TgcBoundingSphere movementSphere, out float t, out Vector3 q, out Vector3 n)
        {
            t = -1f;
            q = Vector3.Empty;
            n = Vector3.Empty;

            // Compute the AABB resulting from expanding b by sphere radius r
            TgcBoundingBox.AABBStruct e = aabb.toStruct();
            e.min.X -= sphere.Radius; e.min.Y -= sphere.Radius; e.min.Z -= sphere.Radius;
            e.max.X += sphere.Radius; e.max.Y += sphere.Radius; e.max.Z += sphere.Radius;

            // Intersect ray against expanded AABB e. Exit with no intersection if ray
            // misses e, else get intersection point p and time t as result
            Vector3 p;

            TgcRay.RayStruct ray = new TgcRay.RayStruct();
            ray.origin    = sphere.Center;
            ray.direction = movementVector;
            if (!intersectRayAABB(ray, e, out t, out p) || t > 1.0f)
            {
                return(false);
            }

            // Compute which min and max faces of b the intersection point p lies
            // outside of. Note, u and v cannot have the same bits set and
            // they must have at least one bit set among them
            int i = 0;

            int[] sign = new int[3];
            if (p.X < aabb.PMin.X)
            {
                sign[0] = -1;
                i++;
            }
            if (p.X > aabb.PMax.X)
            {
                sign[0] = 1;
                i++;
            }
            if (p.Y < aabb.PMin.Y)
            {
                sign[1] = -1;
                i++;
            }
            if (p.Y > aabb.PMax.Y)
            {
                sign[1] = 1;
                i++;
            }
            if (p.Z < aabb.PMin.Z)
            {
                sign[2] = -1;
                i++;
            }
            if (p.Z > aabb.PMax.Z)
            {
                sign[2] = 1;
                i++;
            }



            //Face
            if (i == 1)
            {
                n = new Vector3(sign[0], sign[1], sign[2]);
                q = sphere.Center + t * movementVector - sphere.Radius * n;
                return(true);
            }

            // Define line segment [c, c+d] specified by the sphere movement
            Segment seg = new Segment(sphere.Center, sphere.Center + movementVector);

            //Box extent and center
            Vector3 extent = aabb.calculateAxisRadius();
            Vector3 center = aabb.PMin + extent;

            //Edge
            if (i == 2)
            {
                //Generar los dos puntos extremos del Edge
                float[] extentDir = new float[] { sign[0], sign[1], sign[2] };
                int     zeroIndex = sign[0] == 0 ? 0 : (sign[1] == 0 ? 1 : 2);
                extentDir[zeroIndex] = 1;
                Vector3 capsuleA = center + new Vector3(extent.X * extentDir[0], extent.Y * extentDir[1], extent.Z * extentDir[2]);
                extentDir[zeroIndex] = -1;
                Vector3 capsuleB = center + new Vector3(extent.X * extentDir[0], extent.Y * extentDir[1], extent.Z * extentDir[2]);

                //Colision contra el Edge hecho Capsula
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, sphere.Radius), out t))
                {
                    n = new Vector3(sign[0], sign[1], sign[2]);
                    n.Normalize();
                    q = sphere.Center + t * movementVector - sphere.Radius * n;
                    return(true);
                }
            }



            //Vertex
            if (i == 3)
            {
                float   tmin     = float.MaxValue;
                Vector3 capsuleA = center + new Vector3(extent.X * sign[0], extent.Y * sign[1], extent.Z * sign[2]);
                Vector3 capsuleB;

                capsuleB = center + new Vector3(extent.X * -sign[0], extent.Y * sign[1], extent.Z * sign[2]);
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, sphere.Radius), out t))
                {
                    tmin = TgcCollisionUtils.min(t, tmin);
                }

                capsuleB = center + new Vector3(extent.X * sign[0], extent.Y * -sign[1], extent.Z * sign[2]);
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, sphere.Radius), out t))
                {
                    tmin = TgcCollisionUtils.min(t, tmin);
                }

                capsuleB = center + new Vector3(extent.X * sign[0], extent.Y * sign[1], extent.Z * -sign[2]);
                if (intersectSegmentCapsule(seg, new Capsule(capsuleA, capsuleB, sphere.Radius), out t))
                {
                    tmin = TgcCollisionUtils.min(t, tmin);
                }

                if (tmin == float.MaxValue)
                {
                    return(false);                        // No intersection
                }
                t = tmin;
                n = new Vector3(sign[0], sign[1], sign[2]);
                n.Normalize();
                q = sphere.Center + t * movementVector - sphere.Radius * n;
                return(true); // Intersection at time t == tmin
            }


            return(false);
        }
Example #4
0
 public void setSceneBounds(TgcBoundingBox sceneBounds)
 {
     this.sceneBounds  = sceneBounds;
     this.sceneCenter  = sceneBounds.calculateBoxCenter();
     this.sceneExtents = sceneBounds.calculateAxisRadius();
 }