示例#1
0
        /// <summary>
        /// Renderizar en forma optimizado utilizando el Quadtree para hacer FrustumCulling
        /// </summary>
        public void render(TgcFrustum frustum, bool debugEnabled)
        {
            Vector3 pMax = sceneBounds.PMax;
            Vector3 pMin = sceneBounds.PMin;
            findVisibleMeshes(frustum, quadtreeRootNode,
                pMin.X, pMin.Y, pMin.Z,
                pMax.X, pMax.Y, pMax.Z);

            //Renderizar
            foreach (TgcMesh mesh in modelos)
            {
                if (mesh.Enabled)
                {
                    mesh.render();
                    mesh.Enabled = false;
                }
            }

            if (debugEnabled)
            {
                foreach (TgcDebugBox debugBox in debugQuadtreeBoxes)
                {
                    debugBox.render();
                }
            }
        }
示例#2
0
        public AdaptativeHeightmap(float initialScaleXZ, float initialScaleY, float initialThreshold)
        {
            this.Enabled = true;
            this.AlphaBlendEnable = false;
            this.frustum = new TgcFrustum();

            this.Threshold = initialThreshold;
            this.ScaleY = initialScaleY;
            this.ScaleXZ = initialScaleXZ;
        }
示例#3
0
        /// <summary>
        /// Indica si un Punto colisiona con el Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="p">Punto</param>
        /// <returns>True si el Punto está adentro del Frustum</returns>
        public static bool testPointFrustum(TgcFrustum frustum, Vector3 p)
        {
            bool result = true;

            Plane[] frustumPlanes = frustum.FrustumPlanes;

            for (int i = 0; i < 6; i++)
            {
                if (distPointPlane(p, frustumPlanes[i]) < 0)
                {
                    return(false);
                }
            }
            return(result);
        }
示例#4
0
        /// <summary>
        /// Clasifica un BoundingBox respecto del Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>Resultado de la clasificación</returns>
        public static FrustumResult classifyFrustumAABB(TgcFrustum frustum, TgcBoundingBox aabb)
        {
            int totalIn = 0;

            Plane[] frustumPlanes = frustum.FrustumPlanes;

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

            // test all 8 corners against the 6 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 < 6; ++p)
            {
                int inCount = 8;
                int ptIn    = 1;

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

                // were all the points outside of plane p?
                if (inCount == 0)
                {
                    return(FrustumResult.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(FrustumResult.INSIDE);
            }

            // we must be partly in then otherwise
            return(FrustumResult.INTERSECT);
        }
示例#5
0
        /// <summary>
        /// Indica si un BoundingSphere colisiona con el Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="sphere">BoundingSphere</param>
        /// <returns>Resultado de la colisión</returns>
        public static FrustumResult classifyFrustumSphere(TgcFrustum frustum, TgcBoundingSphere sphere)
        {
            float         distance;
            FrustumResult result = FrustumResult.INSIDE;

            Plane[] frustumPlanes = frustum.FrustumPlanes;

            for (int i = 0; i < 6; i++)
            {
                distance = distPointPlane(sphere.Center, frustumPlanes[i]);

                if (distance < -sphere.Radius)
                {
                    return(FrustumResult.OUTSIDE);
                }
                else if (distance < sphere.Radius)
                {
                    result = FrustumResult.INTERSECT;
                }
            }
            return(result);
        }
示例#6
0
        /// <summary>
        /// Recorrer recursivamente el Quadtree para encontrar los nodos visibles
        /// </summary>
        private void findVisibleMeshes(TgcFrustum frustum, QuadtreeNode node,
            float boxLowerX, float boxLowerY, float boxLowerZ,
            float boxUpperX, float boxUpperY, float boxUpperZ)
        {
            QuadtreeNode[] children = node.children;

            //es hoja, cargar todos los meshes
            if (children == null)
            {
                selectLeafMeshes(node);
            }

            //recursividad sobre hijos
            else
            {
                float midX = FastMath.Abs((boxUpperX - boxLowerX) / 2);
                float midZ = FastMath.Abs((boxUpperZ - boxLowerZ) / 2);

                //00
                testChildVisibility(frustum, children[0], boxLowerX + midX, boxLowerY, boxLowerZ + midZ, boxUpperX, boxUpperY, boxUpperZ);

                //01
                testChildVisibility(frustum, children[1], boxLowerX + midX, boxLowerY, boxLowerZ, boxUpperX, boxUpperY, boxUpperZ - midZ);

                //10
                testChildVisibility(frustum, children[2], boxLowerX, boxLowerY, boxLowerZ + midZ, boxUpperX - midX, boxUpperY, boxUpperZ);

                //11
                testChildVisibility(frustum, children[3], boxLowerX, boxLowerY, boxLowerZ, boxUpperX - midX, boxUpperY, boxUpperZ - midZ);

            }
        }
示例#7
0
        /// <summary>
        /// Indica si un BoundingSphere colisiona con el Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="sphere">BoundingSphere</param>
        /// <returns>Resultado de la colisión</returns>
        public static FrustumResult classifyFrustumSphere(TgcFrustum frustum, TgcBoundingSphere sphere)
        {
            float distance;
            FrustumResult result = FrustumResult.INSIDE;
            Plane[] frustumPlanes = frustum.FrustumPlanes;

            for (int i = 0; i < 6; i++)
            {
                distance = distPointPlane(sphere.Center, frustumPlanes[i]);

                if (distance < - sphere.Radius)
                {
                    return FrustumResult.OUTSIDE;
                }
                else if (distance < sphere.Radius)
                {
                    result = FrustumResult.INTERSECT;
                }

            }
            return result;
        }
示例#8
0
        /// <summary>
        /// Crea todos los modulos necesarios de la aplicacion
        /// </summary>
        internal void initGraphics(MainForm mainForm, Control panel3d)
        {
            this.mainForm = mainForm;
            this.panel3d = panel3d;
            this.fullScreenPanel = new FullScreenPanel();
            panel3d.Focus();

            //Iniciar graficos
            this.tgcD3dDevice = new TgcD3dDevice(panel3d);
            this.texturesManager = new TgcTexture.Manager();
            this.tgcD3dDevice.OnResetDevice(tgcD3dDevice.D3dDevice, null);

            //Iniciar otras herramientas
            this.texturesPool = new TgcTexture.Pool();
            this.logger = new Logger(mainForm.LogConsole);
            this.text3d = new TgcDrawText(tgcD3dDevice.D3dDevice);
            this.tgcD3dInput = new TgcD3dInput(mainForm, panel3d);
            this.fpsCamera = new TgcFpsCamera();
            this.rotCamera = new TgcRotationalCamera();
            this.thirdPersonCamera = new TgcThirdPersonCamera();
            this.axisLines = new TgcAxisLines(tgcD3dDevice.D3dDevice);
            this.userVars = new TgcUserVars(mainForm.getDataGridUserVars());
            this.modifiers = new TgcModifiers(mainForm.getModifiersPanel());
            this.elapsedTime = -1;
            this.frustum = new TgcFrustum();
            this.mp3Player = new TgcMp3Player();
            this.directSound = new TgcDirectSound();
            this.fog = new TgcFog();
            this.currentCamera = this.rotCamera;
            this.customRenderEnabled = false;
            this.drawer2D = new TgcDrawer2D();
            this.shaders = new TgcShaders();

            //toogles
            this.rotCamera.Enable = true;
            this.fpsCamera.Enable = false;
            this.thirdPersonCamera.Enable = false;
            this.fpsCounterEnable = true;
            this.axisLines.Enable = true;

            //Cargar algoritmos
            exampleLoader = new ExampleLoader();
            examplesDir = System.Environment.CurrentDirectory + "\\" + ExampleLoader.EXAMPLES_DIR + "\\";
            examplesMediaDir = examplesDir + "Media" + "\\";
            alumnoEjemplosDir = System.Environment.CurrentDirectory + "\\" + "AlumnoEjemplos" + "\\";
            alumnoEjemplosMediaDir = alumnoEjemplosDir + "AlumnoMedia" + "\\";
            exampleLoader.loadExamplesInGui(mainForm.TreeViewExamples, new string[] { examplesDir, alumnoEjemplosDir });

            //Cargar shaders del framework
            this.shaders.loadCommonShaders();

            //Cargar ejemplo default
            TgcExample defaultExample = exampleLoader.getExampleByName(mainForm.Config.defaultExampleName, mainForm.Config.defaultExampleCategory);
            executeExample(defaultExample);
        }
示例#9
0
        /// <summary>
        /// Clasifica un BoundingBox respecto del Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="aabb">BoundingBox</param>
        /// <returns>Resultado de la clasificación</returns>
        public static FrustumResult classifyFrustumAABB(TgcFrustum frustum, TgcBoundingBox aabb)
        {
            int totalIn = 0;
            Plane[] frustumPlanes = frustum.FrustumPlanes;

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

            // test all 8 corners against the 6 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 < 6; ++p)
            {
                int inCount = 8;
                int ptIn = 1;

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

                // were all the points outside of plane p?
                if (inCount == 0)
                {
                    return FrustumResult.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 FrustumResult.INSIDE;
            }

            // we must be partly in then otherwise
            return FrustumResult.INTERSECT;
        }
示例#10
0
文件: Triangle.cs 项目: faloi/tegece
        public bool shouldSplit(ref Matrix wvp, ref TgcFrustum bf)
        {
            //[!]Cambiar para que los cambios no sean tan bruscos
            /*
             * Determina si un triángulo debe dividirse o no, midiendo la distancia
             *(screen distance) entre su left point y su center point. Cerca del frustum, esta
             *distancia es más grande. Si supera un threshold se considera suficiente para dividirlo.
            */
            bool shouldSplit = false;
            if (TgcCollisionUtils.testPointFrustum(bf, centerPos) //si colisiona con center, left, o right...
                || TgcCollisionUtils.testPointFrustum(bf, lPos)
                || TgcCollisionUtils.testPointFrustum(bf, rPos)) {
                Vector4 lScreenPos = Vector4.Transform(new Vector4(lPos.X, lPos.Y, lPos.Z, 1), wvp);
                Vector4 aScreenPos = Vector4.Transform(new Vector4(centerPos.X, centerPos.Y, centerPos.Z, 1), wvp);
                lScreenPos = lScreenPos * (1 / lScreenPos.W);
                aScreenPos = aScreenPos * (1 / aScreenPos.W);

                Vector4 difference = lScreenPos - aScreenPos;
                Vector2 screenDifference = new Vector2(difference.X, difference.Y);

                //(menos tolerancia => más calidad)
                if (screenDifference.Length() > map.Threshold)
                    shouldSplit = true;
            }

            return shouldSplit;
        }
 public bool collidesWithFrustum(TgcFrustum frustum)
 {
     TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, this.tp.BoundingBox);
     if (result != TgcCollisionUtils.FrustumResult.OUTSIDE) return true;
     return false;
 }
示例#12
0
文件: Triangle.cs 项目: faloi/tegece
        public void createSplitList(ref List<Triangle> splitList, ref List<Triangle> remainderList, ref Matrix wvp, ref TgcFrustum bf)
        {
            this.addedToMergeList = false; //este flag se resetea acá ya que se llama por cada render

            bool hasSplit = false;
            if ((lChild != null) && (!splitted)) { //si todavía no se dividió
                if (shouldSplit(ref wvp, ref bf)) { //y se puede
                    propageSplit(ref splitList); //dale!!!
                    hasSplit = true;
                }
            }

            if (!hasSplit)
                remainderList.Add(this); //sino va a remainderList
        }
示例#13
0
文件: Triangle.cs 项目: faloi/tegece
 public void processMergeList(ref List<Triangle> toDrawList, ref Matrix wvp, ref TgcFrustum bf)
 {
     //Los triángulos que se unen simplemente avisan que no están divididos y se agregan a la lista
     this.splitted = false;
     toDrawList.Add(this);
 }
示例#14
0
文件: Triangle.cs 项目: faloi/tegece
        public void createMergeList(ref List<Triangle> mergeList, ref List<Triangle> leftoverList, ref Matrix wvp, ref TgcFrustum bf)
        {
            //Crea la mergeList, los restantes van a leftoverList
            bool cannotMerge = true;
            if (parent != null)
                cannotMerge = !parent.checkMerge(ref mergeList, ref wvp, ref bf);

            if (cannotMerge)
                leftoverList.Add(this);
        }
示例#15
0
文件: Triangle.cs 项目: faloi/tegece
        public bool checkMerge(ref List<Triangle> mergeList, ref Matrix wvp, ref TgcFrustum bf)
        {
            //Determina si debe unirse o no, y en caso de poderse se agrega a la mergeList
            bool shouldMerge = false;
            if (!addedToMergeList) {
                if (canMerge()) {
                    if (!shouldSplit(ref wvp, ref bf)) {
                        shouldMerge = true;
                        if (bNeigh != null)
                            if (bNeigh.shouldSplit(ref wvp, ref bf)) //él y su vecino deben ponerse de acuerdo para mergear
                                shouldMerge = false;
                    }
                }
            }

            if (shouldMerge) {
                addedToMergeList = true;
                mergeList.Add(this);
                if (bNeigh != null) {
                    bNeigh.addedToMergeList = true;
                    mergeList.Add(bNeigh);
                }
            }

            return addedToMergeList;
        }
示例#16
0
        /// <summary>
        /// Recorrer recursivamente el KdTree para encontrar los nodos visibles
        /// </summary>
        private void findVisibleMeshes(TgcFrustum frustum, KdTreeNode node,
            float boxLowerX, float boxLowerY, float boxLowerZ,
            float boxUpperX, float boxUpperY, float boxUpperZ)
        {
            KdTreeNode[] children = node.children;

            //es hoja, cargar todos los meshes
            if (children == null)
            {
                selectLeafMeshes(node);
            }

            //recursividad sobre hijos
            else
            {
                float xCut = node.xCut;
                float yCut = node.yCut;
                float zCut = node.zCut;

                //000
                testChildVisibility(frustum, children[0], xCut, yCut, zCut, boxUpperX, boxUpperY, boxUpperZ);
                //001
                testChildVisibility(frustum, children[1], xCut, yCut, boxLowerZ, boxUpperX, boxUpperY, zCut);

                //010
                testChildVisibility(frustum, children[2], xCut, boxLowerY, zCut, boxUpperX, yCut, boxUpperZ);
                //011
                testChildVisibility(frustum, children[3], xCut, boxLowerY, boxLowerZ, boxUpperX, yCut, zCut);

                //100
                testChildVisibility(frustum, children[4], boxLowerX, yCut, zCut, xCut, boxUpperY, boxUpperZ);
                //101
                testChildVisibility(frustum, children[5], boxLowerX, yCut, boxLowerZ, xCut, boxUpperY, zCut);

                //110
                testChildVisibility(frustum, children[6], boxLowerX, boxLowerY, zCut, xCut, yCut, boxUpperZ);
                //111
                testChildVisibility(frustum, children[7], boxLowerX, boxLowerY, boxLowerZ, xCut, yCut, zCut);

            }
        }
示例#17
0
        /// <summary>
        /// Hacer visible las meshes de un nodo si es visible por el Frustum
        /// </summary>
        private void testChildVisibility(TgcFrustum frustum, QuadtreeNode childNode,
                float boxLowerX, float boxLowerY, float boxLowerZ, float boxUpperX, float boxUpperY, float boxUpperZ)
        {
            //test frustum-box intersection
            TgcBoundingBox caja = new TgcBoundingBox(
                new Vector3(boxLowerX, boxLowerY, boxLowerZ),
                new Vector3(boxUpperX, boxUpperY, boxUpperZ));
            TgcCollisionUtils.FrustumResult c = TgcCollisionUtils.classifyFrustumAABB(frustum, caja);

            //complementamente adentro: cargar todos los hijos directamente, sin testeos
            if (c == TgcCollisionUtils.FrustumResult.INSIDE)
            {
                addAllLeafMeshes(childNode);
            }

            //parte adentro: seguir haciendo testeos con hijos
            else if (c == TgcCollisionUtils.FrustumResult.INTERSECT)
            {
                findVisibleMeshes(frustum, childNode, boxLowerX, boxLowerY, boxLowerZ, boxUpperX, boxUpperY, boxUpperZ);
            }
        }
示例#18
0
        /// <summary>
        /// Indica si un Punto colisiona con el Frustum
        /// </summary>
        /// <param name="frustum">Frustum</param>
        /// <param name="p">Punto</param>
        /// <returns>True si el Punto está adentro del Frustum</returns>
        public static bool testPointFrustum(TgcFrustum frustum, Vector3 p)
        {
            bool result = true;
            Plane[] frustumPlanes = frustum.FrustumPlanes;

            for(int i=0; i < 6; i++)
            {
                if (distPointPlane(p, frustumPlanes[i]) < 0)
                {
                    return false;
                }
            }
            return result;
        }
示例#19
0
        /// <summary>
        /// Renderizar en forma optimizado utilizando el Quadtree para hacer FrustumCulling
        /// </summary>
        public void render(TgcFrustum frustum, bool debugEnabled, string name)
        {
            Vector3 pMax = sceneBounds.PMax;
            Vector3 pMin = sceneBounds.PMin;
            findVisibleMeshes(frustum, quadtreeRootNode,
                pMin.X, pMin.Y, pMin.Z,
                pMax.X, pMax.Y, pMax.Z);

            //Renderizar
            foreach (TgcMesh mesh in modelos)
            {
                if (mesh.Enabled && mesh.Name.Contains(name))
                {
                    mesh.render();
                    mesh.Enabled = false;
                    GameManager.Instance.vegetacionVisible++;
                    if (debugEnabled)
                    {
                        mesh.BoundingBox.render();
                    }
                }
            }

            if (debugEnabled)
            {
                foreach (TgcDebugBox debugBox in debugQuadtreeBoxes)
                {
                    debugBox.render();
                }
            }
        }
示例#20
0
        /// <summary>
        /// Activar modelos dentro de celdas visibles
        /// </summary>
        private void findVisibleMeshes(TgcFrustum frustum)
        {
            for (int x = 0; x < grid.GetUpperBound(0); x++)
            {
                for (int y = 0; y < grid.GetUpperBound(1); y++)
                {
                    for (int z = 0; z < grid.GetUpperBound(2); z++)
                    {
                        GrillaRegularNode node = grid[x, y, z];
                        TgcCollisionUtils.FrustumResult r = TgcCollisionUtils.classifyFrustumAABB(frustum, node.BoundingBox);

                        if (r != TgcCollisionUtils.FrustumResult.OUTSIDE)
                        {
                            node.activateCellMeshes();
                        }
                    }
                }
            }
        }