public /*override*/ void render(float elapsedTime, Personaje personaje, Vector3 llegada, Explosion explosion) { Device device = GuiController.Instance.D3dDevice; Control panel3d = GuiController.Instance.Panel3d; float aspectRatio = (float)panel3d.Width / (float)panel3d.Height; // if (GuiController.Instance.D3dInput.keyPressed(Microsoft.DirectX.DirectInput.Key.Space )) // vista_unica = !vista_unica; Vector3 lightPosition = (Vector3)GuiController.Instance.Modifiers["LightPosition"]; //Modifico parametros para que la luz gire en circulos /*cont = cont + elapsedTime * Geometry.DegreeToRadian(120.0f); * lightPosition.X = lightPosition.X + (10f * (float)Math.Cos(cont)); * lightPosition.Y = lightPosition.Y + (10f * (float)Math.Sin(cont)); * lightPosition.Z = lightPosition.Z + (50f * (float)Math.Sin(cont));*/ effect.Technique = "DefaultTechnique"; //Cargar variables de shader effect.SetValue("fvLightPosition", TgcParserUtils.vector3ToFloat3Array(lightPosition)); //effect.SetValue("fvEyePosition", TgcParserUtils.vector3ToFloat3Array(GuiController.Instance.RotCamera.getPosition())); effect.SetValue("k_la", (float)GuiController.Instance.Modifiers["Ambient"]); effect.SetValue("k_ld", (float)GuiController.Instance.Modifiers["Diffuse"]); effect.SetValue("k_ls", (float)GuiController.Instance.Modifiers["Specular"]); //effect.SetValue("fvAmbient", ColorValue.FromColor((Color)GuiController.Instance.Modifiers["AmbientColor"])); //effect.SetValue("fvDiffuse", ColorValue.FromColor((Color)GuiController.Instance.Modifiers["DiffuseColor"])); //effect.SetValue("fvSpecular", ColorValue.FromColor((Color)GuiController.Instance.Modifiers["SpecularColor"])); float distancia = FastMath.Pow2(personaje.getPersonaje().Position.X - llegada.X) + FastMath.Pow2(personaje.getPersonaje().Position.Z - llegada.Z); distancia = FastMath.Sqrt(distancia); distancia = Convert.ToInt32(distancia); if (explosion.estaEjecutandose()) { GuiController.Instance.Fog.Enabled = false; } else { if (distancia < DISNTANCIA_SIRENA) { GuiController.Instance.Fog.Enabled = false; } else { GuiController.Instance.Fog.Enabled = (bool)GuiController.Instance.Modifiers["Enabled"]; } } GuiController.Instance.Fog.StartDistance = (float)GuiController.Instance.Modifiers["startDistance"]; GuiController.Instance.Fog.EndDistance = (float)GuiController.Instance.Modifiers["endDistance"]; GuiController.Instance.Fog.Density = (float)GuiController.Instance.Modifiers["density"]; GuiController.Instance.Fog.Color = (Color)GuiController.Instance.Modifiers["color"]; //Actualizar valores de la Niebla GuiController.Instance.Fog.updateValues(); //Cambio los valores del Specular Power de la luz, para simular el parpadeo de la sirena r = t % 10; if (r == 0) { effect.SetValue("fSpecularPower", (float)10); } else { effect.SetValue("fSpecularPower", (float)200); } if (t == 1000) { t = 0; } else { t = t + 1; } //Mover mesh que representa la luz //lightBox.Position = lightPosition; // solo una vista //device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); device.Viewport = ViewF; /*foreach (MyMesh m in scene.Meshes) * { * if (m.Name != "escenarioPrueba") * { * m.effect = effect; * } * m.render();*/ patrulla.render(); //lightBox.render(); //} }
/// <summary> /// Detectar colision entre un Ray y una Capsula /// Basado en: http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrLine3Capsule3.cpp /// </summary> /// <param name="ray">Ray</param> /// <param name="capsule">Capsula</param> /// <param name="t">Menor instante de colision</param> /// <returns>True si hay colision</returns> private bool intersectRayCapsule(TgcRay.RayStruct ray, Capsule capsule, out float t) { t = -1; var origin = ray.origin; var dir = ray.direction; // Create a coordinate system for the capsule. In this system, the // capsule segment center C is the origin and the capsule axis direction // W is the z-axis. U and V are the other coordinate axis directions. // If P = x*U+y*V+z*W, the cylinder containing the capsule wall is // x^2 + y^2 = r^2, where r is the capsule radius. The finite cylinder // that makes up the capsule minus its hemispherical end caps has z-values // |z| <= e, where e is the extent of the capsule segment. The top // hemisphere cap is x^2+y^2+(z-e)^2 = r^2 for z >= e, and the bottom // hemisphere cap is x^2+y^2+(z+e)^2 = r^2 for z <= -e. var U = capsule.segment.dir; var V = U; var W = U; generateComplementBasis(ref U, ref V, W); var rSqr = capsule.radius * capsule.radius; var extent = capsule.segment.extent; // Convert incoming line origin to capsule coordinates. var diff = origin - capsule.segment.center; var P = new Vector3(Vector3.Dot(U, diff), Vector3.Dot(V, diff), Vector3.Dot(W, diff)); // Get the z-value, in capsule coordinates, of the incoming line's unit-length direction. var dz = Vector3.Dot(W, dir); if (FastMath.Abs(dz) >= 1f - float.Epsilon) { // The line is parallel to the capsule axis. Determine whether the line intersects the capsule hemispheres. var radialSqrDist = rSqr - P.X * P.X - P.Y * P.Y; if (radialSqrDist < 0f) { // Line outside the cylinder of the capsule, no intersection. return(false); } // line intersects the hemispherical caps var zOffset = FastMath.Sqrt(radialSqrDist) + extent; if (dz > 0f) { t = -P.Z - zOffset; } else { t = P.Z - zOffset; } return(true); } // Convert incoming line unit-length direction to capsule coordinates. var D = new Vector3(Vector3.Dot(U, dir), Vector3.Dot(V, dir), dz); // Test intersection of line P+t*D with infinite cylinder x^2+y^2 = r^2. // This reduces to computing the roots of a quadratic equation. If // P = (px,py,pz) and D = (dx,dy,dz), then the quadratic equation is // (dx^2+dy^2)*t^2 + 2*(px*dx+py*dy)*t + (px^2+py^2-r^2) = 0 var a0 = P.X * P.X + P.Y * P.Y - rSqr; var a1 = P.X * D.X + P.Y * D.Y; var a2 = D.X * D.X + D.Y * D.Y; var discr = a1 * a1 - a0 * a2; if (discr < 0f) { // Line does not intersect infinite cylinder. return(false); } float root, inv, tValue, zValue; var quantity = 0; if (discr > float.Epsilon) { // Line intersects infinite cylinder in two places. root = FastMath.Sqrt(discr); inv = 1f / a2; tValue = (-a1 - root) * inv; zValue = P.Z + tValue * D.Z; if (FastMath.Abs(zValue) <= extent) { quantity++; t = tValue; } tValue = (-a1 + root) * inv; zValue = P.Z + tValue * D.Z; if (FastMath.Abs(zValue) <= extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); } if (quantity == 2) { // Line intersects capsule wall in two places. return(true); } } else { // Line is tangent to infinite cylinder. tValue = -a1 / a2; zValue = P.Z + tValue * D.Z; if (FastMath.Abs(zValue) <= extent) { t = tValue; return(true); } } // Test intersection with bottom hemisphere. The quadratic equation is // t^2 + 2*(px*dx+py*dy+(pz+e)*dz)*t + (px^2+py^2+(pz+e)^2-r^2) = 0 // Use the fact that currently a1 = px*dx+py*dy and a0 = px^2+py^2-r^2. // The leading coefficient is a2 = 1, so no need to include in the // construction. var PZpE = P.Z + extent; a1 += PZpE * D.Z; a0 += PZpE * PZpE; discr = a1 * a1 - a0; if (discr > float.Epsilon) { root = FastMath.Sqrt(discr); tValue = -a1 - root; zValue = P.Z + tValue * D.Z; if (zValue <= -extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); if (quantity == 2) { return(true); } } tValue = -a1 + root; zValue = P.Z + tValue * D.Z; if (zValue <= -extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); if (quantity == 2) { return(true); } } } else if (FastMath.Abs(discr) <= float.Epsilon) { tValue = -a1; zValue = P.Z + tValue * D.Z; if (zValue <= -extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); if (quantity == 2) { return(true); } } } // Test intersection with top hemisphere. The quadratic equation is // t^2 + 2*(px*dx+py*dy+(pz-e)*dz)*t + (px^2+py^2+(pz-e)^2-r^2) = 0 // Use the fact that currently a1 = px*dx+py*dy+(pz+e)*dz and // a0 = px^2+py^2+(pz+e)^2-r^2. The leading coefficient is a2 = 1, so // no need to include in the construction. a1 -= 2f * extent * D.Z; a0 -= 4 * extent * P.Z; discr = a1 * a1 - a0; if (discr > float.Epsilon) { root = FastMath.Sqrt(discr); tValue = -a1 - root; zValue = P.Z + tValue * D.Z; if (zValue >= extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); if (quantity == 2) { return(true); } } tValue = -a1 + root; zValue = P.Z + tValue * D.Z; if (zValue >= extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); if (quantity == 2) { return(true); } } } else if (FastMath.Abs(discr) <= float.Epsilon) { tValue = -a1; zValue = P.Z + tValue * D.Z; if (zValue >= extent) { quantity++; t = TgcCollisionUtils.min(t, tValue); if (quantity == 2) { return(true); } } } return(quantity > 0); }
//mueve el barco y su boundingspehere en Y; hay que refactorearlo... //mueve el barco y su boundingspehere en Y; hay que refactorearlo... virtual public void flotar() { //normal del mar en el punto donde se encuentra el barco normal = Oceano.normalEnPuntoXZ(this.Position.X, this.Position.Z); //altura del mar en el punto de se encuentra el barco float Y = Oceano.alturaEnPunto(this.Position.X, this.Position.Z); //ponemos el bounding sphere a la altura donde esta el barco this.boundingSphere.moveCenter(new Vector3(0, Y - boundingSphere.Position.Y + 40, 0)); //ubicamos al barco... this.Position = new Vector3(this.Position.X, Y - 15, this.Position.Z); // ...en alto... this.rotation.Z = FastMath.Atan2(-normal.X * FastMath.Cos(this.rotation.Y), normal.Y) + FastMath.Atan2(normal.Z * FastMath.Sin(this.rotation.Y), normal.Y); // ...con rotacion en Z... this.rotation.X = FastMath.Atan2(normal.Z * FastMath.Cos(this.rotation.Y), normal.Y) + FastMath.Atan2(normal.X * FastMath.Sin(this.rotation.Y), normal.Y); // ...con rotacion en Y... }
public override void Render() { PreRender(); // 1) Crear una matriz de transformacion (de 4x4 para 3D) con la identidad var m = Matrix.Identity; // 2) Crear una matriz de transformacion para traslacion var translate = Matrix.Translation(new Vector3(100, -5, 0)); // 3) Crear una matriz de escalado para traslacion var scale = Matrix.Scaling(new Vector3(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 = Matrix.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 Vector3(10, 5, 10); var transformedVec4 = Vector3.Transform(p, movimientoFinal); //Devuelve un Vector4 poque estan las coordenadas homogeneas var transformedVec3 = new Vector3(transformedVec4.X, transformedVec4.Y, transformedVec4.Z); //Ignoramos la componente W // 7) Setear la matriz de World de DirectX D3DDevice.Instance.Device.Transform.World = movimientoFinal; // 8) Crear una matriz de View mirando hacia un determinado punto y aplicarla a DirectX var posicionCamara = new Vector3(20, 10, 0); var haciaDondeMiro = new Vector3(0, 0, 0); var upVector = new Vector3(0, 1, 0); //Indica donde es arriba y donde abajo var viewMatrix = Matrix.LookAtLH(posicionCamara, haciaDondeMiro, upVector); D3DDevice.Instance.Device.Transform.View = viewMatrix; // 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 = Matrix.PerspectiveFovLH(fieldOfViewY, aspectRatio, zNearPlaneDistance, zFarPlaneDistance); D3DDevice.Instance.Device.Transform.Projection = projection; // 10) Proyectar manualmente un punto 3D a la pantalla (lo que normalmente se hace dentro del vertex shader) var q = new Vector3(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 = Vector3.Transform(q, 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 = new Vector3(); 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 = Matrix.Invert(D3DDevice.Instance.Device.Transform.View); //Invertir ViewMatrix var origin = new Vector3(inverseView.M41, inverseView.M42, inverseView.M43); var direction = new Vector3( 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 DrawText.drawText( "Este ejemplo no muestra nada por pantalla. Sino que es para leer el codigo y sus comentarios.", 5, 50, Color.Yellow); PostRender(); }
/// <summary> /// Indica si un cilindro colisiona con un segmento. /// El cilindro se especifica con dos puntos centrales "cylinderInit" y "cylinderEnd" que forman una recta y con un /// radio "radius". /// Si hay colision se devuelve el instante de colision "t". /// No chequear EndCaps /// </summary> /// <param name="segmentInit">Punto de inicio del segmento</param> /// <param name="segmentEnd">Punto de fin del segmento</param> /// <param name="cylinderInit">Punto inicial del cilindro</param> /// <param name="cylinderEnd">Punto final del cilindro</param> /// <param name="radius">Radio del cilindro</param> /// <param name="t">Instante de colision</param> /// <returns>True si hay colision</returns> private static bool intersectSegmentCylinderNoEndcap(TGCVector3 segmentInit, TGCVector3 segmentEnd, TGCVector3 cylinderInit, TGCVector3 cylinderEnd, float radius, out float t) { t = -1; TGCVector3 d = cylinderEnd - cylinderInit, m = segmentInit - cylinderInit, n = segmentEnd - segmentInit; var md = TGCVector3.Dot(m, d); var nd = TGCVector3.Dot(n, d); var dd = TGCVector3.Dot(d, d); // Test if segment fully outside either endcap of cylinder if (md < 0.0f && md + nd < 0.0f) { return(false); // Segment outside ’p’ side of cylinder } if (md > dd && md + nd > dd) { return(false); // Segment outside ’q’ side of cylinder } var nn = TGCVector3.Dot(n, n); var mn = TGCVector3.Dot(m, n); var a = dd * nn - nd * nd; var k = TGCVector3.Dot(m, m) - radius * radius; var c = dd * k - md * md; if (FastMath.Abs(a) < float.Epsilon) { // Segment runs parallel to cylinder axis if (c > 0.0f) { return(false); // 'a' and thus the segment lie outside cylinder } // Now known that segment intersects cylinder; figure out how it intersects if (md < 0.0f) { t = -mn / nn; // Intersect segment against 'p' endcap } else if (md > dd) { t = (nd - mn) / nn; // Intersect segment against ’q’ endcap } else { t = 0.0f; // ’a’ lies inside cylinder } return(true); } var b = dd * mn - nd * md; var discr = b * b - a * c; if (discr < 0.0f) { return(false); // No real roots; no intersection } t = (-b - FastMath.Sqrt(discr)) / a; if (t < 0.0f || t > 1.0f) { return(false); // Intersection lies outside segment } /* No chequear EndCaps * * if (md + t * nd < 0.0f) { * // Intersection outside cylinder on 'p' side * if (nd <= 0.0f) return false; // Segment pointing away from endcap * t = -md / nd; * // Keep intersection if Dot(S(t) - p, S(t) - p) <= r^2 * return k + t * (2.0f * mn + t * nn) <= 0.0f; * } else if (md + t * nd > dd) { * // Intersection outside cylinder on 'q' side * if (nd >= 0.0f) return false; // Segment pointing away from endcap * t = (dd - md) / nd; * // Keep intersection if Dot(S(t) - q, S(t) - q) <= r^2 * return k + dd - 2.0f * md + t * (2.0f * (mn - nd) + t * nn) <= 0.0f; * } */ // Segment intersects cylinder between the endcaps; t is correct return(true); }
// Las coordenas x,z son Originales (sin Escalado) y el z devuelto es Original también (sin Escalado) public float CalcularAlturaTerreno(float x, float z, bool personaje = false) { // Calculo las coordenadas en la Matriz de Heightmap var pos_i = x + (HeightmapSize.Width / 2); var pos_j = z + (HeightmapSize.Width / 2); var pi = (int)pos_i; var fracc_i = pos_i - pi; var pj = (int)pos_j; var fracc_j = pos_j - pj; if (pi < 0) { pi = 0; } else if (pi > (HeightmapSize.Width - 1)) { pi = (HeightmapSize.Width - 1); } if (pj < 0) { pj = 0; } else if (pj > (HeightmapSize.Width - 1)) { pj = (HeightmapSize.Width - 1); } var pi1 = pi + 1; var pj1 = pj + 1; if (pi1 > (HeightmapSize.Width - 1)) { pi1 = (HeightmapSize.Width - 1); } if (pj1 > (HeightmapSize.Width - 1)) { pj1 = (HeightmapSize.Width - 1); } var pi2 = pi - 1; var pj2 = pj - 1; if (pi2 < 0) { pi2 = 0; } if (pj2 < 0) { pj2 = 0; } // 2x2 percent closest filtering usual: var H0 = terrain.HeightmapData[pi, pj]; var H1 = terrain.HeightmapData[pi1, pj]; var H2 = terrain.HeightmapData[pi, pj1]; var H3 = terrain.HeightmapData[pi1, pj1]; var H4 = terrain.HeightmapData[pi2, pj]; var H5 = terrain.HeightmapData[pi2, pj1]; var H6 = terrain.HeightmapData[pi2, pj2]; var H7 = terrain.HeightmapData[pi, pj2]; var H8 = terrain.HeightmapData[pi1, pj2]; var H = (H0 * (1 - fracc_i) + H1 * fracc_i) * (1 - fracc_j) + (H2 * (1 - fracc_i) + H3 * fracc_i) * fracc_j; if (personaje) { H = FastMath.Max(FastMath.Max(FastMath.Max(H0, H1), FastMath.Max(H2, H3)), FastMath.Max(H4, H5)) + 1; //H = ((H0 + H1 + H2 + H3 + H4 + H5) / 6)+2; } return(H); }
public override void Render() { PreRender(); ClearTextures(); bool invisibilidadActivada = (SwitchInvisibilidadJ1 - 1 == SwitchCamara) || (SwitchInvisibilidadJ2 == SwitchCamara); //Permito las particulas D3DDevice.Instance.ParticlesEnabled = true; D3DDevice.Instance.EnableParticles(); switch (SwitchInicio) { case 1: { Hud.PantallaInicio(); if (Input.keyPressed(Key.C)) { SwitchInicio = 2; } if (Input.keyPressed(Key.D1)) { Jugadores[1] = null; SwitchInicio = 3; SwitchMusica = true; SwitchFX = true; AutoFisico1.Encendido(); inGame = true; } if (Input.keyPressed(Key.D2)) { juegoDoble = true; SwitchInicio = 4; SwitchMusica = true; SwitchFX = true; SwitchCamara = 3; AutoFisico1.Encendido(); AutoFisico2.Encendido(); inGame = true; } break; } case 2: { Hud.PantallaControles(); if (Input.keyPressed(Key.V)) { SwitchInicio = 1; } break; } case 3: { var device = D3DDevice.Instance.Device; Tiempo += ElapsedTime; AutoFisico1.ElapsedTime = ElapsedTime; AutoFisico1.FXActivado = SwitchFX; // ShaderInvisibilidad ----- Invisibilidad.Technique = "DefaultTechnique"; var pOldRT = device.GetRenderTarget(0); var pSurf = g_pRenderTarget.GetSurfaceLevel(0); if (invisibilidadActivada) { device.SetRenderTarget(0, pSurf); } var pOldDS = device.DepthStencilSurface; if (invisibilidadActivada) { device.DepthStencilSurface = g_pDepthStencil; } device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); //--------------------------- Plaza.RenderAll(); AutoFisico1.Render(ElapsedTime); GrupoPolicias.Render(ElapsedTime); Cielo.Render(); pSurf.Dispose(); if (invisibilidadActivada) { device.DepthStencilSurface = pOldDS; device.SetRenderTarget(0, pOldRT); Invisibilidad.Technique = "PostProcess"; Invisibilidad.SetValue("time", Tiempo); device.VertexFormat = CustomVertex.PositionTextured.Format; device.SetStreamSource(0, g_pVBV3D, 0); Invisibilidad.SetValue("g_RenderTarget", g_pRenderTarget); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); Invisibilidad.Begin(FX.None); Invisibilidad.BeginPass(0); device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); Invisibilidad.EndPass(); Invisibilidad.End(); } Hud.Juego(invisibilidadActivada, JugadorActivo, juegoDoble, pantallaDoble, AutoFisico1, AutoFisico2); if (AutoFisico1.Vida < 0) { TiempoFinal = Tiempo; Sonidos.SuenaGameOver(); SwitchInicio = 5; } if (Input.keyDown(Key.F10)) { Hud.Pausar(); } // Shader Enviroment Map -------------------------------- //D3DDevice.Instance.Device.EndScene(); var g_pCubeMap = new CubeTexture(D3DDevice.Instance.Device, 256, 1, Usage.RenderTarget, Format.A16B16G16R16F, Pool.Default); var pOldRT2 = D3DDevice.Instance.Device.GetRenderTarget(0); D3DDevice.Instance.Device.Transform.Projection = TGCMatrix.PerspectiveFovLH(Geometry.DegreeToRadian(90.0f), 1f, 1f, 10000f).ToMatrix(); // Genero las caras del enviroment map for (var nFace = CubeMapFace.PositiveX; nFace <= CubeMapFace.NegativeZ; ++nFace) { var pFace = g_pCubeMap.GetCubeMapSurface(nFace, 0); D3DDevice.Instance.Device.SetRenderTarget(0, pFace); TGCVector3 Dir, VUP; Color color; switch (nFace) { default: case CubeMapFace.PositiveX: // Left Dir = new TGCVector3(1, 0, 0); VUP = TGCVector3.Up; color = Color.Black; break; case CubeMapFace.NegativeX: // Right Dir = new TGCVector3(-1, 0, 0); VUP = TGCVector3.Up; color = Color.Red; break; case CubeMapFace.PositiveY: // Up Dir = TGCVector3.Up; VUP = new TGCVector3(0, 0, -1); color = Color.Gray; break; case CubeMapFace.NegativeY: // Down Dir = TGCVector3.Down; VUP = new TGCVector3(0, 0, 1); color = Color.Yellow; break; case CubeMapFace.PositiveZ: // Front Dir = new TGCVector3(0, 0, 1); VUP = TGCVector3.Up; color = Color.Green; break; case CubeMapFace.NegativeZ: // Back Dir = new TGCVector3(0, 0, -1); VUP = TGCVector3.Up; color = Color.Blue; break; } D3DDevice.Instance.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, color, 1.0f, 0); //Renderizar foreach (var mesh in AutoFisico1.Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } } D3DDevice.Instance.Device.SetRenderTarget(0, pOldRT2); D3DDevice.Instance.Device.Transform.View = Camara.GetViewMatrix().ToMatrix(); D3DDevice.Instance.Device.Transform.Projection = TGCMatrix.PerspectiveFovLH(Geometry.DegreeToRadian(45.0f), D3DDevice.Instance.AspectRatio, 1f, 10000f).ToMatrix(); //D3DDevice.Instance.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); EnvMap.SetValue("g_txCubeMap", g_pCubeMap); foreach (var mesh in AutoFisico1.Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } foreach (var rueda in AutoFisico1.Ruedas) { rueda.Effect = EnvMap; rueda.Technique = "RenderScene"; rueda.Render(); } foreach (var mesh in GrupoPolicias.Todos[0].Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } g_pCubeMap.Dispose(); //------------------------------------------------------------- Hud.Tiempo(FastMath.Floor(Tiempo)); break; } case 4: { var device = D3DDevice.Instance.Device; Tiempo += ElapsedTime; AutoFisico1.ElapsedTime = ElapsedTime; AutoFisico2.ElapsedTime = ElapsedTime; AutoFisico1.FXActivado = SwitchFX; AutoFisico2.FXActivado = SwitchFX; // ShaderInvisibilidad ----- Invisibilidad.Technique = "DefaultTechnique"; var pOldRT = device.GetRenderTarget(0); var pSurf = g_pRenderTarget.GetSurfaceLevel(0); if (invisibilidadActivada) { device.SetRenderTarget(0, pSurf); } var pOldDS = device.DepthStencilSurface; if (invisibilidadActivada) { device.DepthStencilSurface = g_pDepthStencil; } device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); //-------------------------- DrawText.drawText("Velocidad P1:" + AutoFisico1.Velocidad, 0, 90, Color.Green); Plaza.RenderAll(); AutoFisico1.Render(ElapsedTime); AutoFisico2.Render(ElapsedTime); GrupoPolicias.Render(ElapsedTime); Cielo.Render(); pSurf.Dispose(); if (invisibilidadActivada) { device.DepthStencilSurface = pOldDS; device.SetRenderTarget(0, pOldRT); Invisibilidad.Technique = "PostProcess"; Invisibilidad.SetValue("time", Tiempo); device.VertexFormat = CustomVertex.PositionTextured.Format; device.SetStreamSource(0, g_pVBV3D, 0); Invisibilidad.SetValue("g_RenderTarget", g_pRenderTarget); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); Invisibilidad.Begin(FX.None); Invisibilidad.BeginPass(0); device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); Invisibilidad.EndPass(); Invisibilidad.End(); } Hud.Juego(invisibilidadActivada, JugadorActivo, juegoDoble, pantallaDoble, AutoFisico1, AutoFisico2); if (AutoFisico1.Vida < 0) { Hud.GanoJ2(); SwitchCamara = 2; Jugadores[1] = null; Sonidos.SuenaAplausos(); inGame = false; } if (AutoFisico2.Vida < 0) { Hud.GanoJ1(); SwitchCamara = 1; Jugadores[0] = null; Sonidos.SuenaAplausos(); inGame = false; } if (Input.keyDown(Key.F10)) { Hud.Pausar(); } if (Input.keyDown(Key.F10)) { Hud.Pausar(); } // Shader Enviroment Map -------------------------------- //D3DDevice.Instance.Device.EndScene(); var g_pCubeMap = new CubeTexture(D3DDevice.Instance.Device, 256, 1, Usage.RenderTarget, Format.A16B16G16R16F, Pool.Default); var pOldRT2 = D3DDevice.Instance.Device.GetRenderTarget(0); D3DDevice.Instance.Device.Transform.Projection = TGCMatrix.PerspectiveFovLH(Geometry.DegreeToRadian(90.0f), 1f, 1f, 10000f).ToMatrix(); // Genero las caras del enviroment map for (var nFace = CubeMapFace.PositiveX; nFace <= CubeMapFace.NegativeZ; ++nFace) { var pFace = g_pCubeMap.GetCubeMapSurface(nFace, 0); D3DDevice.Instance.Device.SetRenderTarget(0, pFace); TGCVector3 Dir, VUP; Color color; switch (nFace) { default: case CubeMapFace.PositiveX: // Left Dir = new TGCVector3(1, 0, 0); VUP = TGCVector3.Up; color = Color.Black; break; case CubeMapFace.NegativeX: // Right Dir = new TGCVector3(-1, 0, 0); VUP = TGCVector3.Up; color = Color.Red; break; case CubeMapFace.PositiveY: // Up Dir = TGCVector3.Up; VUP = new TGCVector3(0, 0, -1); color = Color.Gray; break; case CubeMapFace.NegativeY: // Down Dir = TGCVector3.Down; VUP = new TGCVector3(0, 0, 1); color = Color.Yellow; break; case CubeMapFace.PositiveZ: // Front Dir = new TGCVector3(0, 0, 1); VUP = TGCVector3.Up; color = Color.Green; break; case CubeMapFace.NegativeZ: // Back Dir = new TGCVector3(0, 0, -1); VUP = TGCVector3.Up; color = Color.Blue; break; } D3DDevice.Instance.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, color, 1.0f, 0); //Renderizar foreach (var mesh in AutoFisico1.Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } foreach (var mesh in AutoFisico2.Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } } D3DDevice.Instance.Device.SetRenderTarget(0, pOldRT2); D3DDevice.Instance.Device.Transform.View = Camara.GetViewMatrix().ToMatrix(); D3DDevice.Instance.Device.Transform.Projection = TGCMatrix.PerspectiveFovLH(Geometry.DegreeToRadian(45.0f), D3DDevice.Instance.AspectRatio, 1f, 10000f).ToMatrix(); //D3DDevice.Instance.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); EnvMap.SetValue("g_txCubeMap", g_pCubeMap); foreach (var mesh in AutoFisico1.Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } foreach (var mesh in AutoFisico2.Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } foreach (var rueda in AutoFisico1.Ruedas) { rueda.Effect = EnvMap; rueda.Technique = "RenderScene"; rueda.Render(); } foreach (var mesh in GrupoPolicias.Todos[0].Mayas) { mesh.Effect = EnvMap; mesh.Technique = "RenderScene"; mesh.Render(); } g_pCubeMap.Dispose(); //------------------------------------------------------------- Hud.Tiempo(FastMath.Floor(Tiempo)); break; } case 5: { SwitchFX = false; SwitchMusica = false; inGame = false; Hud.JuegoTerminado(); Hud.TiempoFinal(FastMath.Floor(TiempoFinal)); if (Input.keyPressed(Key.M)) { SwitchInicio = 1; } break; } } PostRender(); }
/// <summary> /// Calcular Tangent y Binormal en base a los 3 vertices de un triangulo y la normal del primero de ellos /// Basado en: http://www.dhpoware.com/demos/d3d9NormalMapping.html /// </summary> public static void computeTangentBinormal(BumpMappingVertex v1, BumpMappingVertex v2, BumpMappingVertex v3, out TGCVector3 tangent, out TGCVector3 binormal) { // Given the 3 vertices (position and texture coordinates) of a triangle // calculate and return the triangle's tangent vector. The handedness of // the local coordinate system is stored in tangent.w. The bitangent is // then: float3 bitangent = cross(normal, tangent.xyz) * tangent.w. // Create 2 vectors in object space. // // edge1 is the vector from vertex positions v1 to v2. // edge2 is the vector from vertex positions v1 to v3. var edge1 = v2.Position - v1.Position; var edge2 = v3.Position - v1.Position; edge1.Normalize(); edge2.Normalize(); // Create 2 vectors in tangent (texture) space that point in the same // direction as edge1 and edge2 (in object space). // // texEdge1 is the vector from texture coordinates texCoord1 to texCoord2. // texEdge2 is the vector from texture coordinates texCoord1 to texCoord3. var texEdge1 = new TGCVector2(v2.Tu - v1.Tu, v2.Tv - v1.Tv); var texEdge2 = new TGCVector2(v3.Tu - v1.Tu, v3.Tv - v1.Tv); texEdge1.Normalize(); texEdge2.Normalize(); // These 2 sets of vectors form the following system of equations: // // edge1 = (texEdge1.x * tangent) + (texEdge1.y * bitangent) // edge2 = (texEdge2.x * tangent) + (texEdge2.y * bitangent) // // Using matrix notation this system looks like: // // [ edge1 ] [ texEdge1.x texEdge1.y ] [ tangent ] // [ ] = [ ] [ ] // [ edge2 ] [ texEdge2.x texEdge2.y ] [ bitangent ] // // The solution is: // // [ tangent ] 1 [ texEdge2.y -texEdge1.y ] [ edge1 ] // [ ] = ------- [ ] [ ] // [ bitangent ] det A [-texEdge2.x texEdge1.x ] [ edge2 ] // // where: // [ texEdge1.x texEdge1.y ] // A = [ ] // [ texEdge2.x texEdge2.y ] // // det A = (texEdge1.x * texEdge2.y) - (texEdge1.y * texEdge2.x) // // From this solution the tangent space basis vectors are: // // tangent = (1 / det A) * ( texEdge2.y * edge1 - texEdge1.y * edge2) // bitangent = (1 / det A) * (-texEdge2.x * edge1 + texEdge1.x * edge2) // normal = cross(tangent, bitangent) var det = texEdge1.X * texEdge2.Y - texEdge1.Y * texEdge2.X; if (FastMath.Abs(det) < 0.0001f) // almost equal to zero { tangent = new TGCVector3(1.0f, 0.0f, 0.0f); binormal = new TGCVector3(0.0f, 1.0f, 0.0f); } else { det = 1.0f / det; tangent = TGCVector3.Empty; tangent.X = (texEdge2.Y * edge1.X - texEdge1.Y * edge2.X) * det; tangent.Y = (texEdge2.Y * edge1.Y - texEdge1.Y * edge2.Y) * det; tangent.Z = (texEdge2.Y * edge1.Z - texEdge1.Y * edge2.Z) * det; //tangent.W = 0.0f; binormal = TGCVector3.Empty; binormal.X = (-texEdge2.X * edge1.X + texEdge1.X * edge2.X) * det; binormal.Y = (-texEdge2.X * edge1.Y + texEdge1.X * edge2.Y) * det; binormal.Z = (-texEdge2.X * edge1.Z + texEdge1.X * edge2.Z) * det; tangent.Normalize(); binormal.Normalize(); } // Calculate the handedness of the local tangent space. // The bitangent vector is the cross product between the triangle face // normal vector and the calculated tangent vector. The resulting bitangent // vector should be the same as the bitangent vector calculated from the // set of linear equations above. If they point in different directions // then we need to invert the cross product calculated bitangent vector. var b = TGCVector3.Cross(v1.Normal, tangent); var w = TGCVector3.Dot(b, binormal) < 0.0f ? -1.0f : 1.0f; binormal = b * w; }
public void Update() { var velocidadCaminar = 300f; var velocidadSalto = 100f; var velocidadRotacion = 120f; vectorDesplazamiento = TGCVector3.Empty; vectorColision = TGCVector3.Empty; //Calcular proxima posicion de personaje segun Input var Input = GModel.Input; var moveForward = 0f; var moveJump = 0f; float rotate = 0; var moving = false; var rotating = false; var lastPos = personaje.Position; desplazamientoDePlataforma = TGCVector3.Empty; //Adelante if (Input.keyDown(Key.W)) { moveForward = velocidadCaminar * GModel.ElapsedTime; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = -velocidadCaminar * GModel.ElapsedTime; moving = true; } //Derecha if (Input.keyDown(Key.D)) { rotate = velocidadRotacion; rotating = true; } //Izquierda if (Input.keyDown(Key.A)) { rotate = -velocidadRotacion; rotating = true; } //Si hubo rotacion if (rotating) { //Rotar personaje y la camara, hay que multiplicarlo por el tiempo transcurrido para no atarse a la velocidad el hardware var rotAngle = FastMath.ToRad(rotate * GModel.ElapsedTime); matrizRotacionPersonajeY *= TGCMatrix.RotationY(rotAngle); GModel.camaraInterna.rotateY(rotAngle); anguloDeRotacion += rotAngle; //Ajustar la matriz de rotacion segun el angulo de rotacion (sobre el sentido de la orientacion) //Lo que se desplaza en cada eje depende del angulo de rotacion //Cada componente podria separarse en funcion del seno y coseno orientacion.X = FastMath.Sin(anguloDeRotacion); orientacion.Z = FastMath.Cos(anguloDeRotacion); } if (moving) { //Activar animacion de caminando personaje.playAnimation("Caminando", true); //Ajustar el vector desplazamiento en base a lo que se movio y la orientacion que tiene vectorDesplazamiento.X += moveForward * orientacion.X; vectorDesplazamiento.Z += moveForward * orientacion.Z; } //Si no se esta moviendo, activar animacion de Parado else { personaje.playAnimation("Parado", true); } //----------Salto //Por el momento solamente parece que flota if (Input.keyDown(Key.Space) /*&& colliderY != null*/) { moveJump = velocidadSalto * GModel.ElapsedTime; vectorDesplazamiento.Y += moveJump; } //---------prueba gravedad---------- vectorDesplazamiento.Y += FastMath.Clamp(gravedad * GModel.ElapsedTime, -10, 10); //--------Colision con el piso a nivel triangulo TgcBoundingAxisAlignBox colliderPlano = null; foreach (var obstaculo in GModel.escenario1.getPiso()) { if (TgcCollisionUtils.testAABBAABB(personaje.BoundingBox, obstaculo.BoundingBox)) { colliderPlano = obstaculo.BoundingBox; //No le afecta la gravedad si está en el piso vectorDesplazamiento.Y -= FastMath.Clamp(gravedad * GModel.ElapsedTime, -10, 10); break; } } this.posicion = posicion + vectorDesplazamiento; //Reseteo el vector desplazamiento una vez que lo sume vectorDesplazamiento = TGCVector3.Empty; //---------Colisiones objetos-------------------------- var collide = false; foreach (var obstaculo in GModel.escenario1.getAABBDelEscenario() /*GModel.escenario1.getPared1()*/) { if (TgcCollisionUtils.testAABBAABB(personaje.BoundingBox, obstaculo)) { collide = true; collider = obstaculo; break; } } //Una buena idea seria diferenciar las plataformas del resto de los objetos foreach (var plataforma in GModel.escenario1.getPlataformasDelEscenario()) { if (TgcCollisionUtils.testAABBAABB(personaje.BoundingBox, plataforma)) { collide = true; collider = plataforma; //Pensamos en calcular cuanto se desplaza la plataforma y mandarselo al personaje para que se muevan juntos //Todavia no funciona como esperamos desplazamientoDePlataforma = GModel.escenario1.desplazamientoDePlataforma(collider); break; } } if (collide) { var movementRay = lastPos - posicion; //Cuando choca con algo que se ponga rojo, nos sirve para probar collider.setRenderColor(Color.Red); var rs = TGCVector3.Empty; if (((personaje.BoundingBox.PMax.X > collider.PMax.X && movementRay.X > 0) || (personaje.BoundingBox.PMin.X < collider.PMin.X && movementRay.X < 0)) && ((personaje.BoundingBox.PMax.Z > collider.PMax.Z && movementRay.Z > 0) || (personaje.BoundingBox.PMin.Z < collider.PMin.Z && movementRay.Z < 0)) && ((personaje.BoundingBox.PMax.Y > collider.PMax.Y && movementRay.Y > 0) || (personaje.BoundingBox.PMin.Y < collider.PMin.Y && movementRay.Y < 0))) { if (personaje.Position.X > collider.PMin.X && personaje.Position.X < collider.PMax.X) { //El personaje esta contenido en el bounding X rs = new TGCVector3(movementRay.X, movementRay.Y, 0); } if (personaje.Position.Z > collider.PMin.Z && personaje.Position.Z < collider.PMax.Z) { //El personaje esta contenido en el bounding Z rs = new TGCVector3(0, movementRay.Y, movementRay.Z); } if (personaje.Position.Y > collider.PMin.Y && personaje.Position.Y < collider.PMax.Y) { //El personaje esta contenido en el bounding Y rs = new TGCVector3(movementRay.X, 0, movementRay.Z); } } else { if ((personaje.BoundingBox.PMax.X > collider.PMax.X && movementRay.X > 0) || (personaje.BoundingBox.PMin.X < collider.PMin.X && movementRay.X < 0)) { rs = new TGCVector3(0, movementRay.Y, movementRay.Z); } if ((personaje.BoundingBox.PMax.Z > collider.PMax.Z && movementRay.Z > 0) || (personaje.BoundingBox.PMin.Z < collider.PMin.Z && movementRay.Z < 0)) { rs = new TGCVector3(movementRay.X, movementRay.Y, 0); } if ((personaje.BoundingBox.PMax.Y > collider.PMax.Y && movementRay.Y > 0) || (personaje.BoundingBox.PMin.Y < collider.PMin.Y && movementRay.Y < 0)) { //Si esta sobre un plano XZ tampoco deberia afectarle la gravedad vectorDesplazamiento.Y -= FastMath.Clamp(gravedad * GModel.ElapsedTime, -10, 10); rs = new TGCVector3(movementRay.X, 0, movementRay.Z); } } //El vector rs actua como "freno" al movimiento del personaje //Le "descuento" la gravedad si es que colisiona con el plano XZ personaje.Position = lastPos - rs + new TGCVector3(0, vectorDesplazamiento.Y, 0); posicion = personaje.Position; } personaje.Position = posicion; //Una forma de reiniciar, que se active con R o cuando el personaje muere //Por ahora el personaje muere solamente si su coordenada en Y es inferior a un valor determinado if (Input.keyDown(Key.R) || this.estaMuerto()) { posicion = this.checkpoint; } matrizPosicionamientoPersonaje = TGCMatrix.Translation(posicion /*+ desplazamientoDePlataforma*/); GModel.camaraInterna.Target = GModel.tgcPersonaje.getPosicion(); }
public override void Effect(Character character) { var hitPointsGained = healingRate * character.maxHitPoints; character.hitPoints = FastMath.Min(character.maxHitPoints, character.hitPoints + hitPointsGained); }
/// <summary> /// Find a complex root for the polynomial with the given coefficients, /// starting from the given initial value. /// </summary> /// <param name="coefficients"> Polynomial coefficients. </param> /// <param name="initial"> Start value. </param> /// <returns> the point at which the function value is zero. </returns> /// <exception cref="org.apache.commons.math3.exception.TooManyEvaluationsException"> /// if the maximum number of evaluations is exceeded. </exception> /// <exception cref="NullArgumentException"> if the {@code coefficients} is /// {@code null}. </exception> /// <exception cref="NoDataException"> if the {@code coefficients} array is empty. </exception> public virtual Complex Solve(Complex[] coefficients, Complex initial) { if (coefficients == null) { throw new NullArgumentException(); } int n = coefficients.Length - 1; if (n == 0) { throw new NoDataException(LocalizedFormats.POLYNOMIAL); } double absoluteAccuracy = outerInstance.AbsoluteAccuracy; double relativeAccuracy = outerInstance.RelativeAccuracy; double functionValueAccuracy = outerInstance.FunctionValueAccuracy; Complex nC = new Complex(n, 0); Complex n1C = new Complex(n - 1, 0); Complex z = initial; Complex oldz = new Complex(double.PositiveInfinity, double.PositiveInfinity); while (true) { // Compute pv (polynomial value), dv (derivative value), and // d2v (second derivative value) simultaneously. Complex pv = coefficients[n]; Complex dv = Complex.ZERO; Complex d2v = Complex.ZERO; for (int j = n - 1; j >= 0; j--) { d2v = dv.add(z.multiply(d2v)); dv = pv.add(z.multiply(dv)); pv = coefficients[j].add(z.multiply(pv)); } d2v = d2v.multiply(new Complex(2.0, 0.0)); // Check for convergence. double tolerance = FastMath.max(relativeAccuracy * z.abs(), absoluteAccuracy); if ((z.subtract(oldz)).abs() <= tolerance) { return(z); } if (pv.abs() <= functionValueAccuracy) { return(z); } // Now pv != 0, calculate the new approximation. Complex G = dv.divide(pv); Complex G2 = G.multiply(G); Complex H = G2.subtract(d2v.divide(pv)); Complex delta = n1C.multiply((nC.multiply(H)).subtract(G2)); // Choose a denominator larger in magnitude. Complex deltaSqrt = delta.sqrt(); Complex dplus = G.add(deltaSqrt); Complex dminus = G.subtract(deltaSqrt); Complex denominator = dplus.abs() > dminus.abs() ? dplus : dminus; // Perturb z if denominator is zero, for instance, // p(x) = x^3 + 1, z = 0. if (denominator.Equals(new Complex(0.0, 0.0))) { z = z.add(new Complex(absoluteAccuracy, absoluteAccuracy)); oldz = new Complex(double.PositiveInfinity, double.PositiveInfinity); } else { oldz = z; z = z.subtract(nC.divide(denominator)); } outerInstance.IncrementEvaluationCount(); } }
/// <summary> /// Radio del BoundingBox /// </summary> public float calculateBoxRadius() { var rsq = calculateBoxRadiusSquare(); return(FastMath.Sqrt(rsq)); }
/// <summary> /// Returns the inverse erf. /// <para> /// This implementation is described in the paper: /// <a href="http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf">Approximating /// the erfinv function</a> by Mike Giles, Oxford-Man Institute of Quantitative Finance, /// which was published in GPU Computing Gems, volume 2, 2010. /// The source code is available <a href="http://gpucomputing.net/?q=node/1828">here</a>. /// </para> /// </summary> /// <param name="x">the value</param> /// <returns>t such that x = erf(t)</returns> public static double erfInv(double x) { // beware that the logarithm argument must be // commputed as (1.0 - x) * (1.0 + x), // it must NOT be simplified as 1.0 - x * x as this // would induce rounding errors near the boundaries +/-1 double w = -FastMath.log((1.0 - x) * (1.0 + x)); double p; if (w < 6.25) { w -= 3.125; p = -3.6444120640178196996e-21; p = -1.685059138182016589e-19 + p * w; p = 1.2858480715256400167e-18 + p * w; p = 1.115787767802518096e-17 + p * w; p = -1.333171662854620906e-16 + p * w; p = 2.0972767875968561637e-17 + p * w; p = 6.6376381343583238325e-15 + p * w; p = -4.0545662729752068639e-14 + p * w; p = -8.1519341976054721522e-14 + p * w; p = 2.6335093153082322977e-12 + p * w; p = -1.2975133253453532498e-11 + p * w; p = -5.4154120542946279317e-11 + p * w; p = 1.051212273321532285e-09 + p * w; p = -4.1126339803469836976e-09 + p * w; p = -2.9070369957882005086e-08 + p * w; p = 4.2347877827932403518e-07 + p * w; p = -1.3654692000834678645e-06 + p * w; p = -1.3882523362786468719e-05 + p * w; p = 0.0001867342080340571352 + p * w; p = -0.00074070253416626697512 + p * w; p = -0.0060336708714301490533 + p * w; p = 0.24015818242558961693 + p * w; p = 1.6536545626831027356 + p * w; } else if (w < 16.0) { w = FastMath.sqrt(w) - 3.25; p = 2.2137376921775787049e-09; p = 9.0756561938885390979e-08 + p * w; p = -2.7517406297064545428e-07 + p * w; p = 1.8239629214389227755e-08 + p * w; p = 1.5027403968909827627e-06 + p * w; p = -4.013867526981545969e-06 + p * w; p = 2.9234449089955446044e-06 + p * w; p = 1.2475304481671778723e-05 + p * w; p = -4.7318229009055733981e-05 + p * w; p = 6.8284851459573175448e-05 + p * w; p = 2.4031110387097893999e-05 + p * w; p = -0.0003550375203628474796 + p * w; p = 0.00095328937973738049703 + p * w; p = -0.0016882755560235047313 + p * w; p = 0.0024914420961078508066 + p * w; p = -0.0037512085075692412107 + p * w; p = 0.005370914553590063617 + p * w; p = 1.0052589676941592334 + p * w; p = 3.0838856104922207635 + p * w; } else if (!Double.IsInfinity(w)) { w = FastMath.sqrt(w) - 5.0; p = -2.7109920616438573243e-11; p = -2.5556418169965252055e-10 + p * w; p = 1.5076572693500548083e-09 + p * w; p = -3.7894654401267369937e-09 + p * w; p = 7.6157012080783393804e-09 + p * w; p = -1.4960026627149240478e-08 + p * w; p = 2.9147953450901080826e-08 + p * w; p = -6.7711997758452339498e-08 + p * w; p = 2.2900482228026654717e-07 + p * w; p = -9.9298272942317002539e-07 + p * w; p = 4.5260625972231537039e-06 + p * w; p = -1.9681778105531670567e-05 + p * w; p = 7.5995277030017761139e-05 + p * w; p = -0.00021503011930044477347 + p * w; p = -0.00013871931833623122026 + p * w; p = 1.0103004648645343977 + p * w; p = 4.8499064014085844221 + p * w; } else { // this branch does not appears in the original code, it // was added because the previous branch does not handle // x = +/-1 correctly. In this case, w is positive infinity // and as the first coefficient (-2.71e-11) is negative. // Once the first multiplication is done, p becomes negative // infinity and remains so throughout the polynomial evaluation. // So the branch above incorrectly returns negative infinity // instead of the correct positive infinity. p = Double.PositiveInfinity; } return(p * x); }
public float distance(Vector3 a, Vector3 b) { return(FastMath.Sqrt(FastMath.Pow2(a.X - b.X) + FastMath.Pow2(a.Y - b.Y) + FastMath.Pow2(a.Z - b.Z))); }
/// <summary> /// {@inheritDoc} </summary> protected internal override double DoIntegrate() { // compute first estimate with a single step double oldt = Stage(1); int n = 2; while (true) { // improve integral with a larger number of steps //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double t = stage(n); double t = Stage(n); // estimate error //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double delta = org.apache.commons.math3.util.FastMath.abs(t - oldt); double delta = FastMath.Abs(t - oldt); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double limit = org.apache.commons.math3.util.FastMath.max(getAbsoluteAccuracy(), getRelativeAccuracy() * (org.apache.commons.math3.util.FastMath.abs(oldt) + org.apache.commons.math3.util.FastMath.abs(t)) * 0.5); double limit = FastMath.Max(GetAbsoluteAccuracy(), GetRelativeAccuracy() * (FastMath.Abs(oldt) + FastMath.Abs(t)) * 0.5); // check convergence if ((GetIterations() + 1 >= GetMinimalIterationCount()) && (delta <= limit)) { return(t); } // prepare next iteration double ratio = FastMath.Min(4, FastMath.Pow(delta / limit, 0.5 / abscissas.Length)); n = FastMath.Max((int)(ratio * n), n + 1); oldt = t; IncrementCount(); } }
public Boolean MaxSpeed() { return(FastMath.Abs(velocidadGeneral - maximaVelocidad) < 20); }
public void fire(int opposite, Device dsDevice) { rigidBody.WorldTransform = Matrix.Translation(opposite * shooter.meshAxisRadius.X * 0.8f, 0.265f, -shooter.meshAxisRadius.Z - shooter.currentSpeed * 0.01f - 0.47f) * Matrix.RotationY(shooter.yawPitchRoll.Y) * Matrix.Translation(shooter.Mesh.Transform.Origin.ToBsVector); rigidBody.ApplyCentralImpulse(new Vector3(shooter.frontVector.X, 0, shooter.frontVector.Z) * (25 + (FastMath.Sqrt(FastMath.Abs(shooter.currentSpeed)) / 2))); sound = new Tgc3dSound(Game.Default.MediaDirectory + Game.Default.FXDirectory + "machinegun.wav", shooter.Mesh.Transform.Origin, dsDevice); sound.MinDistance = 50f; sound.play(false); }
/// <summary> /// Compara que dos floats sean iguales, o casi /// </summary> public static bool equalsFloat(float f1, float f2) { return(FastMath.Abs(f1 - f2) <= EPSILON); }
/// <summary> /// [Ganrod] Nidel: Check if between two values are near with tolerance. /// </summary> /// <param name="valueToHave"></param> /// <param name="compareToCompare"></param> /// <param name="tolerance"></param> /// <returns></returns> public static bool IsNearValue(int valueToHave, int compareToCompare, ushort tolerance) { return(FastMath.Abs(valueToHave - compareToCompare) <= FastMath.Abs(tolerance)); }
private void CreateSpark() { ParticleNode node = new ParticleNode(me.SceneMgr, IdMgr.GetNewId(me.SceneMgr.GetCurrentPlayer().GetId())); // TODO spawn in a whole volume bool left = me.SceneMgr.GetRandomGenerator().Next(2) == 0 ? false : true; if (left) { Vector position = (meNode.Center - (meNode.Direction.Rotate(Math.PI / 4) * (asteroid.Radius))); position += meNode.Direction * (asteroid.Radius * 1.5); node.Position = position; node.Direction = meNode.Direction.Rotate(FastMath.DegToRad(-10)); } else { Vector position = (meNode.Center - (meNode.Direction.Rotate(-Math.PI / 4) * (asteroid.Radius))); position += meNode.Direction * (asteroid.Radius * 1.5); node.Position = position; node.Direction = meNode.Direction.Rotate(FastMath.DegToRad(10)); } float minSize = (float)FastMath.LinearInterpolate(0.2, 0.5, me.SceneMgr.GetRandomGenerator().NextDouble()); float maxSize = minSize * 1.2f; ParticleEmmitor smokeEmmitor = ParticleEmmitorFactory.CreateBasicFire(me.SceneMgr, Color.FromArgb(80, 0, 0, 0)); smokeEmmitor.Amount = 20; smokeEmmitor.MinLife = 0.3f; smokeEmmitor.MaxLife = 0.4f; smokeEmmitor.MinSize = minSize * 1.3f; smokeEmmitor.MaxSize = maxSize * 1.3f; smokeEmmitor.SpawnRadius = 4f; smokeEmmitor.Infinite = true; ParticleEmmitor fireEmmitor = ParticleEmmitorFactory.CreateBasicFire(me.SceneMgr, Color.FromArgb(150, 255, 100, 0)); fireEmmitor.Amount = 20; fireEmmitor.MinLife = 0.1f; fireEmmitor.MaxLife = 0.2f; fireEmmitor.MinSize = minSize * 1.1f; fireEmmitor.MaxSize = maxSize * 1.1f; fireEmmitor.Infinite = true; ParticleEmmitor fireEmmitor2 = ParticleEmmitorFactory.CreateBasicFire(me.SceneMgr, Color.FromArgb(200, 255, 200, 0)); fireEmmitor2.Amount = 20; fireEmmitor2.MinLife = 0.1f; fireEmmitor2.MaxLife = 0.1f; fireEmmitor2.MinSize = minSize; fireEmmitor2.MaxSize = maxSize; fireEmmitor2.Infinite = true; EmmitorGroup grp = new EmmitorGroup(); grp.Add(smokeEmmitor); grp.Add(fireEmmitor); grp.Add(fireEmmitor2); node.AddEmmitorGroup(grp, new Vector(), false); NewtonianMovementControl nmc = new NewtonianMovementControl(); nmc.Speed = (asteroid.GetControlOfType <IMovementControl>().RealSpeed / tpf) * 0.75f; node.AddControl(nmc); node.AddControl(new LimitedLifeControl((float)FastMath.LinearInterpolate(0.5, 2, me.SceneMgr.GetRandomGenerator().NextDouble()))); me.SceneMgr.DelayedAttachToScene(node); }
public float AnguloEntreVectores(TGCVector3 v1, TGCVector3 v2) { var angle = FastMath.Acos(TGCVector3.Dot(TGCVector3.Normalize(v1), TGCVector3.Normalize(v2))); return(angle); }
public double Log(double x) { return(FastMath.Log2(x + 1)); }
private void CheckInputs(float ElapsedTime, ref bool estaEnNave_) { int w = Input.keyDown(Key.W) ? 1 : 0; int s = Input.keyDown(Key.S) ? 1 : 0; int d = Input.keyDown(Key.D) ? 1 : 0; int a = Input.keyDown(Key.A) ? 1 : 0; int space = Input.keyDown(Key.Space) ? 1 : 0; int ctrl = Input.keyDown(Key.LeftControl) ? 1 : 0; bool o = Input.keyDown(Key.O); bool i = Input.keyDown(Key.I); // nuestra "implementacion" del key pressed (porque nos da false todo el tiempo el de TGC) if (o) { o = false; presionoO = true; } else { if (presionoO) { o = true; presionoO = false; } } if (i) { i = false; presionoI = true; } else { if (presionoI) { i = true; presionoI = false; } } float fmov = w - s; //foward movement float hmov = a - d; //horizontal movement float vmov = space - ctrl; //vertical movement //Check for in-ship movement var LookDir = Camara.LookDir(); var LeftDir = Camara.LeftDir(); if (estaEnNave) { LookDir.Y = 0; LeftDir.Y = 0; vmov = 0; } //Move player TGCVector3 movement = LookDir * fmov * speed + Camara.LeftDir() * hmov * speed + TGCVector3.Up * vmov * vspeed; movement *= ElapsedTime; movement.Y = mesh.Position.Y + movement.Y < MIN_Y_POS ? 0 : movement.Y; if (IsOnTopOfWater()) { movement.Y = FastMath.Min(movement.Y, 0); } Move(movement, ElapsedTime); if (i) { if (!Hud.IsCurrentStatus(Hud.Status.MainMenu) && !Hud.IsCurrentStatus(Hud.Status.GameOver)) { if (!Hud.IsCurrentStatus(Hud.Status.Inventory) && !Hud.IsCurrentStatus(Hud.Status.Crafting)) { if (!estaEnNave) { Hud.ChangeStatus(Hud.Status.Inventory); } else { Hud.ChangeStatus(Hud.Status.Crafting); } } else { Hud.ChangeStatus(Hud.Status.Gameplay); } } } if (o) { estaEnNave_ = !estaEnNave_; walking.stop(); if (estaEnNave_) { // guardar la posicion en la que estaba para que cuando vuelva, ponerlo en esa posicion anterior // posiciono dentro de nave posicionMar = mesh.Position; mesh.Position = posicionInteriorNave; } else { mesh.Position = posicionMar; } Hud.ChangeStatus(Hud.Status.Gameplay); } //Dev bool p = Input.keyDown(Key.P); // usar nuestra implementacion del key pressed if (p) { p = false; presionoP = true; } else { if (presionoP) { p = true; presionoP = false; } } if (p) { godmode = !godmode; GodMode(godmode); } }
public double ILog(double y) { return(FastMath.Pow(2, y) - 1); }
public void Init(TgcD3dInput input) { var d3dDevice = D3DDevice.Instance.Device; drawer2D = new Drawer2D(); #region configurarSprites play.Bitmap = new CustomBitmap(GameModel.mediaDir + "\\sprites\\menuCopy.png", D3DDevice.Instance.Device); var textureSize = play.Bitmap.Size; play.Position = new TGCVector2(FastMath.Max((D3DDevice.Instance.Width - textureSize.Width) * 0.5f, 0), FastMath.Max((D3DDevice.Instance.Height - textureSize.Height) * 0.5f, 0));// 200, 100); seleccion1.Bitmap = new CustomBitmap(GameModel.mediaDir + "\\sprites\\seleccion1.png", D3DDevice.Instance.Device); textureSize = seleccion1.Bitmap.Size; seleccion1.Position = play.Position; seleccion2.Bitmap = new CustomBitmap(GameModel.mediaDir + "\\sprites\\seleccion2.png", D3DDevice.Instance.Device); textureSize = seleccion2.Bitmap.Size; seleccion2.Position = play.Position; seleccion3.Bitmap = new CustomBitmap(GameModel.mediaDir + "\\sprites\\seleccion3.png", D3DDevice.Instance.Device); textureSize = seleccion3.Bitmap.Size; seleccion3.Position = play.Position; #endregion }
public override void Update() { PreUpdate(); //Actualizar valores al sprite interno. sprite.Position = new Vector2(0f, 0f); sprite.Scaling = new Vector2(0.5f, 0.5f); sprite.Rotation = 0f; //Internamente realiza Matrix.Transformation2D(scalingCenter, 0, scaling, rotationCenter, rotation, position); /*El método Transformation2D calcula la matriz de transformación afín por medio de la fórmula siguiente, evaluando la concatenación de la matriz de izquierda a derecha. * M salida = (M ce )-1 * (M re )-1 * M s* M re* M ce * (M cr )-1 * M r* M cr* M t * donde: * M salida = matriz de transformación de salida (el valor devuelto) * M ce = matriz de centro de escala (scalingCenter) * M re = matriz de rotación de escala(scalingRotation) * M e = matriz de escala(scaling) * M cr = matriz de centro de rotación(rotationCenter) * M r = matriz de rotación(rotation) * M t = matriz de traslación(translation) */ //Sacar toda transformación. matrixIdentity = Matrix.Identity; //Traslación al centro de la pantalla. traslation = Matrix.Translation(centerScreen.X, centerScreen.Y, 0f); //Un escalado, siempre olvidar la coordenada Z. scaling = Matrix.Scaling(sprite.Scaling.X, sprite.Scaling.Y, 1f); //Las rotaciones en 2D serán siempre rotaciones con eje Z. rotation = Matrix.RotationZ(FastMath.ToRad(45)); //Rotación animada (dependiente de frames) rotationAnimateFrameDepend = rotationAnimateFrameDepend * Matrix.RotationZ(FastMath.ToRad(25)); //Una rotación animada cada 1 segundo. if (acumlatedTime > 1f) { acumlatedTime = 0; rotationAnimateOneSec = rotationAnimateOneSec * Matrix.RotationZ(FastMath.ToRad(25)); //roto 25 grados por segundo } acumlatedTime += ElapsedTime; //rotación animada por render (Sin acoplar), //Si ElapsedTime es muy chico (como suele pasar con buenas computadoras y poco procesamiento) //Al multiplicarlo por nuestra velocidad angular, se transformaran en "pequeñas rotaciones". rotationAnimate = rotationAnimate * Matrix.RotationZ(FastMath.ToRad(25) * ElapsedTime); }
/// <summary> /// Moves the entity to the specified location in the time given. /// </summary> /// <param name="destination"></param> /// <param name="time"></param> public void PhysicsMove(Vector3 destination, float time, Color debugColor, bool checkGroundedness, bool Xmove, bool Ymove, Entity[] neighbouringEntities) { if (time == Time.PhysicsDeltaTime) { //Get the colliders bool Intersected = false, Grounded = false; BoundingBox newCollider = _coll.Offset(destination); Vector3Int MinBounds = Vector3Int.Floor(newCollider.Min); Vector3Int MaxBounds = Vector3Int.Ceiling(newCollider.Max); float axisPoint = 0; float axis = 0; //TEMP VAR for (int x = MinBounds.X; x <= MaxBounds.X; x++) { for (int y = MinBounds.Y; y <= MaxBounds.Y; y++) { for (int z = MinBounds.Z; z <= MaxBounds.Z; z++) { //Intersection test if (Xmove) { Intersected = Intersected || TestIntersectionX(new Vector3Int(x, y, z), newCollider, out axis); axisPoint = FastMath.ClosestToZero(axis, axisPoint); } else { if (Ymove) { if (checkGroundedness) { Grounded = Grounded || TestIntersectionY(new Vector3Int(x, y, z), newCollider, out axis); } Intersected = Intersected || TestIntersectionY(new Vector3Int(x, y, z), newCollider, out axis); axisPoint = FastMath.ClosestToZero(axis, axisPoint); } else { Intersected = Intersected || TestIntersectionZ(new Vector3Int(x, y, z), newCollider, out axis); axisPoint = FastMath.ClosestToZero(axis, axisPoint); } } //Exit the loop if we collided, these are all extra iterations if (Intersected) { break; } } //Exit the loop if we collided, these are all extra iterations if (Intersected) { break; } } //Exit the loop if we collided, these are all extra iterations if (Intersected) { break; } } //TODO: Entity intersections if (GameSettings.Debug.RenderPhysicsTestLocations) { //Entity Collider RenderUtils.DebugRenderBox(newCollider, debugColor, GameSettings.BlockOutlineWidth); } //GameClient.LOGGER.debug(-1, "======================================="); //Check for intersecting bounding boxes if (EnablePhysics) { if (Intersected == false) { //GameClient.LOGGER.debug(-1, "intersected: " + Intersected); //No intersection. Move the entity position = destination; } else { if (!IsGrounded) { //Intersection. Add axis point to the corresponding axis //Convert axisPoint to a Vector3 if (Xmove) { position.X += axisPoint; } else { if (Ymove) { position.Y += axisPoint; } else { position.Z += axisPoint; } } } } } else if (!EnablePhysics) { //Move the entity position = destination; } if (checkGroundedness && Ymove) { //Check for y IsGrounded = Grounded; } } }
public override void Render() { PreRender(); //Obtener boolean para saber si hay que mostrar Bounding Box var showBB = (bool)Modifiers.getValue("showBoundingBox"); //obtener velocidades de Modifiers var velocidadCaminar = (float)Modifiers.getValue("VelocidadCaminar"); var velocidadRotacion = (float)Modifiers.getValue("VelocidadRotacion"); //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var d3dInput = TgcD3dInput.Instance; var moving = false; var rotating = false; float jump = 0; //Adelante if (d3dInput.keyDown(Key.W)) { moveForward = -velocidadCaminar; moving = true; } //Atras if (d3dInput.keyDown(Key.S)) { moveForward = velocidadCaminar; moving = true; } //Derecha if (d3dInput.keyDown(Key.D)) { rotate = velocidadRotacion; rotating = true; } //Izquierda if (d3dInput.keyDown(Key.A)) { rotate = -velocidadRotacion; rotating = true; } //Jump if (d3dInput.keyDown(Key.Space)) { jump = 30; moving = true; } //Si hubo rotacion if (rotating) { //Rotar personaje y la camara, hay que multiplicarlo por el tiempo transcurrido para no atarse a la velocidad el hardware var rotAngle = Geometry.DegreeToRadian(rotate * ElapsedTime); personaje.rotateY(rotAngle); camaraInterna.rotateY(rotAngle); } //Si hubo desplazamiento if (moving) { //Activar animacion de caminando personaje.playAnimation("Caminando", true); } //Si no se esta moviendo, activar animacion de Parado else { personaje.playAnimation("Parado", true); } //Vector de movimiento var movementVector = Vector3.Empty; if (moving) { //Aplicar movimiento, desplazarse en base a la rotacion actual del personaje movementVector = new Vector3(FastMath.Sin(personaje.Rotation.Y) * moveForward, jump, FastMath.Cos(personaje.Rotation.Y) * moveForward); } //Actualizar valores de gravedad collisionManager.GravityEnabled = (bool)Modifiers["HabilitarGravedad"]; collisionManager.GravityForce = (Vector3)Modifiers["Gravedad"]; collisionManager.SlideFactor = (float)Modifiers["SlideFactor"]; //Mover personaje con detección de colisiones, sliding y gravedad var realMovement = collisionManager.moveCharacter(characterSphere, movementVector, objetosColisionables); personaje.move(realMovement); //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; //Actualizar valores de la linea de movimiento directionArrow.PStart = characterSphere.Center; directionArrow.PEnd = characterSphere.Center + Vector3.Multiply(movementVector, 50); directionArrow.updateValues(); //Cargar desplazamiento realizar en UserVar UserVars.setValue("Movement", TgcParserUtils.printVector3(realMovement)); //Ver cual de las mallas se interponen en la visión de la cámara en 3ra persona. objectsBehind.Clear(); objectsInFront.Clear(); foreach (var mesh in escenario.Meshes) { Vector3 q; if (TgcCollisionUtils.intersectSegmentAABB(Camara.Position, camaraInterna.Target, mesh.BoundingBox, out q)) { objectsBehind.Add(mesh); } else { objectsInFront.Add(mesh); } } //Render mallas que no se interponen foreach (var mesh in objectsInFront) { mesh.render(); if (showBB) { mesh.BoundingBox.render(); } } //Para las mallas que se interponen a la cámara, solo renderizar su BoundingBox foreach (var mesh in objectsBehind) { mesh.BoundingBox.render(); } //Render personaje personaje.animateAndRender(ElapsedTime); if (showBB) { characterSphere.render(); } //Render linea directionArrow.render(); //Render SkyBox skyBox.render(); PostRender(); }
/// <summary> /// Vuelve a crear la esfera si hubo cambio en el nivel de detalle, color o coordenadas de textura o si ForceUpdate /// esta en true. /// </summary> public virtual void updateValues() { if (!mustUpdate && !ForceUpdate) { return; } if (indexBuffer != null && !indexBuffer.Disposed) { indexBuffer.Dispose(); } if (vertexBuffer != null && !vertexBuffer.Disposed) { vertexBuffer.Dispose(); } //Obtengo las posiciones de los vertices e indices de la esfera List <TGCVector3> positions; createSphereSubdividingAPolyhedron(out positions, out indices); /////// vertices = new List <Vertex.PositionColoredTexturedNormal>(); var iverticesU1 = new List <int>(); var polos = new int[2]; var p = 0; var c = Color.ToArgb(); var twoPi = FastMath.TWO_PI; //Creo la lista de vertices for (var i = 0; i < positions.Count; i++) { var pos = positions[i]; var u = 0.5f + FastMath.Atan2(pos.Z, pos.X) / twoPi; var v = 0.5f - 2 * FastMath.Asin(pos.Y) / twoPi; vertices.Add(new Vertex.PositionColoredTexturedNormal(pos, c, UVTiling.X * u + UVOffset.X, UVTiling.Y * v + UVOffset.Y, pos)); if (u == 1 || esPolo(vertices[i])) { iverticesU1.Add(i); if (u != 1) { try { polos[p++] = i; } catch (Exception e) { //Arreglar esto... y despues quitar el try catch :( System.Console.WriteLine(e.Message); } } } } //Corrijo los triangulos que tienen mal las coordenadas debido a vertices compartidos fixTexcoords(vertices, indices, iverticesU1, polos); verticesCount = vertices.Count; triangleCount = indices.Count / 3; vertexBuffer = new VertexBuffer(typeof(Vertex.PositionColoredTexturedNormal), verticesCount, D3DDevice.Instance.Device, Usage.Dynamic | Usage.WriteOnly, Vertex.PositionColoredTexturedNormal.Format, Pool.Default); vertexBuffer.SetData(vertices.ToArray(), 0, LockFlags.None); indexBuffer = new IndexBuffer(typeof(int), indices.Count, D3DDevice.Instance.Device, Usage.Dynamic | Usage.WriteOnly, Pool.Default); indexBuffer.SetData(indices.ToArray(), 0, LockFlags.None); mustUpdate = false; }
public override void render(float elapsedTime) { Device d3dDevice = GuiController.Instance.D3dDevice; //Si hacen clic con el mouse, ver si hay colision con el suelo if (GuiController.Instance.D3dInput.buttonPressed(TgcViewer.Utils.Input.TgcD3dInput.MouseButtons.BUTTON_LEFT)) { //Actualizar Ray de colisión en base a posición del mouse pickingRay.updateRay(); //Detectar colisión Ray-AABB if (TgcCollisionUtils.intersectRayAABB(pickingRay.Ray, suelo.BoundingBox, out newPosition)) { //Fijar nueva posición destino applyMovement = true; collisionPointMesh.Position = newPosition; directionArrow.PEnd = new Vector3(newPosition.X, 30f, newPosition.Z); //Rotar modelo en base a la nueva dirección a la que apunta Vector3 direction = Vector3.Normalize(newPosition - mesh.Position); float angle = FastMath.Acos(Vector3.Dot(originalMeshRot, direction)); Vector3 axisRotation = Vector3.Cross(originalMeshRot, direction); meshRotationMatrix = Matrix.RotationAxis(axisRotation, angle); } } float speed = (float)GuiController.Instance.Modifiers["speed"]; //Interporlar movimiento, si hay que mover if (applyMovement) { //Ver si queda algo de distancia para mover Vector3 posDiff = newPosition - mesh.Position; float posDiffLength = posDiff.LengthSq(); if (posDiffLength > float.Epsilon) { //Movemos el mesh interpolando por la velocidad float currentVelocity = speed * elapsedTime; posDiff.Normalize(); posDiff.Multiply(currentVelocity); //Ajustar cuando llegamos al final del recorrido Vector3 newPos = mesh.Position + posDiff; if (posDiff.LengthSq() > posDiffLength) { newPos = newPosition; } //Actualizar flecha de movimiento directionArrow.PStart = new Vector3(mesh.Position.X, 30f, mesh.Position.Z); directionArrow.updateValues(); //Actualizar posicion del mesh mesh.Position = newPos; //Como desactivamos la transformacion automatica, tenemos que armar nosotros la matriz de transformacion mesh.Transform = meshRotationMatrix * Matrix.Translation(mesh.Position); //Actualizar camara GuiController.Instance.ThirdPersonCamera.Target = mesh.Position; } //Se acabo el movimiento else { applyMovement = false; } } //Mostrar caja con lugar en el que se hizo click, solo si hay movimiento if (applyMovement) { collisionPointMesh.render(); directionArrow.render(); } suelo.render(); mesh.render(); }