/// <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 var caja = new TgcBoundingAxisAlignBox( new TGCVector3(boxLowerX, boxLowerY, boxLowerZ), new TGCVector3(boxUpperX, boxUpperY, boxUpperZ)); var 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 void RenderScene2(bool shadow) { //gameModel.Frustum.updateVolume(viewMatrix, projectionMatrix); var meshesQueChocanConFrustrum = gameModel.escenario.tgcScene.Meshes.FindAll (mesh => TgcCollisionUtils.classifyFrustumAABB(gameModel.Frustum, mesh.BoundingBox) != TgcCollisionUtils.FrustumResult.OUTSIDE); foreach (var T in meshesQueChocanConFrustrum) { if (shadow) { T.Technique = "RenderShadow"; } else { T.Technique = "RenderScene"; } T.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); }
public override void Render() { PreRender(); var frustumCullingEnabled = (bool)Modifiers["culling"]; //Renderizar sin ninguna optimizacion if (!frustumCullingEnabled) { tgcScene.renderAll(); UserVars.setValue("Meshes renderizadas", tgcScene.Meshes.Count); } //Renderizar con Frustum Culling else { //Analizar cada malla contra el Frustum - con fuerza bruta var totalMeshes = 0; foreach (var mesh in tgcScene.Meshes) { //Nos ocupamos solo de las mallas habilitadas if (mesh.Enabled) { //Solo mostrar la malla si colisiona contra el Frustum var r = TgcCollisionUtils.classifyFrustumAABB(TgcFrustum.Instance, mesh.BoundingBox); if (r != TgcCollisionUtils.FrustumResult.OUTSIDE) { mesh.render(); totalMeshes++; } } } //Actualizar cantidad de meshes dibujadas UserVars.setValue("Meshes renderizadas", totalMeshes); } PostRender(); }
public bool IsInView(TgcMesh mesh) { this.Transform(); return(TgcCollisionUtils.classifyFrustumAABB(GlobalConcepts.GetInstance().GetFrustum(), mesh.BoundingBox) != 0); }
/// <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; } } }
public static bool FrustumColisionaCuadrado(TgcFrustum frustum, TgcBoundingBox boundingBox) { var c = TgcCollisionUtils.classifyFrustumAABB(frustum, boundingBox); return(c == TgcCollisionUtils.FrustumResult.INSIDE || c == TgcCollisionUtils.FrustumResult.INTERSECT); }
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); }
private bool IsInView() { return(TgcCollisionUtils.classifyFrustumAABB(GlobalConcepts.GetInstance().GetFrustum(), this.plane.toMesh("plane").BoundingBox) != 0); }
public override void Render() { //Inicio el render de la escena, para ejemplos simples. Cuando tenemos postprocesado o shaders es mejor realizar las operaciones según nuestra conveniencia. PreRender(); if (estaEnMenu) { drawer2D.BeginDrawSprite(); drawer2D.DrawSprite(menu); drawer2D.EndDrawSprite(); reproducirSonido("st.mp3"); } if (finDePartida) { System.Drawing.Font font = new System.Drawing.Font("Arial", 15, FontStyle.Bold); DrawText.changeFont(font); DrawText.drawText("HAS PERDIDO", D3DDevice.Instance.Width / 2, D3DDevice.Instance.Height / 2, Color.OrangeRed); } if (!estaEnMenu && !finDePartida) { //DrawText.drawText("[G]-Habilita GodMod ", 0, 20, Color.OrangeRed); //DrawText.drawText("Posicion camara actual: " + TgcParserUtils.printVector3(Camara.Position), 0, 150, Color.Blue); //DrawText.drawText(luz.getNombreYEnergia(), 0, 90, Color.Blue); drawer2D.BeginDrawSprite(); //Dibujar sprite (si hubiese mas, deberian ir todos aquí) drawer2D.DrawSprite(barra); drawer2D.DrawSprite(energia); //Finalizar el dibujado de Sprites drawer2D.EndDrawSprite(); #region ComentoCheckPoint DrawText.drawText("Checkpoint Id: " + DestinoMonstruo.id, 0, 40, Color.OrangeRed); //DESCOMENTAR PARA VER EL CAMINO CheckpointHelper.renderAll(); #endregion if (!activoVisionNoctura) { foreach (var mesh in meshEscenario) { //Nos ocupamos solo de las mallas habilitadas if (mesh.Enabled) { //Solo mostrar la malla si colisiona contra el Frustum var r = TgcCollisionUtils.classifyFrustumAABB(Frustum, mesh.BoundingBox); if (r != TgcCollisionUtils.FrustumResult.OUTSIDE) { if (flagGod) { luz.deshabilitarEfecto(mesh); } else { luz.aplicarEfecto(mesh, Camara.Position, direccionLookAt); } mesh.render(); } } } if (monstruo.Enabled) { var r = TgcCollisionUtils.classifyFrustumAABB(Frustum, monstruo.BoundingBox); if (r != TgcCollisionUtils.FrustumResult.OUTSIDE) { if (flagGod) { luz.deshabilitarEfecto(monstruo); } else { luz.aplicarEfecto(monstruo, Camara.Position, direccionLookAt); } } } monstruo.animateAndRender(ElapsedTime); } else { visionNoctura(); D3DDevice.Instance.Device.BeginScene(); } } //Finaliza el render y presenta en pantalla, al igual que el preRender se debe para casos puntuales es mejor utilizar a mano las operaciones de EndScene y PresentScene PostRender(); }
/// <summary> /// main render method /// </summary> public override void Render() { BorrarPantalla(); if (showMenu) { //TODO -> mostrar menu inicial return; } if (!FinishedLoading) { return; } crono.render(ElapsedTime); preRenderPointLight(); //render 1 //preRenderNiebla(); //render2, rompe con la luz por eso esta comentado IniciarScene(); //empiezo main escena //cilindroBB.render(); //PreRenderPersonalizado(); //para el shadowMapFIX if (GodModeOn) { DibujarDebug(); } var posCamara = AutoJugador.CamaraAuto.Position; //foreach (Auto a in Autos) //{ // foreach (LuzFija luz in LucesLst) // { // luz.setValues(a.Mesh, posCamara); // } // a.Render(); //} foreach (TgcMesh mesh in MapScene.Meshes) { //rendereo solo lo que esta dentro del frustrum var c = TgcCollisionUtils.classifyFrustumAABB(Frustum, mesh.BoundingBox); if (c != TgcCollisionUtils.FrustumResult.OUTSIDE) { mesh.render(); } } DrawText.drawText(AutoJugador.Velocidad.ToString(), 20, 50, Color.Orange); //skybox render //render de menubox solo cuando es necesario. if (GodModeOn == true && MenuBox != null) { MenuBox.Render(); } //Dibujo los sprites2d en pantalla Velocimetro.Render(); autoOponente.render(); SkyBox.render(); RenderAxis(); RenderFPS(); AutoJugador.Render(); TerminarScene(); //termino main scene ImprimirPantalla(); }
public override void render(float elapsedTime) { motionBlurFlag = (bool)GuiController.Instance.Modifiers["motionBlurFlag"]; TgcTexture texture = TgcTexture.createTexture(GuiController.Instance.AlumnoEjemplosMediaDir + "TheC#\\Pista\\pistaCarreras.png"); Microsoft.DirectX.Direct3D.Device d3dDevice = GuiController.Instance.D3dDevice; //pantalla De Inicio if (flagInicio == 0) { //Actualizar valores cargados en modifiers /*sprite.Position = (Vector2)GuiController.Instance.Modifiers["position"]; * sprite.Scaling = (Vector2)GuiController.Instance.Modifiers["scaling"]; * sprite.Rotation = FastMath.ToRad((float)GuiController.Instance.Modifiers["rotation"]); */ //Iniciar dibujado de todos los Sprites de la escena (en este caso es solo uno) GuiController.Instance.Drawer2D.beginDrawSprite(); sprite.render(); //Finalizar el dibujado de Sprites GuiController.Instance.Drawer2D.endDrawSprite(); flagInicio = jugador.verSiAprietaSpace(); textIngreseTeclaSombra.render(); textIngreseTecla.render(); musica.verSiCambioMP3(); } else { //Para contar el tiempo desde que preciona la barra espaciadora y comienza el juego if (primerRenderDelJuegoAndando == true) { this.horaInicio = DateTime.Now; primerRenderDelJuegoAndando = false; } //Todo lo referente a lo que debe hacer el IA autoIA.elapsedTime = elapsedTime; autoIA.establecerVelocidadMáximaEn((float)GuiController.Instance.Modifiers["velocidadMaxima"] * 1.02f); if (colision.getTiempoQueChoco() == 0) { jugadorIA.jugar(trayectoDeIA[0].Center, meshAutoIA.Position); } meshAutoIA.Rotation = new Vector3(0f, autoIA.rotacion, 0f); jugadorIA.setRotacion(meshAutoIA.Rotation); meshAutoIA.moveOrientedY(-autoIA.velocidad * elapsedTime); //Fin movimiento de auto IA //Le paso el elapsed time al auto porque sus metodos no deben depender de los FPS auto.elapsedTime = elapsedTime; //Varío la velocidad Máxima del vehículo con el modifier "velocidadMáxima" auto.establecerVelocidadMáximaEn((float)GuiController.Instance.Modifiers["velocidadMaxima"]); //El jugador envia mensajes al auto dependiendo de que tecla presiono //Se pone un tiempo para que luego de chocar 2 autos, estos no puedan ingresar movimiento (sólo se mueve por inercia) if (colision.getTiempoQueChoco() == 0) { jugador.jugar(cantidadDeNitro); } else { colision.setTiempoQueChoco(colision.getTiempoQueChoco() - (8 * elapsedTime)); if (colision.getTiempoQueChoco() < 0) { colision.setTiempoQueChoco(0); } } //Transfiero la rotacion del auto abstracto al mesh, y su obb autoMesh.Rotation = new Vector3(0f, auto.rotacion, 0f); oBBAuto.Center = autoMesh.Position; oBBAuto.setRotation(autoMesh.Rotation); meshAutoIA.Rotation = new Vector3(0f, autoIA.rotacion, 0f); oBBAutoIa.Center = meshAutoIA.Position; oBBAutoIa.setRotation(meshAutoIA.Rotation); //Calculo de giro de la rueda rotacionVertical -= auto.velocidad * elapsedTime / 60; //Calculo el movimiento del mesh dependiendo de la velocidad del auto autoMesh.moveOrientedY(-auto.velocidad * elapsedTime); //Detección de colisiones //Hubo colisión con un objeto. Guardar resultado y abortar loop. //Si hubo alguna colisión, hacer esto: if (huboColision(oBBAuto)) { autoMesh.moveOrientedY(20 * auto.velocidad * elapsedTime); //Lo hago "como que rebote un poco" para no seguir colisionando auto.velocidad = -(auto.velocidad * 0.3f); //Lo hago ir atrás un tercio de velocidad de choque } if (huboColision(oBBAutoIa)) { meshAutoIA.moveOrientedY(20 * autoIA.velocidad * elapsedTime); //Lo hago "como que rebote un poco" para no seguir colisionando autoIA.velocidad = -(autoIA.velocidad * 0.3f); //Lo hago ir atrás un tercio de velocidad de choque } //Colisión entre los autos for (int i = 0; i < 4; i++) { float ro, alfa_rueda; float posicion_xA1; float posicion_yA1; float posicion_xA2; float posicion_yA2; ro = FastMath.Sqrt(dx[i] * dxAColision[i] + dyAColision[i] * dyAColision[i]); alfa_rueda = FastMath.Asin(dxAColision[i] / ro); if (i == 0 || i == 2) { alfa_rueda += FastMath.PI; } posicion_xA1 = FastMath.Sin(alfa_rueda + auto.rotacion) * ro; posicion_yA1 = FastMath.Cos(alfa_rueda + auto.rotacion) * ro; posicion_xA2 = FastMath.Sin(alfa_rueda + autoIA.rotacion) * ro; posicion_yA2 = FastMath.Cos(alfa_rueda + autoIA.rotacion) * ro; obbsAuto[i].Position = (new Vector3(posicion_xA1, 15.5f, posicion_yA1) + autoMesh.Position); obbsOtroAuto[i].Position = (new Vector3(posicion_xA2, 15.5f, posicion_yA2) + meshAutoIA.Position); } colision.colisionEntreAutos(obbsAuto, obbsOtroAuto, jugador, auto, autoIA, autoMesh, meshAutoIA, elapsedTime); //Cosas sobre derrape int direcGiroDerrape = 0; if (auto.velocidad > 1500 && (jugador.estaGirandoDerecha() || jugador.estaGirandoIzquierda())) { if (jugador.estaGirandoIzquierda()) { direcGiroDerrape = -1; } else if (jugador.estaGirandoDerecha()) { direcGiroDerrape = 1; } autoMesh.Rotation = new Vector3(0f, auto.rotacion + (direcGiroDerrape * anguloDerrape), 0f); oBBAuto.setRotation(new Vector3(autoMesh.Rotation.X, autoMesh.Rotation.Y + (direcGiroDerrape * anguloDerrape / 2), autoMesh.Rotation.Z)); if (anguloDerrape <= anguloMaximoDeDerrape) { anguloDerrape += velocidadDeDerrape * elapsedTime; } } else { direcGiroDerrape = 0; anguloDerrape = 0; } //Fin derrape //Posiciono las ruedas for (int i = 0; i < 4; i++) { float ro, alfa_rueda; float posicion_x; float posicion_y; ro = FastMath.Sqrt(dx[i] * dx[i] + dy[i] * dy[i]); alfa_rueda = FastMath.Asin(dx[i] / ro); if (i == 0 || i == 2) { alfa_rueda += FastMath.PI; } posicion_x = FastMath.Sin(alfa_rueda + auto.rotacion + (anguloDerrape * direcGiroDerrape)) * ro; posicion_y = FastMath.Cos(alfa_rueda + auto.rotacion + (anguloDerrape * direcGiroDerrape)) * ro; ruedas[i].Position = (new Vector3(posicion_x, 15.5f, posicion_y) + autoMesh.Position); //Si no aprieta para los costados, dejo la rueda derecha (por ahora, esto se puede modificar) if (input.keyDown(Key.Left) || input.keyDown(Key.A) || input.keyDown(Key.Right) || input.keyDown(Key.D)) { ruedas[i].Rotation = new Vector3(rotacionVertical, auto.rotacion + auto.rotarRueda(i) + (anguloDerrape * direcGiroDerrape), 0f); } else { ruedas[i].Rotation = new Vector3(rotacionVertical, auto.rotacion + (anguloDerrape * direcGiroDerrape), 0f); } } //comienzo humo float rohumo, alfa_humo; float posicion_xhumo; float posicion_yhumo; rohumo = FastMath.Sqrt(-19f * -19f + 126f * 126f); alfa_humo = FastMath.Asin(-19f / rohumo); posicion_xhumo = FastMath.Sin(alfa_humo + auto.rotacion + (anguloDerrape * direcGiroDerrape)) * rohumo; posicion_yhumo = FastMath.Cos(alfa_humo + auto.rotacion + (anguloDerrape * direcGiroDerrape)) * rohumo; humo.Position = (new Vector3(posicion_xhumo, 15.5f, posicion_yhumo) + autoMesh.Position); //Si no aprieta para los costados, dejo la rueda derecha (por ahora, esto se puede modificar) if (input.keyDown(Key.Left) || input.keyDown(Key.A) || input.keyDown(Key.Right) || input.keyDown(Key.D)) { humo.Rotation = new Vector3(0f, auto.rotacion + (anguloDerrape * direcGiroDerrape), 0f); } else { humo.Rotation = new Vector3(0f, auto.rotacion + (anguloDerrape * direcGiroDerrape), 0f); } //fin de humo fuego.Position = humo.Position; fuego.Rotation = humo.Rotation; //fin fuego cantidadDeNitro += 0.5f * elapsedTime; cantidadDeNitro = FastMath.Min(cantidadDeNitro, 100f); if (auto.nitro) { cantidadDeNitro -= 7 * elapsedTime; cantidadDeNitro = FastMath.Max(cantidadDeNitro, 0f); if (cantidadDeNitro > 1) { humo.Enabled = false; fuego.Enabled = false; } } else { humo.Enabled = false; fuego.Enabled = false; } tiempoHumo += elapsedTime; humo.UVOffset = new Vector2(0.9f, tiempoHumo); humo.updateValues(); fuego.UVOffset = new Vector2(0.9f, tiempoHumo); fuego.updateValues(); if (tiempoHumo > 50f) { tiempoHumo = 0f; } autoMeshPrevX = autoMesh.Position.X; autoMeshPrevZ = autoMesh.Position.Z; //Lineas de Frenado if (jugador.estaFrenandoDeMano()) { lineaDeFrenado[0].addTrack(new Vector3(ruedaDerechaDelanteraMesh.Position.X, 0, ruedaDerechaDelanteraMesh.Position.Z)); lineaDeFrenado[1].addTrack(new Vector3(ruedaDerechaTraseraMesh.Position.X, 0, ruedaDerechaTraseraMesh.Position.Z)); lineaDeFrenado[2].addTrack(new Vector3(ruedaIzquierdaDelanteraMesh.Position.X, 0, ruedaIzquierdaDelanteraMesh.Position.Z)); lineaDeFrenado[3].addTrack(new Vector3(ruedaIzquierdaTraseraMesh.Position.X, 0, ruedaIzquierdaTraseraMesh.Position.Z)); } if (jugador.dejoDeFrenarDeMano()) { for (int i = 0; i < lineaDeFrenado.Length; i++) { lineaDeFrenado[i].endTrack(); } } for (int i = 0; i < lineaDeFrenado.Length; i++) { lineaDeFrenado[i].render(); lineaDeFrenado[i].pasoDelTiempo(elapsedTime); } //Dibujo el reflejo de la luz en el auto reflejo.Render(); //////Camara/////// if (jugador.estaMirandoHaciaAtras()) { GuiController.Instance.ThirdPersonCamera.setCamera(autoMesh.Position, 200, -500); GuiController.Instance.ThirdPersonCamera.Target = autoMesh.Position; GuiController.Instance.ThirdPersonCamera.RotationY = auto.rotacion; } else { coheficienteCamara = jugador.verSiCambiaCamara(); GuiController.Instance.ThirdPersonCamera.setCamera(autoMesh.Position, 100 + (coheficienteCamara), 900 - (coheficienteCamara) * 4); GuiController.Instance.ThirdPersonCamera.Target = autoMesh.Position; GuiController.Instance.ThirdPersonCamera.RotationY = auto.rotacion; } //La camara no rota exactamente a la par del auto, hay un pequeño retraso //GuiController.Instance.ThirdPersonCamera.RotationY += 5 * (auto.rotacion - prevCameraRotation) * elapsedTime; //Ajusto la camara a menos de 360 porque voy a necesitar hacer calculos entre angulos while (prevCameraRotation > 360) { prevCameraRotation -= 360; } prevCameraRotation = GuiController.Instance.ThirdPersonCamera.RotationY; ///////Musica///////// jugador.verSiModificaMusica(musica); //Dibujar objeto principal //Siempre primero hacer todos los cálculos de lógica e input y luego al final dibujar todo (ciclo update-render) foreach (TgcMesh mesh in scenePista.Meshes) { mesh.Enabled = (TgcCollisionUtils.classifyFrustumAABB(GuiController.Instance.Frustum, mesh.BoundingBox) != TgcCollisionUtils.FrustumResult.OUTSIDE); } if (motionBlurFlag) { motionBlur.update(elapsedTime); motionBlur.motionBlurRender(elapsedTime, HighResolutionTimer.Instance.FramesPerSecond, auto.velocidad, 0); } else { foreach (TgcMesh mesh in scenePista.Meshes) { mesh.Technique = "DefaultTechnique"; mesh.render(); } } //Mostrar al auto IA meshAutoIA.render(); //Muestro el punto siguiente trayecto[0].render(); //mostrar el auto manejado por el humano autoMesh.render(); for (int i = 0; i < 4; i++) { ruedas[i].render(); } humo.render(); fuego.render(); //Colision con puntos de control, tanto de persona como IA for (int i = 0; i < trayecto.Count; i++) { //Pregunto si colisiona con un punto de control activado. Lo sé, feo. if ((i == 0) && TgcCollisionUtils.testPointCylinder(oBBAuto.Position, trayecto[i].BoundingCylinder)) { TgcCylinder cilindroModificado = new TgcCylinder(trayecto[i].Center, 130, 30); if (contadorDeActivacionesDePuntosDeControl != (posicionesPuntosDeControl.Count * 3)) { trayecto.RemoveAt(i); trayecto.Add(cilindroModificado); contadorDeActivacionesDePuntosDeControl++; textPuntosDeControlAlcanzados.Text = "Puntos De Control Alcanzados = " + contadorDeActivacionesDePuntosDeControl.ToString(); textTiempo.Text = (Convert.ToDouble(textTiempo.Text) + 3).ToString(); } else { gano = true; textGanaste.Text = "Ganaste y obtuviste un puntaje de " + textTiempo.Text + " puntos"; textGanaste.render(); auto.estatico(); //Para el IA autoIA.estatico(); } } } for (int i = 0; i < trayectoDeIA.Count; i++) { //Pregunto si colisiona con un punto de control activado if ((i == 0) && TgcCollisionUtils.testPointCylinder(meshAutoIA.Position, trayectoDeIA[i].BoundingCylinder)) { TgcCylinder cilindroModificado = new TgcCylinder(trayectoDeIA[i].Center, 130, 30); if (contadorDeActivacionesDePuntosDeControlDeIA != (posicionesPuntosDeControlDeIA.Count * 3)) { trayectoDeIA.RemoveAt(i); trayectoDeIA.Add(cilindroModificado); contadorDeActivacionesDePuntosDeControlDeIA++; } else { gano = true; textGanaste.Text = "Ganó la máquina :P "; textGanaste.render(); //Para el IA autoIA.estatico(); auto.estatico(); } } } textPosicionDelAutoActual.Text = autoMesh.Position.ToString(); //Renderizar los tres textos textoVelocidad.mostrarVelocidad(auto.velocidad / 10).render(); //renderiza la velocidad textPuntosDeControlAlcanzados.render(); textPosicionDelAutoActual.render(); //Cosas del tiempo tiempo.incrementarTiempo(this, elapsedTime, (bool)GuiController.Instance.Modifiers["jugarConTiempo"]); //Actualizo y dibujo el relops if ((bool)GuiController.Instance.Modifiers["jugarConTiempo"]) { if ((DateTime.Now.Subtract(this.horaInicio).TotalSeconds) > segundosAuxiliares) { if (Convert.ToDouble(textTiempo.Text) == 0) { textPerdiste.Text = "Perdiste y lograste " + contadorDeActivacionesDePuntosDeControl.ToString() + " puntos de control"; textPerdiste.render(); auto.estatico(); //Para el IA autoIA.estatico(); } else if (gano == true) { } else { this.textTiempo.Text = (Convert.ToDouble(textTiempo.Text) - 1).ToString(); segundosAuxiliares++; } } } emisorHumo.update(elapsedTime, GuiController.Instance.CurrentCamera.getLookAt(), auto.rotacion, autoMesh.Position, anguloDerrape, direcGiroDerrape, auto.nitro && (cantidadDeNitro > 1), auto.velocidad); emisorHumo.render(GuiController.Instance.CurrentCamera.getPosition()); textTiempo.render(); stringTiempo.render(); contadorDeFrames++; hud.render(auto.velocidad, cantidadDeNitro); }//cierra el if de que no esta en pantalla inicio textFPS.Text = " FPS: " + HighResolutionTimer.Instance.FramesPerSecond.ToString(); textFPS.render(); }
/// <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(TGCVector3 camPos, TgcFrustum frustum, float elapsedTime) { time += elapsedTime; //Obtener leaf actual var actualLeaf = FindLeaf(camPos); //Obtener clusters visibles segun PVS var actualCluster = Data.leafs[actualLeaf].cluster; if (actualCluster != antCluster) { antCluster = actualCluster; clusterVis.Clear(); for (var 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; //TODO: esto creo que ya lo hace solo el example en el preupdate. frustum.updateVolume(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View), TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.Projection)); foreach (var nleaf in clusterVis) { //Frustum Culling con el AABB del cluster var result = TgcCollisionUtils.classifyFrustumAABB(frustum, Data.leafs[nleaf].boundingBox); if (result == TgcCollisionUtils.FrustumResult.OUTSIDE) { continue; } //Habilitar meshes de este leaf var currentLeaf = Data.leafs[nleaf]; for (var i = currentLeaf.firstLeafSurface; i < currentLeaf.firstLeafSurface + currentLeaf.numLeafSurfaces; i++) { var iMesh = Data.leafSurfaces[i]; var mesh = Meshes[iMesh]; if (mesh != null) { Meshes[iMesh].Enabled = true; } } } //TODO: No deberia manipular Matrix de DX. //Renderizar meshes visibles mViewProj = TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View * D3DDevice.Instance.Device.Transform.Projection); for (var i = 0; i < Meshes.Count; i++) { //Ignonar si no está habilitada var mesh = Meshes[i]; if (mesh == null || !mesh.Enabled) { continue; } var 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; } } }
public void Render() { foreach (TgcMesh mesh in this.getAllMeshes()) { //rendereo solo lo que esta dentro del frustrum var c = TgcCollisionUtils.classifyFrustumAABB(this.env.Frustum, mesh.BoundingBox); if (c != TgcCollisionUtils.FrustumResult.OUTSIDE) { mesh.render(); } } //Renderizar suelo suelo.render(); //calle.render(); //Renderizar SkyBox skyBox.render(); //Renderizar instancias // foreach (var mesh in meshes) // mesh.render(); //Renderizar items int nroItem = 0; foreach (var item in items) { if (itemsTiempoInvisibilidad[nroItem] < 380) { //posEncontrada = nroItem; itemsTiempoInvisibilidad[nroItem] = itemsTiempoInvisibilidad[nroItem]++; } else { if (item.Position.Y < 10) { item.move(0, 50, 0); } } item.render(); nroItem++; } //Renderizado de cordones foreach (var cordon in cordones) { cordon.render(); } //Renderizado de veredas foreach (var v in veredas) { v.render(); } //Renderizado de paredes foreach (var p in paredes) { p.render(); } //Renderizado de calles foreach (var c in calles) { c.render(); } /* foreach (var vehiculo in vehiculos) * { * vehiculo.getMesh().render(); * }*/ //mostrarBounding(); }