/// <summary> /// Renderiza el terreno /// </summary> public void render() { TgcFrustum frustum = GuiController.Instance.Frustum; for (int i = 0; i < vbTerrains.Count; i++) { TgcCollisionUtils.FrustumResult c = TgcCollisionUtils.classifyFrustumAABB(frustum, boundingBoxes[i]); if (c == TgcCollisionUtils.FrustumResult.INSIDE || c == TgcCollisionUtils.FrustumResult.INTERSECT) { Vector3 centroBB = (boundingBoxes[i].PMax + boundingBoxes[i].PMin); centroBB.Multiply(0.5f); if (((CustomFpsCamera.Instance.eye - centroBB).Length() < CustomFpsCamera.FAR_PLANE / 1.5f)) { renderTerrain(vbTerrains[i]); GameManager.Instance.terrenosVisibles++; } } bool drawBoundingBoxes = GameManager.Instance.drawBoundingBoxes; if (drawBoundingBoxes) { boundingBoxes[i].render(); } } }
/// <summary> /// Hacer visible las meshes de un nodo si es visible por el Frustum /// </summary> private void testChildVisibility(TgcFrustum frustum, OctreeNode childNode, float boxLowerX, float boxLowerY, float boxLowerZ, float boxUpperX, float boxUpperY, float boxUpperZ) { if (childNode == null) { return; } //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); } }
public override void render(float elapsedTime) { bool frustumCullingEnabled = (bool)GuiController.Instance.Modifiers["culling"]; //Renderizar sin ninguna optimizacion if (!frustumCullingEnabled) { tgcScene.renderAll(); GuiController.Instance.UserVars.setValue("Meshes renderizadas", tgcScene.Meshes.Count); } //Renderizar con Frustum Culling else { //Analizar cada malla contra el Frustum - con fuerza bruta TgcFrustum frustum = GuiController.Instance.Frustum; int totalMeshes = 0; foreach (TgcMesh mesh in tgcScene.Meshes) { //Nos ocupamos solo de las mallas habilitadas if (mesh.Enabled) { //Solo mostrar la malla si colisiona contra el Frustum TgcCollisionUtils.FrustumResult r = TgcCollisionUtils.classifyFrustumAABB(frustum, mesh.BoundingBox); if (r != TgcCollisionUtils.FrustumResult.OUTSIDE) { mesh.render(); totalMeshes++; } } } //Actualizar cantidad de meshes dibujadas GuiController.Instance.UserVars.setValue("Meshes renderizadas", totalMeshes); } }
public void renderPasto(float tLeftMoved, float tRightMoved, int parte) { if ((CustomFpsCamera.Instance.eye - partePasto[parte].Origin).Length() < CustomFpsCamera.FAR_PLANE / 4.5) { TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(GuiController.Instance.Frustum, partePasto[parte].BoundingBox); if (result != TgcCollisionUtils.FrustumResult.OUTSIDE) { Device d3dDevice = GuiController.Instance.D3dDevice; TgcTexture.Manager texturesManager = GuiController.Instance.TexturesManager; d3dDevice.RenderState.AlphaTestEnable = true; d3dDevice.RenderState.AlphaBlendEnable = true; TgcPlaneWall pastoWall = partePasto[parte]; texturesManager.shaderSet(pastoWall.Effect, "texDiffuseMap", pastoWall.Texture); texturesManager.clear(1); GuiController.Instance.Shaders.setShaderMatrixIdentity(pastoWall.Effect); d3dDevice.VertexDeclaration = GuiController.Instance.Shaders.VdecPositionTextured; pastoWall.Effect.Technique = pastoWall.Technique; //Render con shader pastoWall.Effect.Begin(0); pastoWall.Effect.BeginPass(0); d3dDevice.DrawUserPrimitives(PrimitiveType.TriangleList, 2, actualizarPasto(tLeftMoved, tRightMoved, parte, pastoWall)); pastoWall.Effect.EndPass(); pastoWall.Effect.End(); d3dDevice.RenderState.AlphaTestEnable = false; d3dDevice.RenderState.AlphaBlendEnable = false; } } }
//==================================== // Renderiza las imagenes //==================================== public override void render(float Tiempo) { Device device = GuiController.Instance.D3dDevice; //Mover mesh //Vector3 meshPos = (Vector3)GuiController.Instance.Modifiers["MeshPos"]; //mesh4.Position = meshPos; bool showBB = (bool)GuiController.Instance.Modifiers.getValue("showBoundingBox"); //FRUSTUM CULLING TgcFrustum frustum = GuiController.Instance.Frustum; if (mesh4.Enabled) { //Solo mostrar la malla si colisiona contra el Frustum TgcCollisionUtils.FrustumResult r = TgcCollisionUtils.classifyFrustumAABB(frustum, mesh4.BoundingBox); if (r != TgcCollisionUtils.FrustumResult.OUTSIDE) { mesh4.render(); } if (showBB) { mesh4.BoundingBox.render(); } } if (disparando) { disparar(Tiempo); } }
protected virtual List <TgcMesh> MeshesToRender() { // FRUSTUM CULLING return(Meshes.FindAll(mesh => { TgcCollisionUtils.FrustumResult collisionResult = TgcCollisionUtils.classifyFrustumAABB(GameInstance.Frustum, mesh.BoundingBox); return collisionResult != TgcCollisionUtils.FrustumResult.OUTSIDE; })); }
/// <summary> /// Hacer FrustumCulling por fuerza bruta para detectar que modelos se ven /// </summary> private void doFrustumCulling() { TgcFrustum frustum = GuiController.Instance.Frustum; foreach (SceneEditorMeshObject meshObj in meshObjects) { TgcCollisionUtils.FrustumResult r = TgcCollisionUtils.classifyFrustumAABB(frustum, meshObj.mesh.BoundingBox); if (r == TgcCollisionUtils.FrustumResult.OUTSIDE) { meshObj.visible = false; } else { meshObj.visible = true; } } }
internal void RenderBrigth(float elapsedTime) { TgcFrustum frustum = GuiController.Instance.Frustum; foreach (Enemy enemigo in enemies) { TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, enemigo.mesh.BoundingBox); if (result == TgcCollisionUtils.FrustumResult.INSIDE || result == TgcCollisionUtils.FrustumResult.INTERSECT) { enemigo.Render(elapsedTime); } } proyectiles.ForEach(proyectil => proyectil.Render(elapsedTime)); quadTree.render(frustum, drawBoundingBoxes, "Oil"); }
/// <summary> /// Activar modelos dentro de celdas visibles /// </summary> public void UpdateVisibleMeshes(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(); } } } } }
public bool validarVisibilidad(Municion municion) { bool result = true; TgcCollisionUtils.FrustumResult c = TgcCollisionUtils.classifyFrustumSphere(GuiController.Instance.Frustum, municion.getMunicion().BoundingSphere); //complementamente adentro: cargar todos los hijos directamente, sin testeos if (c == TgcCollisionUtils.FrustumResult.INSIDE) { result = true; } //parte adentro: seguir haciendo testeos con hijos else if (c == TgcCollisionUtils.FrustumResult.INTERSECT) { result = false; } return(result); }
public void render() { bool showBB = (bool)GuiController.Instance.Modifiers.getValue("showBoundingBox"); //FRUSTUM CULLING TgcFrustum frustum = GuiController.Instance.Frustum; if (mesh.Enabled) { //Solo mostrar la malla si colisiona contra el Frustum TgcCollisionUtils.FrustumResult r = TgcCollisionUtils.classifyFrustumAABB(frustum, mesh.BoundingBox); if (r != TgcCollisionUtils.FrustumResult.OUTSIDE) { mesh.animateAndRender(); } if (showBB) { mesh.BoundingBox.render(); } } }
static List <int> IndicesVisiblesDentroDelFrustum(Nodo node) { Device deviceContext = GuiController.Instance.D3dDevice; // Check to see if the node can be viewed, height doesn't matter in a quad tree. //test frustum-box intersection TgcCollisionUtils.FrustumResult c = TgcCollisionUtils.classifyFrustumAABB(GuiController.Instance.Frustum, node.caja); // Si el nodo no es visible devuelvo lista vacia de indices if (c == TgcCollisionUtils.FrustumResult.OUTSIDE) { return(new List <int>()); } //Si el nodo es visible en su totalidad traigo todos indices de los nodos hijos if (c == TgcCollisionUtils.FrustumResult.INSIDE) { return(AgregarTodosLosNodos(node)); } //Si el nodo es hoja devuelvo la lista de indices if (node.hijos == null) { return(IndicesConNivelDeDetalle(node)); } //Si el nodo es parcialmente visible y no es hoja le pido a cada nodo hijo que verifique si es visible var lista = new List <int>(); for (int i = 0; i < 4; i++) { if (node.hijos[i] != null) { lista.AddRange(IndicesVisiblesDentroDelFrustum(node.hijos[i])); } } return(lista); }
/// <summary> /// Renderizar escenario BSP utilizando matriz PVS para descartar clusters no visibles /// </summary> /// <param name="camPos">Posición actual de la camara</param> public void render(Vector3 camPos) { Device device = GuiController.Instance.D3dDevice; float elapsedTime = GuiController.Instance.ElapsedTime; time += elapsedTime; //Obtener leaf actual int actualLeaf = FindLeaf(camPos); //Obtener clusters visibles segun PVS int actualCluster = data.leafs[actualLeaf].cluster; if (actualCluster != antCluster) { antCluster = actualCluster; clusterVis.Clear(); for (int i = 0; i < data.leafs.Length; i++) { if (isClusterVisible(actualCluster, data.leafs[i].cluster)) { clusterVis.Add(i); } } } //Actualizar volumen del Frustum con nuevos valores de camara TgcFrustum frustum = GuiController.Instance.Frustum; frustum.updateVolume(device.Transform.View, device.Transform.Projection); foreach (int nleaf in clusterVis) { //Frustum Culling con el AABB del cluster TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, data.leafs[nleaf].boundingBox); if (result == TgcCollisionUtils.FrustumResult.OUTSIDE) { continue; } //Habilitar meshes de este leaf QLeaf currentLeaf = data.leafs[nleaf]; for (int i = currentLeaf.firstLeafSurface; i < currentLeaf.firstLeafSurface + currentLeaf.numLeafSurfaces; i++) { int iMesh = data.leafSurfaces[i]; TgcMesh mesh = meshes[iMesh]; if (mesh != null) { meshes[iMesh].Enabled = true; } } } //Renderizar meshes visibles mViewProj = device.Transform.View * device.Transform.Projection; for (int i = 0; i < meshes.Count; i++) { //Ignonar si no está habilitada TgcMesh mesh = meshes[i]; if (mesh == null || !mesh.Enabled) { continue; } QShaderData shader = data.shaderXSurface[i]; //Renderizado con shaders //TODO: Mejorar el renderizado de shaders. Por ahora esta deshabilitado if (shader != null && shader.Stages.Count > 0) { renderShaderMesh(mesh, shader); } //Renderizado normal else { //render mesh.render(); //deshabilitar para la proxima vuelta mesh.Enabled = false; } } }
internal void RenderAll(float elapsedTime) { Device d3dDevice = GuiController.Instance.D3dDevice; terrain.Technique = "RenderTerrain"; terrain.render(); TgcFrustum frustum = GuiController.Instance.Frustum; if (drawBoundingBoxes) { foreach (Barril barril in barriles) { //barril.explosion.render(); } } skyBox.render(); quadTree.render(frustum, drawBoundingBoxes, "ArbolBosque"); quadTree.render(frustum, drawBoundingBoxes, "ArbustoComplejo"); if (drawBoundingBoxes) { CustomFpsCamera.Instance.boundingBox.render(); } foreach (Proyectil proyectil in proyectiles) { TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, proyectil.mesh.BoundingBox); if (result == TgcCollisionUtils.FrustumResult.INSIDE || result == TgcCollisionUtils.FrustumResult.INTERSECT) { proyectil.Render(elapsedTime); } } //Obtener valor de UserVar (hay que castear) GuiController.Instance.UserVars.setValue("N Vegetacion Visible", vegetacionVisible); int valor = (int)GuiController.Instance.UserVars.getValue("N Vegetacion Visible"); vegetacionVisible = 0; GuiController.Instance.UserVars.setValue("N Sub-terrenos Visibles", terrenosVisibles); int valor2 = (int)GuiController.Instance.UserVars.getValue("N Sub-terrenos Visibles"); terrenosVisibles = 0; int parte, texture = 0; foreach (Pasto pasto in pastos) { for (parte = 0; parte < 6; parte++) { switch (texture) { case 0: pasto.renderPasto(tLeftMoved0, tRightMoved0, parte); break; case 1: pasto.renderPasto(tLeftMoved1, tRightMoved1, parte); break; case 2: pasto.renderPasto(tLeftMoved2, tRightMoved2, parte); break; } texture++; if (texture > 2) { texture = 0; } } } //dibujamos todos los enemigos foreach (Enemy enemigo in enemies) { enemigo.renderParticulas(elapsedTime); TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, enemigo.mesh.BoundingBox); if (result == TgcCollisionUtils.FrustumResult.INSIDE || result == TgcCollisionUtils.FrustumResult.INTERSECT) { enemigo.Render(elapsedTime); } } foreach (Barril barril in barriles) { barril.Render(elapsedTime); } foreach (TgcMesh tesoro in tesoros) { tesoro.render(); } player1.Render(elapsedTime); }