/// <summary> /// Renderizar ejes segun posicion actual de la camara /// </summary> public void render() { //Obtener World coordinate de la esquina inferior de la pantalla var w = D3DDevice.Instance.Device.Viewport.Width; var h = D3DDevice.Instance.Device.Viewport.Height; var sx = AXIS_POS_OFFSET; var sy = h - AXIS_POS_OFFSET; var matProj = D3DDevice.Instance.Device.Transform.Projection; var v = new TGCVector3( (2.0f * sx / w - 1) / matProj.M11, -(2.0f * sy / h - 1) / matProj.M22, 1.0f); //Transform the screen space into 3D space var m = TGCMatrix.Invert(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View)); var rayDir = new TGCVector3( v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31, v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32, v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33); var rayOrig = new TGCVector3(m.M41, m.M42, m.M43); var worldCoordPos = rayOrig + AXIS_POS_DISTANCE * rayDir; //Renderizar TexturesManager.Instance.clear(0); TexturesManager.Instance.clear(1); D3DDevice.Instance.Device.Material = D3DDevice.DEFAULT_MATERIAL; D3DDevice.Instance.Device.Transform.World = TGCMatrix.Translation(worldCoordPos).ToMatrix(); D3DDevice.Instance.Device.VertexFormat = CustomVertex.PositionColored.Format; D3DDevice.Instance.Device.SetStreamSource(0, vertexBuffer, 0); D3DDevice.Instance.Device.DrawPrimitives(PrimitiveType.LineList, 0, 3); D3DDevice.Instance.Device.Transform.World = TGCMatrix.Identity.ToMatrix(); }
/// <summary> /// Actualiza el Ray de colision en base a la posicion del mouse en la pantalla /// </summary> public void updateRay() { //Crear Ray en base a coordenadas del mouse var sx = Input.Xpos; var sy = Input.Ypos; var w = D3DDevice.Instance.Device.Viewport.Width; var h = D3DDevice.Instance.Device.Viewport.Height; var matProj = D3DDevice.Instance.Device.Transform.Projection; var v = new Mathematica.TGCVector3(); v.X = (2.0f * sx / w - 1) / matProj.M11; v.Y = -(2.0f * sy / h - 1) / matProj.M22; v.Z = 1.0f; //Transform the screen space pick ray into 3D space var m = TGCMatrix.Invert(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View)); var rayDir = new TGCVector3( v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31, v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32, v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33 ); var rayOrig = new TGCVector3(m.M41, m.M42, m.M43); //Picking Ray creado Ray.Origin = rayOrig; Ray.Direction = rayDir; }
/// <summary> /// Proyectar punto 3D a 2D /// </summary> /// <param name="box3d">Punto 3D</param> /// <param name="box2D">Rectangulo 2D proyectado</param> /// <returns>False si es un caso degenerado de proyeccion y no debe considerarse</returns> public static bool projectPoint(TGCVector3 p, out Rectangle box2D) { //Datos de viewport var d3dDevice = D3DDevice.Instance.Device; var viewport = d3dDevice.Viewport; var view = d3dDevice.Transform.View; var proj = d3dDevice.Transform.Projection; var width = viewport.Width; var height = viewport.Height; var m = view * proj; //Proyectar box2D = new Rectangle(); var pOut = TGCVector3.Transform(TGCVector3.FromVector3(p), TGCMatrix.FromMatrix(m)); if (pOut.W < 0) { return(false); } var projVertex = toScreenSpace(pOut, width, height); var min = new TGCVector2(projVertex.X, projVertex.Y); var max = min + new TGCVector2(1, 1); //Clamp if (min.X < 0f) { min.X = 0f; } if (min.Y < 0f) { min.Y = 0f; } if (max.X >= width) { max.X = width - 1; } if (max.Y >= height) { max.Y = height - 1; } //Control de tamaño minimo if (max.X - min.X < 1f) { return(false); } if (max.Y - min.Y < 1f) { return(false); } //Cargar valores de box2D box2D.Location = new Point((int)min.X, (int)min.Y); box2D.Size = new Size((int)(max.X - min.X), (int)(max.Y - min.Y)); return(true); }
public override void Update() { PreUpdate(); escapeDelay += ElapsedTime; if (!InPrincipalMenu && Input.keyDown(Key.Escape) && escapeDelay > 0.5f) // uso el delay porque no me funciona el keyUp o keyPressed { escapeDelay = 0; FocusInGame = !FocusInGame; ManageFocus(); } if (FocusInGame || InPrincipalMenu) // Si no se está en modo gameplay, desactivar el update de todo { principalMenu.Update(ElapsedTime); UpdateInstantiatedObjects(); spawnManager.Update(); UpdateBoundingBoxRendering(); // Actualizo el frustum para que solo tome hasta la fog distance asi no manda a renderizar items del quadtree que estén por detras var projectionMatrixFog = TGCMatrix.PerspectiveFovLH(D3DDevice.Instance.FieldOfView, D3DDevice.Instance.AspectRatio, D3DDevice.Instance.ZNearPlaneDistance, FastMath.Abs(fog.EndDistance)); Frustum.updateVolume(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View), projectionMatrixFog); ScenesQuadTree.UpdateVisibleObjects(Frustum); // Todos los objetos (estaticos y no estaticos) foreach (GameObject o in SceneObjects) { o.Update(); } // HeightMaps foreach (HeightMapTextured hm in heightMaps) { hm.Update(); } PlayAmbienceSound(); // Muevo el centro del skybox para que sea inalcanzable skyBox.Center = new TGCVector3(Camera.Position.X, 0, Camera.Position.Z); } UpdateHUD(); UpdateParticleEmitter(); time += ElapsedTime; PostUpdate(); }
public override void Render(DXGui gui) { // Guardo la TGCMatrix anterior TGCMatrix matAnt = TGCMatrix.FromMatrix(gui.sprite.Transform) * TGCMatrix.Identity; // Inicializo escalas, matrices, estados InitRender(gui); // Secuencia standard: texto + Frame + Glyph RenderText(); if (border) RenderFrame(); RenderGlyph(); // Restauro la transformacion del sprite gui.sprite.Transform = matAnt; }
/// <summary> /// Proyecta a pantalla el punto minimo y maximo de un BoundingBox y genera un vector 2D normalizado /// </summary> public static TGCVector2 projectAABBScreenVec(TgcBoundingAxisAlignBox aabb) { var device = D3DDevice.Instance.Device; var viewport = device.Viewport; var world = device.Transform.World; var view = device.Transform.View; var proj = device.Transform.Projection; //Proyectar punto minimo y maximo del AABB var minProj = TGCVector3.Project(aabb.PMin, viewport, TGCMatrix.FromMatrix(proj), TGCMatrix.FromMatrix(view), TGCMatrix.FromMatrix(world)); var maxProj = TGCVector3.Project(aabb.PMax, viewport, TGCMatrix.FromMatrix(proj), TGCMatrix.FromMatrix(view), TGCMatrix.FromMatrix(world)); //Armar vector 2D var vec2D = new TGCVector2(maxProj.X - minProj.X, maxProj.Y - minProj.Y); vec2D.Normalize(); return(vec2D); }
/// <summary> /// Proyecta el BoundingBox a un rectangulo 2D de screen space /// </summary> /// <returns>Rectangulo 2D con proyeccion en screen space</returns> public Rectangle projectToScreen() { var viewport = D3DDevice.Instance.Device.Viewport; var world = D3DDevice.Instance.Device.Transform.World; var view = D3DDevice.Instance.Device.Transform.View; var proj = D3DDevice.Instance.Device.Transform.Projection; //Proyectar los 8 corners del BoundingBox var projVertices = computeCorners(); for (var i = 0; i < projVertices.Length; i++) { projVertices[i] = TGCVector3.Project(projVertices[i], viewport, TGCMatrix.FromMatrix(proj), TGCMatrix.FromMatrix(view), TGCMatrix.FromMatrix(world)); } //Buscar los puntos extremos var min = new TGCVector2(float.MaxValue, float.MaxValue); var max = new TGCVector2(float.MinValue, float.MinValue); foreach (var v in projVertices) { if (v.X < min.X) { min.X = v.X; } if (v.Y < min.Y) { min.Y = v.Y; } if (v.X > max.X) { max.X = v.X; } if (v.Y > max.Y) { max.Y = v.Y; } } return(new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y))); }
/// <summary> /// Acutaliza el Frustum /// </summary> protected void UpdateFrustum() { Frustum.updateVolume(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View), TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.Projection)); }
public override void Update() { // 1) Crear una matriz de transformacion (de 4x4 para 3D) con la identidad var m = TGCMatrix.Identity; // 2) Crear una matriz de transformacion para traslacion var translate = TGCMatrix.Translation(new TGCVector3(100, -5, 0)); // 3) Crear una matriz de escalado para traslacion var scale = TGCMatrix.Scaling(new TGCVector3(2, 4, 2)); // 4) Crear una matriz de rotacion para traslacion var angleY = FastMath.PI_HALF; //En radianes var angleX = FastMath.ToRad(60); //De grados a radianes var angleZ = FastMath.PI / 14; var rotation = TGCMatrix.RotationYawPitchRoll(angleY, angleX, angleZ); //Ojo con el orden de los angulos // 5) Combinar varias matrices en una sola. El orden depende del movimiento que se quiera lograr var movimientoFinal = scale * rotation * translate; // 6) Transformar un punto en base al movimiento de una matriz de transformacion var p = new TGCVector3(10, 5, 10); var transformedVec4 = TGCVector3.Transform(p, movimientoFinal); //Devuelve un TGCVector4 poque estan las coordenadas homogeneas var transformedVec3 = new TGCVector3(transformedVec4.X, transformedVec4.Y, transformedVec4.Z); //Ignoramos la componente W // 7) Setear la matriz de World de DirectX D3DDevice.Instance.Device.Transform.World = movimientoFinal.ToMatrix(); // 8) Crear una matriz de View mirando hacia un determinado punto y aplicarla a DirectX var posicionCamara = new TGCVector3(20, 10, 0); var haciaDondeMiro = TGCVector3.Empty; var upVector = TGCVector3.Up; //Indica donde es arriba y donde abajo var viewMatrix = TGCMatrix.LookAtLH(posicionCamara, haciaDondeMiro, upVector); D3DDevice.Instance.Device.Transform.View = viewMatrix.ToMatrix(); // 9) Crear una matriz de proyeccion y aplicarla en DirectX var fieldOfViewY = FastMath.ToRad(45.0f); var aspectRatio = D3DDevice.Instance.AspectRatio; var zNearPlaneDistance = 1f; var zFarPlaneDistance = 10000f; var projection = TGCMatrix.PerspectiveFovLH(fieldOfViewY, aspectRatio, zNearPlaneDistance, zFarPlaneDistance); D3DDevice.Instance.Device.Transform.Projection = projection.ToMatrix(); // 10) Proyectar manualmente un punto 3D a la pantalla (lo que normalmente se hace dentro del vertex shader) var q = new TGCVector3(100, -15, 2); var worldViewProj = D3DDevice.Instance.Device.Transform.World * D3DDevice.Instance.Device.Transform.View * D3DDevice.Instance.Device.Transform.Projection; //Obtener la matriz final var projectedPoint = TGCVector3.Transform(q, TGCMatrix.FromMatrix(worldViewProj)); //Proyectar //Dividir por w projectedPoint.X /= projectedPoint.W; projectedPoint.Y /= projectedPoint.W; projectedPoint.Z /= projectedPoint.W; //La z solo es necesaria si queremos hacer Depth-testing //Pasarlo a screen-space var screenPoint = new Point( (int)(0.5f + (p.X + 1) * 0.5f * D3DDevice.Instance.Device.Viewport.Width), (int)(0.5f + (1 - p.Y) * 0.5f * D3DDevice.Instance.Device.Viewport.Height)); // 11) Con vertir de un punto 2D a uno 3D, al revez de lo que se hizo antes (normalmente para hacer picking con el mouse) var screenPoint2 = new Point(15, 100); //punto 2D de la pantalla var vAux = TGCVector3.Empty; vAux.X = (2.0f * screenPoint2.X / D3DDevice.Instance.Device.Viewport.Width - 1) / D3DDevice.Instance.Device.Transform.Projection.M11; vAux.Y = -(2.0f * screenPoint2.Y / D3DDevice.Instance.Device.Viewport.Height - 1) / D3DDevice.Instance.Device.Transform.Projection.M22; vAux.Z = 1.0f; var inverseView = TGCMatrix.Invert(TGCMatrix.FromMatrix(D3DDevice.Instance.Device.Transform.View)); //Invertir ViewMatrix var origin = new TGCVector3(inverseView.M41, inverseView.M42, inverseView.M43); var direction = new TGCVector3( vAux.X * inverseView.M11 + vAux.Y * inverseView.M21 + vAux.Z * inverseView.M31, vAux.X * inverseView.M12 + vAux.Y * inverseView.M22 + vAux.Z * inverseView.M32, vAux.X * inverseView.M13 + vAux.Y * inverseView.M23 + vAux.Z * inverseView.M33); //Con origin y direction formamos una recta que hay que buscar interseccion contra todos los objetos del escenario y quedarnos con la mas cercana a la camara }
public override void Render() { Device d3dDevice = D3DDevice.Instance.Device; time += ElapsedTime; TGCVector3 lightDir = lightDirModifier.Value; effect.SetValue("g_LightDir", TGCVector3.TGCVector3ToFloat3Array(lightDir)); effect.SetValue("min_cant_samples", minSampleModifier.Value); effect.SetValue("max_cant_samples", maxSampleModifier.Value); effect.SetValue("fHeightMapScale", heightMapScaleModifier.Value); effect.SetValue("fvEyePosition", TGCVector3.TGCVector3ToFloat3Array(Camera.Position)); effect.SetValue("time", time); effect.SetValue("aux_Tex", g_pBaseTexture); effect.SetValue("height_map", g_pHeightmap); effect.SetValue("phong_lighting", true); d3dDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); d3dDevice.BeginScene(); foreach (TgcMesh mesh in scene.Meshes) { bool va = true; int nro_textura = 0; mesh.Effect = effect; if (mesh.Name.Contains("Floor")) { effect.SetValue("g_normal", TGCVector3.TGCVector3ToFloat3Array(TGCVector3.Down)); effect.SetValue("g_tangent", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(1, 0, 0))); effect.SetValue("g_binormal", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(0, 0, 1))); nro_textura = 0; } else if (mesh.Name.Contains("Roof")) { effect.SetValue("g_normal", TGCVector3.TGCVector3ToFloat3Array(TGCVector3.Up)); effect.SetValue("g_tangent", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(1, 0, 0))); effect.SetValue("g_binormal", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(0, 0, 1))); nro_textura = 0; va = false; } else if (mesh.Name.Contains("East")) { effect.SetValue("g_normal", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(1, 0, 0))); effect.SetValue("g_tangent", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(0, 0, 1))); effect.SetValue("g_binormal", TGCVector3.TGCVector3ToFloat3Array(TGCVector3.Up)); nro_textura = 1; } else if (mesh.Name.Contains("West")) { effect.SetValue("g_normal", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(-1, 0, 0))); effect.SetValue("g_tangent", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(0, 0, 1))); effect.SetValue("g_binormal", TGCVector3.TGCVector3ToFloat3Array(TGCVector3.Up)); nro_textura = 1; } else if (mesh.Name.Contains("North")) { effect.SetValue("g_normal", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(0, 0, -1))); effect.SetValue("g_tangent", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(1, 0, 0))); effect.SetValue("g_binormal", TGCVector3.TGCVector3ToFloat3Array(TGCVector3.Up)); nro_textura = 1; } else if (mesh.Name.Contains("South")) { effect.SetValue("g_normal", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(0, 0, 1))); effect.SetValue("g_tangent", TGCVector3.TGCVector3ToFloat3Array(new TGCVector3(1, 0, 0))); effect.SetValue("g_binormal", TGCVector3.TGCVector3ToFloat3Array(TGCVector3.Up)); nro_textura = 1; } switch (nro_textura) { case 0: default: effect.SetValue("aux_Tex", g_pBaseTexture); effect.SetValue("height_map", g_pHeightmap); break; case 1: effect.SetValue("aux_Tex", g_pBaseTexture2); effect.SetValue("height_map", g_pHeightmap2); break; case 2: effect.SetValue("aux_Tex", g_pBaseTexture3); effect.SetValue("height_map", g_pHeightmap3); break; case 3: effect.SetValue("aux_Tex", g_pBaseTexture4); effect.SetValue("height_map", g_pHeightmap4); break; } if (va) { mesh.Technique = "ParallaxOcclusion2"; mesh.Render(); } } //Render personames enemigos foreach (TgcSkeletalMesh m in enemigos) { m.Render(); } // Render hud renderHUD(); gui.trapezoidal_style = false; //radar de proximidad float max_dist = 80; foreach (TgcSkeletalMesh m in enemigos) { TGCVector3 pos_personaje = Camera.Position; TGCVector3 pos_enemigo = m.Position * 1; float dist = (pos_personaje - pos_enemigo).Length(); if (dist < max_dist) { pos_enemigo.Y = m.BoundingBox.PMax.Y * 0.75f + m.BoundingBox.PMin.Y * 0.25f; pos_enemigo.Project(d3dDevice.Viewport, TGCMatrix.FromMatrix(d3dDevice.Transform.Projection), TGCMatrix.FromMatrix(d3dDevice.Transform.View), TGCMatrix.FromMatrix(d3dDevice.Transform.World)); if (pos_enemigo.Z > 0 && pos_enemigo.Z < 1) { float an = (max_dist - dist) / max_dist * 3.1415f * 2.0f; int d = (int)dist; gui.DrawArc(new TGCVector2(pos_enemigo.X + 20, pos_enemigo.Y), 40, 0, an, 10, dist < 30 ? Color.Tomato : Color.WhiteSmoke); gui.DrawLine(pos_enemigo.X, pos_enemigo.Y, pos_enemigo.X + 20, pos_enemigo.Y, 3, Color.PowderBlue); gui.DrawLine(pos_enemigo.X + 20, pos_enemigo.Y, pos_enemigo.X + 40, pos_enemigo.Y - 20, 3, Color.PowderBlue); gui.TextOut((int)pos_enemigo.X + 50, (int)pos_enemigo.Y - 20, "Proximidad " + d, Color.PowderBlue); } } } gui.trapezoidal_style = true; PostRender(); }
public override void Render() { ClearTextures(); var device = D3DDevice.Instance.Device; // guardo el Render target anterior y seteo la textura como render target var pOldRT = device.GetRenderTarget(0); var pSurf = g_pVel1.GetSurfaceLevel(0); device.SetRenderTarget(0, pSurf); // hago lo mismo con el depthbuffer, necesito el que no tiene multisampling var pOldDS = device.DepthStencilSurface; device.DepthStencilSurface = g_pDepthStencil; // 1 - Genero un mapa de velocidad effect.Technique = "VelocityMap"; // necesito mandarle la matrix de view proj anterior effect.SetValue("matWorldViewProjAnt", antMatWorldView.ToMatrix() * device.Transform.Projection); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); device.BeginScene(); renderScene("VelocityMap"); device.EndScene(); device.Present(); pSurf.Dispose(); // 2- Genero la imagen pp dicha effect.Technique = "DefaultTechnique"; pSurf = g_pRenderTarget.GetSurfaceLevel(0); device.SetRenderTarget(0, pSurf); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); device.BeginScene(); renderScene("DefaultTechnique"); device.EndScene(); device.Present(); pSurf.Dispose(); // Ultima pasada vertical va sobre la pantalla pp dicha device.SetRenderTarget(0, pOldRT); device.DepthStencilSurface = pOldDS; device.BeginScene(); effect.Technique = "PostProcessMotionBlur"; device.VertexFormat = CustomVertex.PositionTextured.Format; device.SetStreamSource(0, g_pVBV3D, 0); effect.SetValue("g_RenderTarget", g_pRenderTarget); effect.SetValue("texVelocityMap", g_pVel1); effect.SetValue("texVelocityMapAnt", g_pVel2); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); effect.Begin(FX.None); effect.BeginPass(0); device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); effect.EndPass(); effect.End(); device.EndScene(); device.Present(); // actualizo los valores para el proximo frame antMatWorldView = mesh.Transform * TGCMatrix.FromMatrix(device.Transform.View); var aux = g_pVel2; g_pVel2 = g_pVel1; g_pVel1 = aux; }
/// <summary> /// Proyectar un poligono 3D a 2D en la pantalla /// </summary> /// <param name="vertices">Vertices del poligono</param> /// <param name="box2D">Rectangulo 2D proyectado</param> /// <returns>False si es un caso degenerado de proyeccion y no debe considerarse</returns> public static bool projectPolygon(TGCVector3[] vertices, out Rectangle box2D) { //Datos de viewport var d3dDevice = D3DDevice.Instance.Device; var viewport = d3dDevice.Viewport; var view = d3dDevice.Transform.View; var proj = d3dDevice.Transform.Projection; var width = viewport.Width; var height = viewport.Height; box2D = new Rectangle(); //Proyectar todos los puntos, sin dividir aun por W var m = view * proj; var projVertices = new TGCVector3[vertices.Length]; for (var i = 0; i < vertices.Length; i++) { var pOut = TGCVector3.Transform(vertices[i], TGCMatrix.FromMatrix(m)); if (pOut.W < 0) { return(false); } projVertices[i] = toScreenSpace(pOut, width, height); } //Buscar los puntos extremos var min = new TGCVector2(float.MaxValue, float.MaxValue); var max = new TGCVector2(float.MinValue, float.MinValue); var minDepth = float.MaxValue; foreach (var v in projVertices) { if (v.X < min.X) { min.X = v.X; } if (v.Y < min.Y) { min.Y = v.Y; } if (v.X > max.X) { max.X = v.X; } if (v.Y > max.Y) { max.Y = v.Y; } if (v.Z < minDepth) { minDepth = v.Z; } } //Clamp if (min.X < 0f) { min.X = 0f; } if (min.Y < 0f) { min.Y = 0f; } if (max.X >= width) { max.X = width - 1; } if (max.Y >= height) { max.Y = height - 1; } //Control de tamaño minimo if (max.X - min.X < 1f) { return(false); } if (max.Y - min.Y < 1f) { return(false); } //Cargar valores de box2D box2D.Location = new Point((int)min.X, (int)min.Y); box2D.Size = new Size((int)(max.X - min.X), (int)(max.Y - min.Y)); return(true); }
/// <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; } } }