Пример #1
0
 public TgcPortalRenderingCell(string name, TgcConvexPolyhedron convexPolyhedron)
 {
     this.name = name;
     this.convexPolyhedron = convexPolyhedron;
     this.meshes = new List<TgcMesh>();
     this.connections = new List<TgcPortalRenderingConnection>();
 }
 /// <summary>
 /// Crear Manager
 /// </summary>
 /// <param name="scene">Escenario a administrar</param>
 public TgcPortalRenderingManager(TgcScene scene)
 {
     this.scene = scene;
     this.cells = new List<TgcPortalRenderingCell>();
     this.portals = new List<TgcPortalRenderingPortal>();
     this.frustumConvexPolyhedon = new TgcConvexPolyhedron();
 }
Пример #3
0
 /// <summary>
 /// Indica si un punto se encuentra dentro de un Cuerpo Convexo.
 /// Los planos del Cuerpo Convexo deben apuntar hacia adentro.
 /// Es más ágil que llamar a classifyPointConvexPolyhedron()
 /// </summary>
 /// <param name="q">Punto a clasificar</param>
 /// <param name="polyhedron">Cuerpo Convexo</param>
 /// <returns>True si se encuentra adentro.</returns>
 public static bool testPointConvexPolyhedron(Vector3 q, TgcConvexPolyhedron polyhedron)
 {
     for (int i = 0; i < polyhedron.Planes.Length; i++)
     {
         //Si el punto está detrás de algún plano, entonces está afuera
         if (TgcCollisionUtils.classifyPointPlane(q, polyhedron.Planes[i]) == PointPlaneResult.BEHIND)
         {
             return(false);
         }
     }
     //Si está delante de todos los planos, entonces está adentro.
     return(true);
 }
Пример #4
0
        /// <summary>
        /// Clasifica un BoundingBox respecto de un Cuerpo Convexo.
        /// Los planos del Cuerpo Convexo deben apuntar hacia adentro.
        /// </summary>
        /// <param name="polyhedron">Cuerpo convexo</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>Resultado de la clasificación</returns>
        public static ConvexPolyhedronResult classifyConvexPolyhedronAABB(TgcConvexPolyhedron polyhedron, TgcBoundingBox aabb)
        {
            int totalIn = 0;

            Plane[] polyhedronPlanes = polyhedron.Planes;

            // get the corners of the box into the vCorner array
            Vector3[] aabbCorners = aabb.computeCorners();

            // test all 8 corners against the polyhedron sides
            // if all points are behind 1 specific plane, we are out
            // if we are in with all points, then we are fully in
            for (int p = 0; p < polyhedronPlanes.Length; ++p)
            {
                int inCount = 8;
                int ptIn    = 1;

                for (int i = 0; i < 8; ++i)
                {
                    // test this point against the planes
                    if (classifyPointPlane(aabbCorners[i], polyhedronPlanes[p]) == PointPlaneResult.BEHIND)
                    {
                        ptIn = 0;
                        --inCount;
                    }
                }

                // were all the points outside of plane p?
                if (inCount == 0)
                {
                    return(ConvexPolyhedronResult.OUTSIDE);
                }

                // check if they were all on the right side of the plane
                totalIn += ptIn;
            }

            // so if iTotalIn is 6, then all are inside the view
            if (totalIn == 6)
            {
                return(ConvexPolyhedronResult.INSIDE);
            }

            // we must be partly in then otherwise
            return(ConvexPolyhedronResult.INTERSECT);
        }
Пример #5
0
        /// <summary>
        /// Clasifica un punto respecto de un Cuerpo Convexo de N caras.
        /// Puede devolver OUTSIDE o INSIDE (si es coincidente se considera como INSIDE).
        /// Los planos del Cuerpo Convexo deben apuntar hacia adentro.
        /// </summary>
        /// <param name="q">Punto a clasificar</param>
        /// <param name="polyhedron">Cuerpo Convexo</param>
        /// <returns>Resultado de la clasificación</returns>
        public static ConvexPolyhedronResult classifyPointConvexPolyhedron(Vector3 q, TgcConvexPolyhedron polyhedron)
        {
            bool             fistTime = true;
            PointPlaneResult lastC    = PointPlaneResult.BEHIND;
            PointPlaneResult c;

            for (int i = 0; i < polyhedron.Planes.Length; i++)
            {
                c = TgcCollisionUtils.classifyPointPlane(q, polyhedron.Planes[i]);

                if (c == PointPlaneResult.COINCIDENT)
                {
                    continue;
                }

                //guardar clasif para primera vez
                if (fistTime)
                {
                    fistTime = false;
                    lastC    = c;
                }


                //comparar con ultima clasif
                if (c != lastC)
                {
                    //basta con que haya una distinta para que este Afuera
                    return(ConvexPolyhedronResult.OUTSIDE);
                }
            }

            //Si todos dieron el mismo resultado, entonces esta adentro
            return(ConvexPolyhedronResult.INSIDE);
        }
        /// <summary>
        /// Cargar información de PortalRendering
        /// </summary>
        public TgcPortalRenderingManager loadFromData(TgcScene scene, TgcPortalRenderingData portalRenderingData)
        {
            TgcPortalRenderingManager manager = new TgcPortalRenderingManager(scene);

            //Crear dictionary de nombres de los meshes
            Dictionary<string, TgcMesh> meshDictionary = new Dictionary<string, TgcMesh>();
            foreach (TgcMesh mesh in scene.Meshes)
            {
                meshDictionary.Add(mesh.Name, mesh);
            }

            //Cargar celdas
            foreach (TgcPortalRenderingCellData cellData in portalRenderingData.cells)
            {
                //Crear cuerpo Convexo
                TgcConvexPolyhedron convexPoly = new TgcConvexPolyhedron();
                convexPoly.Planes = new Plane[cellData.facePlanes.Length / 4];
                for (int i = 0; i < convexPoly.Planes.Length; i++)
                {
                    convexPoly.Planes[i] = new Plane(
                        cellData.facePlanes[i * 4],
                        cellData.facePlanes[i * 4 + 1],
                        cellData.facePlanes[i * 4 + 2],
                        cellData.facePlanes[i * 4 + 3]
                        );
                }
                convexPoly.BoundingVertices = new Vector3[cellData.boundingVertices.Length / 3];
                for (int i = 0; i < convexPoly.BoundingVertices.Length; i++)
                {
                    convexPoly.BoundingVertices[i] = new Vector3(
                        cellData.boundingVertices[i * 3],
                        cellData.boundingVertices[i * 3 + 1],
                        cellData.boundingVertices[i * 3 + 2]
                        );
                }

                //Crear celda
                TgcPortalRenderingCell cell = new TgcPortalRenderingCell(cellData.name, convexPoly);
                manager.Cells.Add(cell);

                //Cargar meshes en celda
                for (int i = 0; i < cellData.meshes.Length; i++)
                {
                    TgcMesh mesh = meshDictionary[cellData.meshes[i]];
                    cell.Meshes.Add(mesh);
                }
            }

            //Cargar portales
            foreach (TgcPortalRenderingPortalData portalData in portalRenderingData.portals)
            {
                //BoundingBox del portal
                TgcBoundingBox boundingBox = new TgcBoundingBox(
                    new Vector3(portalData.pMin[0], portalData.pMin[1], portalData.pMin[2]),
                    new Vector3(portalData.pMax[0], portalData.pMax[1], portalData.pMax[2])
                    );

                //Crear portal
                TgcPortalRenderingPortal portal = new TgcPortalRenderingPortal(portalData.name, boundingBox);
                manager.Portals.Add(portal);

                //Cargar conexiones para celdas A y B
                TgcPortalRenderingCell cellA = manager.Cells[portalData.cellA];
                TgcPortalRenderingCell cellB = manager.Cells[portalData.cellB];

                //Poligono del portal para la celda A
                TgcConvexPolygon polygonA = new TgcConvexPolygon();
                polygonA.BoundingVertices = new Vector3[portalData.boundingVerticesA.Length / 3];
                for (int i = 0; i < polygonA.BoundingVertices.Length; i++)
                {
                    polygonA.BoundingVertices[i] = new Vector3(
                        portalData.boundingVerticesA[i * 3],
                        portalData.boundingVerticesA[i * 3 + 1],
                        portalData.boundingVerticesA[i * 3 + 2]
                        );
                }

                //Plano del portal para la celda A
                Plane planeA = TgcParserUtils.float4ArrayToPlane(portalData.planeA);

                //Crear conexion A
                TgcPortalRenderingConnection connectionA = new TgcPortalRenderingConnection(portal, cellB, polygonA, planeA);
                cellA.Connections.Add(connectionA);

                //Poligono del portal para la celda B
                TgcConvexPolygon polygonB = new TgcConvexPolygon();
                polygonB.BoundingVertices = new Vector3[portalData.boundingVerticesB.Length / 3];
                for (int i = 0; i < polygonB.BoundingVertices.Length; i++)
                {
                    polygonB.BoundingVertices[i] = new Vector3(
                        portalData.boundingVerticesB[i * 3],
                        portalData.boundingVerticesB[i * 3 + 1],
                        portalData.boundingVerticesB[i * 3 + 2]
                        );
                }

                //Plano del portal para la celda B
                Plane planeB = TgcParserUtils.float4ArrayToPlane(portalData.planeB);

                //Crear conexion B
                TgcPortalRenderingConnection connectionB = new TgcPortalRenderingConnection(portal, cellA, polygonB, planeB);
                cellB.Connections.Add(connectionB);
            }

            return manager;
        }
Пример #7
0
        /// <summary>
        /// Clasifica un punto respecto de un Cuerpo Convexo de N caras.
        /// Puede devolver OUTSIDE o INSIDE (si es coincidente se considera como INSIDE).
        /// Los planos del Cuerpo Convexo deben apuntar hacia adentro.
        /// </summary>
        /// <param name="q">Punto a clasificar</param>
        /// <param name="polyhedron">Cuerpo Convexo</param>
        /// <returns>Resultado de la clasificación</returns>
        public static ConvexPolyhedronResult classifyPointConvexPolyhedron(Vector3 q, TgcConvexPolyhedron polyhedron)
        {
            bool fistTime = true;
            PointPlaneResult lastC = PointPlaneResult.BEHIND;
            PointPlaneResult c;

            for (int i = 0; i < polyhedron.Planes.Length; i++)
            {
                c = TgcCollisionUtils.classifyPointPlane(q, polyhedron.Planes[i]);

                if (c == PointPlaneResult.COINCIDENT)
                    continue;

                //guardar clasif para primera vez
                if (fistTime)
                {
                    fistTime = false;
                    lastC = c;
                }

                //comparar con ultima clasif
                if (c != lastC)
                {
                    //basta con que haya una distinta para que este Afuera
                    return ConvexPolyhedronResult.OUTSIDE;
                }
            }

            //Si todos dieron el mismo resultado, entonces esta adentro
            return ConvexPolyhedronResult.INSIDE;
        }
Пример #8
0
        /// <summary>
        /// Clasifica un BoundingBox respecto de un Cuerpo Convexo.
        /// Los planos del Cuerpo Convexo deben apuntar hacia adentro.
        /// </summary>
        /// <param name="polyhedron">Cuerpo convexo</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>Resultado de la clasificación</returns>
        public static ConvexPolyhedronResult classifyConvexPolyhedronAABB(TgcConvexPolyhedron polyhedron, TgcBoundingBox aabb)
        {
            int totalIn = 0;
            Plane[] polyhedronPlanes = polyhedron.Planes;

            // get the corners of the box into the vCorner array
            Vector3[] aabbCorners = aabb.computeCorners();

            // test all 8 corners against the polyhedron sides
            // if all points are behind 1 specific plane, we are out
            // if we are in with all points, then we are fully in
            for (int p = 0; p < polyhedronPlanes.Length; ++p)
            {
                int inCount = 8;
                int ptIn = 1;

                for (int i = 0; i < 8; ++i)
                {
                    // test this point against the planes
                    if (classifyPointPlane(aabbCorners[i], polyhedronPlanes[p]) == PointPlaneResult.BEHIND)
                    {
                        ptIn = 0;
                        --inCount;
                    }
                }

                // were all the points outside of plane p?
                if (inCount == 0)
                {
                    return ConvexPolyhedronResult.OUTSIDE;
                }

                // check if they were all on the right side of the plane
                totalIn += ptIn;
            }

            // so if iTotalIn is 6, then all are inside the view
            if (totalIn == 6)
            {
                return ConvexPolyhedronResult.INSIDE;
            }

            // we must be partly in then otherwise
            return ConvexPolyhedronResult.INTERSECT;
        }
Пример #9
0
 /// <summary>
 /// Indica si un punto se encuentra dentro de un Cuerpo Convexo.
 /// Los planos del Cuerpo Convexo deben apuntar hacia adentro.
 /// Es más ágil que llamar a classifyPointConvexPolyhedron()
 /// </summary>
 /// <param name="q">Punto a clasificar</param>
 /// <param name="polyhedron">Cuerpo Convexo</param>
 /// <returns>True si se encuentra adentro.</returns>
 public static bool testPointConvexPolyhedron(Vector3 q, TgcConvexPolyhedron polyhedron)
 {
     for (int i = 0; i < polyhedron.Planes.Length; i++)
     {
         //Si el punto está detrás de algún plano, entonces está afuera
         if (TgcCollisionUtils.classifyPointPlane(q, polyhedron.Planes[i]) == PointPlaneResult.BEHIND)
         {
             return false;
         }
     }
     //Si está delante de todos los planos, entonces está adentro.
     return true;
 }