public void Render(Personaje personaje, SuvirvalCraft contexto) { //Hacer que la camara siga al personaje en su nueva posicion. Sumamos 100 en el posición de Y porque queremos que la cámara este un poco más alta. camaraTgc.Target = personaje.mesh.Position + new Vector3(0, 100, 0); //Actualizamos la rotacion si es que hubo camaraTgc.RotationY = personaje.mesh.Rotation.Y; //Porque el personaje esta rotado 180 grados respecto de la camara. camaraTgc.rotateY(Geometry.DegreeToRadian(180f)); //Actualizar volumen del Frustum con nuevos valores de camara frustum.updateVolume(d3dDevice.Transform.View, d3dDevice.Transform.Projection); personaje.RenderizarTerceraPersona(contexto); }
public override void Update() { PreUpdate(); var velocidadCaminar = 400f; var velocidadRotacion = 120f; //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var moving = false; var rotating = false; //Adelante if (Input.keyDown(Key.W)) { moveForward = -velocidadCaminar; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = velocidadCaminar; 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 = Geometry.DegreeToRadian(rotate * ElapsedTime); personaje.Rotation += new TGCVector3(0, rotAngle, 0); camaraInterna.rotateY(rotAngle); } //Si hubo desplazamiento if (moving) { //Activar animacion de caminando personaje.playAnimation("Caminando", true); //Aplicar movimiento hacia adelante o atras segun la orientacion actual del Mesh var lastPos = personaje.Position; //La velocidad de movimiento tiene que multiplicarse por el elapsedTime para hacerse independiente de la velocida de CPU //Ver Unidad 2: Ciclo acoplado vs ciclo desacoplado var moveF = moveForward * ElapsedTime; var z = (float)Math.Cos(personaje.Rotation.Y) * moveF; var x = (float)Math.Sin(personaje.Rotation.Y) * moveF; personaje.Position += new TGCVector3(x, 0, z); //Detectar colisiones var collide = false; foreach (var obstaculo in obstaculos) { var result = TgcCollisionUtils.classifyBoxBox(personaje.BoundingBox, obstaculo.BoundingBox); if (result == TgcCollisionUtils.BoxBoxResult.Adentro || result == TgcCollisionUtils.BoxBoxResult.Atravesando) { collide = true; break; } } //Si hubo colision, restaurar la posicion anterior if (collide) { personaje.Position = lastPos; } personaje.Transform = TGCMatrix.Scaling(personaje.Scale) * TGCMatrix.RotationYawPitchRoll(personaje.Rotation.Y, personaje.Rotation.X, personaje.Rotation.Z) * TGCMatrix.Translation(personaje.Position); //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; } //Si no se esta moviendo, activar animacion de Parado else { personaje.playAnimation("Parado", true); } //Ajustar la posicion de la camara segun la colision con los objetos del escenario ajustarPosicionDeCamara(); PostUpdate(); }
public override void Render() { PreRender(); //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var moving = false; var rotating = false; //Adelante if (Input.keyDown(Key.W)) { moveForward = -VELODICAD_CAMINAR; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = VELODICAD_CAMINAR; moving = true; } //Derecha if (Input.keyDown(Key.D)) { rotate = VELOCIDAD_ROTACION; rotating = true; } //Izquierda if (Input.keyDown(Key.A)) { rotate = -VELOCIDAD_ROTACION; 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 = Geometry.DegreeToRadian(rotate * ElapsedTime); personaje.RotateY(rotAngle); camaraInterna.rotateY(rotAngle); } //Si hubo desplazamiento if (moving) { //Aplicar movimiento hacia adelante o atras segun la orientacion actual del Mesh var lastPos = personaje.Position; var moveF = moveForward * ElapsedTime; var z = (float)Math.Cos(personaje.Rotation.Y) * moveF; var x = (float)Math.Sin(personaje.Rotation.Y) * moveF; personaje.Position += new TGCVector3(x, 0, z); //Detectar colisiones var collide = false; foreach (var obstaculo in obstaculos) { var result = TgcCollisionUtils.classifyBoxBox(personaje.BoundingBox, obstaculo.BoundingBox); if (result == TgcCollisionUtils.BoxBoxResult.Adentro || result == TgcCollisionUtils.BoxBoxResult.Atravesando) { collide = true; break; } } //Si hubo colision, restaurar la posicion anterior if (collide) { personaje.Position = lastPos; } } //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; //Render piso piso.Render(); //Render obstaculos foreach (var obstaculo in obstaculos) { obstaculo.Render(); } //Render personaje personaje.Transform = TGCMatrix.Scaling(personaje.Scale) * TGCMatrix.RotationYawPitchRoll(personaje.Rotation.Y, personaje.Rotation.X, personaje.Rotation.Z) * TGCMatrix.Translation(personaje.Position); personaje.Render(); PostRender(); }
public override void Update() { PreUpdate(); //obtener velocidades de Modifiers var velocidadCaminar = (float)Modifiers.getValue("VelocidadCaminar"); var velocidadRotacion = (float)Modifiers.getValue("VelocidadRotacion"); var velocidadSalto = (float)Modifiers.getValue("VelocidadSalto"); var tiempoSalto = (float)Modifiers.getValue("TiempoSalto"); //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var moving = false; var rotating = false; float jump = 0; //Adelante if (Input.keyDown(Key.W)) { moveForward = -velocidadCaminar; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = velocidadCaminar; moving = true; } //Derecha if (Input.keyDown(Key.D)) { rotate = velocidadRotacion; rotating = true; } //Izquierda if (Input.keyDown(Key.A)) { rotate = -velocidadRotacion; rotating = true; } //Jump if (!jumping && Input.keyPressed(Key.Space)) { if (collisionManager.Collision) { jumping = true; jumpingElapsedTime = 0f; jump = 0; } } //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); } //Actualizar salto if (jumping) { jumpingElapsedTime += ElapsedTime; if (jumpingElapsedTime > tiempoSalto) { jumping = false; } else { jump = velocidadSalto; } } //Vector de movimiento var movementVector = Vector3.Empty; if (moving || jumping) { //Aplicar movimiento, desplazarse en base a la rotacion actual del personaje //jump *= elapsedTime; 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"] /** elapsedTime*/; collisionManager.SlideFactor = (float)Modifiers["SlideFactor"]; collisionManager.OnGroundMinDotValue = (float)Modifiers["Pendiente"]; //Si esta saltando, desactivar gravedad if (jumping) { collisionManager.GravityEnabled = false; } //Mover personaje con detección de colisiones, sliding y gravedad if ((bool)Modifiers["Collisions"]) { var realMovement = collisionManager.moveCharacter(characterSphere, movementVector, objetosColisionables); personaje.move(realMovement); //Cargar desplazamiento realizar en UserVar UserVars.setValue("Movement", TgcParserUtils.printVector3(realMovement)); UserVars.setValue("ySign", realMovement.Y); } else { personaje.move(movementVector); } //Si estaba saltando y hubo colision de una superficie que mira hacia abajo, desactivar salto if (jumping && collisionManager.Collision) { jumping = false; } //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(); //Actualizar valores de normal de colision if (collisionManager.Collision) { collisionNormalArrow.PStart = collisionManager.LastCollisionPoint; collisionNormalArrow.PEnd = collisionManager.LastCollisionPoint + Vector3.Multiply(collisionManager.LastCollisionNormal, 80); collisionNormalArrow.updateValues(); collisionPoint.Position = collisionManager.LastCollisionPoint; collisionPoint.render(); } }
public override void Update() { PreUpdate(); //obtener velocidades de Modifiers var velocidadCaminar = velocidadCaminarModifier.Value; var velocidadRotacion = velocidadRotacionModifier.Value; //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var moving = false; var rotating = false; float jump = 0; //Adelante if (Input.keyDown(Key.W)) { moveForward = -velocidadCaminar; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = velocidadCaminar; moving = true; } //Derecha if (Input.keyDown(Key.D)) { rotate = velocidadRotacion; rotating = true; } //Izquierda if (Input.keyDown(Key.A)) { rotate = -velocidadRotacion; rotating = true; } //Jump if (Input.keyUp(Key.Space) && jumping < 30) { jumping = 30; } if (Input.keyUp(Key.Space) || jumping > 0) { jumping -= 30 * ElapsedTime; jump = jumping; 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.Rotation += new TGCVector3(0, rotAngle, 0); 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 = TGCVector3.Empty; if (moving) { //Aplicar movimiento, desplazarse en base a la rotacion actual del personaje movementVector = new TGCVector3(FastMath.Sin(personaje.Rotation.Y) * moveForward, jump, FastMath.Cos(personaje.Rotation.Y) * moveForward); } //Actualizar valores de gravedad collisionManager.GravityEnabled = habilitarGravedadModifier.Value; collisionManager.GravityForce = gravedadModifier.Value; collisionManager.SlideFactor = slideFactorModifier.Value; //Mover personaje con detección de colisiones, sliding y gravedad var realMovement = collisionManager.moveCharacter(characterSphere, movementVector, objetosColisionables); personaje.Position += realMovement; personaje.Transform = TGCMatrix.Scaling(personaje.Scale) * TGCMatrix.RotationYawPitchRoll(personaje.Rotation.Y, personaje.Rotation.X, personaje.Rotation.Z) * TGCMatrix.Translation(personaje.Position); //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 + TGCVector3.Multiply(movementVector, 50); directionArrow.updateValues(); //Cargar desplazamiento realizar en UserVar UserVars.setValue("Movement", TGCVector3.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) { TGCVector3 q; if (TgcCollisionUtils.intersectSegmentAABB(Camara.Position, camaraInterna.Target, mesh.BoundingBox, out q)) { objectsBehind.Add(mesh); } else { objectsInFront.Add(mesh); } } PostUpdate(); }
public override void Update() { PreUpdate(); //obtener velocidades de Modifiers var velocidadCaminar = velocidadCaminarModifier.Value; var velocidadRotacion = velocidadRotacionModifier.Value; //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var moving = false; var rotating = false; //Adelante if (Input.keyDown(Key.W)) { moveForward = -velocidadCaminar; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = velocidadCaminar; 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 = Geometry.DegreeToRadian(rotate * ElapsedTime); personaje.RotateY(rotAngle); camaraInterna.rotateY(rotAngle); } //Si hubo desplazamiento if (moving) { //Activar animacion de caminando personaje.playAnimation("Caminando", true); //Aplicar movimiento hacia adelante o atras segun la orientacion actual del Mesh var lastPos = personaje.Position; //La velocidad de movimiento tiene que multiplicarse por el elapsedTime para hacerse independiente de la velocida de CPU //Ver Unidad 2: Ciclo acoplado vs ciclo desacoplado //NO SE RECOMIENDA UTILIZAR! moveOrientedY mueve el personaje segun la direccion actual, realiza operaciones de seno y coseno. personaje.MoveOrientedY(moveForward * ElapsedTime); //Detectar colisiones var collide = false; //Guardamos los objetos colicionados para luego resolver la respuesta. (para este ejemplo simple es solo 1 caja) TGCBox collider = null; foreach (var obstaculo in obstaculos) { if (TgcCollisionUtils.testAABBAABB(personaje.BoundingBox, obstaculo.BoundingBox)) { collide = true; collider = obstaculo; break; } } //Si hubo colision, restaurar la posicion anterior, CUIDADO!!!!! //Hay que tener cuidado con este tipo de respuesta a colision, puede darse el caso que el objeto este parcialmente dentro en este y en el frame anterior. //para solucionar el problema que tiene hacer este tipo de respuesta a colisiones y que los elementos no queden pegados hay varios algoritmos y hacks. //almacenar la posicion anterior no es lo mejor para responder a una colision. //Una primera aproximacion para evitar que haya inconsistencia es realizar sliding if (collide) { //si no esta activo el sliding es la solucion anterior de este ejemplo. if (!activateSlidingModifier.Value) { personaje.Position = lastPos; //Por como esta el framework actualmente esto actualiza el BoundingBox. text = ""; } else { //La idea del slinding es simplificar el problema, sabemos que estamos moviendo bounding box alineadas a los ejes. //Significa que si estoy colisionando con alguna de las caras de un AABB los planos siempre son los ejes coordenados. //Entones creamos un rayo de movimiento, esto dado por la posicion anterior y la posicion actual. var movementRay = lastPos - personaje.Position; //Luego debemos clasificar sobre que plano estamos chocando y la direccion de movimiento //Para todos los casos podemos deducir que la normal del plano cancela el movimiento en dicho plano. //Esto quiere decir que podemos cancelar el movimiento en el plano y movernos en el otros. var t = ""; var rs = TGCVector3.Empty; if (((personaje.BoundingBox.PMax.X > collider.BoundingBox.PMax.X && movementRay.X > 0) || (personaje.BoundingBox.PMin.X < collider.BoundingBox.PMin.X && movementRay.X < 0)) && ((personaje.BoundingBox.PMax.Z > collider.BoundingBox.PMax.Z && movementRay.Z > 0) || (personaje.BoundingBox.PMin.Z < collider.BoundingBox.PMin.Z && movementRay.Z < 0))) { //Este primero es un caso particularse dan las dos condiciones simultaneamente entonces para saber de que lado moverse hay que hacer algunos calculos mas. //por el momento solo se esta verificando que la posicion actual este dentro de un bounding para moverlo en ese plano. t += "Coso conjunto!\n" + "PMin X: " + personaje.BoundingBox.PMin.X + " - " + collider.BoundingBox.PMin.X + "\n" + "PMax X: " + personaje.BoundingBox.PMax.X + " - " + collider.BoundingBox.PMax.X + "\n" + "PMin Z: " + personaje.BoundingBox.PMin.Z + " - " + collider.BoundingBox.PMin.Z + "\n" + "PMax Z: " + personaje.BoundingBox.PMax.Z + " - " + collider.BoundingBox.PMax.Z + "\n" + "Last X: " + (lastPos.X - rs.X) + " - Z: " + (lastPos.Z - rs.Z) + "\n" + "Actual X: " + (personaje.Position.X) + " - Z: " + (personaje.Position.Z) + "\n" + "move X: " + (movementRay.X) + " - Z: " + (movementRay.Z); if (personaje.Position.X > collider.BoundingBox.PMin.X && personaje.Position.X < collider.BoundingBox.PMax.X) { //El personaje esta contenido en el bounding X t += "\n Sliding Z Dentro de X"; rs = new TGCVector3(movementRay.X, movementRay.Y, 0); } if (personaje.Position.Z > collider.BoundingBox.PMin.Z && personaje.Position.Z < collider.BoundingBox.PMax.Z) { //El personaje esta contenido en el bounding Z t += "\n Sliding X Dentro de Z"; rs = new TGCVector3(0, movementRay.Y, movementRay.Z); } //Seria ideal sacar el punto mas proximo al bounding que colisiona y chequear con eso, en ves que con la posicion. } else { if ((personaje.BoundingBox.PMax.X > collider.BoundingBox.PMax.X && movementRay.X > 0) || (personaje.BoundingBox.PMin.X < collider.BoundingBox.PMin.X && movementRay.X < 0)) { t += "Sliding X"; rs = new TGCVector3(0, movementRay.Y, movementRay.Z); } if ((personaje.BoundingBox.PMax.Z > collider.BoundingBox.PMax.Z && movementRay.Z > 0) || (personaje.BoundingBox.PMin.Z < collider.BoundingBox.PMin.Z && movementRay.Z < 0)) { t += "Sliding Z"; rs = new TGCVector3(movementRay.X, movementRay.Y, 0); } } text = t; personaje.Position = lastPos - rs; //Este ejemplo solo se mueve en X y Z con lo cual realizar el test en el plano Y no tiene sentido. } } } //Si no se esta moviendo, activar animacion de Parado else { personaje.playAnimation("Parado", true); } //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; PostUpdate(); }
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"); var velocidadSalto = (float)Modifiers.getValue("VelocidadSalto"); var tiempoSalto = (float)Modifiers.getValue("TiempoSalto"); //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 (!jumping && d3dInput.keyPressed(Key.Space)) { //Se puede saltar solo si hubo colision antes if (collisionManager.Result.collisionFound) { jumping = true; jumpingElapsedTime = 0f; jump = 0; } } //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); } //Saltando if (jumping) { //Activar animacion de saltando personaje.playAnimation("Jump", true); } //Si hubo desplazamiento else if (moving) { //Activar animacion de caminando personaje.playAnimation("Walk", true); } //Si no se esta moviendo ni saltando, activar animacion de Parado else { personaje.playAnimation("StandBy", true); } //Actualizar salto if (jumping) { //El salto dura un tiempo hasta llegar a su fin jumpingElapsedTime += ElapsedTime; if (jumpingElapsedTime > tiempoSalto) { jumping = false; } else { jump = velocidadSalto * (tiempoSalto - jumpingElapsedTime); } } //Vector de movimiento var movementVector = Vector3.Empty; if (moving || jumping) { //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"] /** elapsedTime*/; collisionManager.SlideFactor = (float)Modifiers["SlideFactor"]; collisionManager.OnGroundMinDotValue = (float)Modifiers["Pendiente"]; //Si esta saltando, desactivar gravedad if (jumping) { collisionManager.GravityEnabled = false; } //Mover personaje con detección de colisiones, sliding y gravedad if ((bool)Modifiers["Collisions"]) { //Aca se aplica toda la lógica de detección de colisiones del CollisionManager. Intenta mover el Elipsoide //del personaje a la posición deseada. Retorna la verdadera posicion (realMovement) a la que se pudo mover var realMovement = collisionManager.moveCharacter(characterElipsoid, movementVector, objetosColisionables); personaje.move(realMovement); //Cargar desplazamiento realizar en UserVar UserVars.setValue("Movement", TgcParserUtils.printVector3(realMovement)); } else { personaje.move(movementVector); } /* * //Si estaba saltando y hubo colision de una superficie que mira hacia abajo, desactivar salto * if (jumping && collisionManager.Result.collisionNormal.Y < 0) * { * jumping = false; * } */ //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; //Actualizar valores de la linea de movimiento directionArrow.PStart = characterElipsoid.Center; directionArrow.PEnd = characterElipsoid.Center + Vector3.Multiply(movementVector, 50); directionArrow.updateValues(); //Actualizar valores de normal de colision if (collisionManager.Result.collisionFound) { collisionNormalArrow.PStart = collisionManager.Result.collisionPoint; collisionNormalArrow.PEnd = collisionManager.Result.collisionPoint + Vector3.Multiply(collisionManager.Result.collisionNormal, 80); ; collisionNormalArrow.updateValues(); collisionNormalArrow.render(); collisionPoint.Position = collisionManager.Result.collisionPoint; collisionPoint.render(); } //Render de mallas foreach (var mesh in escenario.Meshes) { mesh.render(); } //Render personaje personaje.animateAndRender(ElapsedTime); if (showBB) { characterElipsoid.render(); } //Render linea directionArrow.render(); //Render SkyBox skyBox.render(); PostRender(); }
public void actualizar(Vector3 pos) { if (input.keyPressed(Key.P)) { if (!apuntando) { apuntando = true; apuntado = new Vector3(0, 50, -50); camera.OffsetForward = DISTANCIA_APUNTANDO; camera.OffsetHeight = ALTURA_APUNTANDO; } else { apuntando = false; apuntado = new Vector3(0, 0, 0); camera.setCamera(pos, ALTURA, DISTANCIA); } } if (apuntando) { camera.RotationY = ship.anguloRotacion; } //Solo rotar si se esta aprentando el boton izq del mouse if (input.buttonDown(TgcD3dInput.MouseButtons.BUTTON_LEFT)) { if (!apuntando) { camera.rotateY(-input.XposRelative * ROTATION_SPEED); } } if (input.keyDown(Key.LeftShift)) { camera.OffsetHeight += 5; camera.OffsetForward += 5; } if (input.keyDown(Key.LeftControl)) { camera.OffsetHeight -= 5; camera.OffsetForward -= 5; } if (input.WheelPos != wheelPos) { zoom = input.WheelPos - wheelPos < 0 ? 20f : -20F; camera.OffsetHeight += zoom; camera.OffsetForward += zoom; } Vector3 aux = ship.delante; aux.Y = 0; camera.Target = pos + new Vector3(0, apuntado.Y, 0) + (apuntado.Z * aux); camera.updateCamera(); }
public override void Render() { PreRender(); //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var d3dInput = TgcD3dInput.Instance; var moving = false; var rotating = false; //Adelante if (d3dInput.keyDown(Key.W)) { moveForward = -VELODICAD_CAMINAR; moving = true; } //Atras if (d3dInput.keyDown(Key.S)) { moveForward = VELODICAD_CAMINAR; moving = true; } //Derecha if (d3dInput.keyDown(Key.D)) { rotate = VELOCIDAD_ROTACION; rotating = true; } //Izquierda if (d3dInput.keyDown(Key.A)) { rotate = -VELOCIDAD_ROTACION; 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 = Geometry.DegreeToRadian(rotate * ElapsedTime); personaje.rotateY(rotAngle); camaraInterna.rotateY(rotAngle); } //Si hubo desplazamiento if (moving) { //Aplicar movimiento hacia adelante o atras segun la orientacion actual del Mesh var lastPos = personaje.Position; personaje.moveOrientedY(moveForward * ElapsedTime); //Detectar colisiones var collide = false; foreach (var obstaculo in obstaculos) { var result = TgcCollisionUtils.classifyBoxBox(personaje.BoundingBox, obstaculo.BoundingBox); if (result == TgcCollisionUtils.BoxBoxResult.Adentro || result == TgcCollisionUtils.BoxBoxResult.Atravesando) { collide = true; break; } } //Si hubo colision, restaurar la posicion anterior if (collide) { personaje.Position = lastPos; } } //Hacer que la camara siga al personaje en su nueva posicion Camara = new TgcThirdPersonCamera(); camaraInterna.Target = personaje.Position; //Render piso piso.render(); //Render obstaculos foreach (var obstaculo in obstaculos) { obstaculo.render(); } //Render personaje personaje.render(); PostRender(); }
public override void Update() { PreUpdate(); //obtener velocidades de Modifiers var velocidadCaminar = velocidadCaminarModifier.Value; var velocidadRotacion = velocidadRotacionModifier.Value; var velocidadSalto = velocidadSaltoModifier.Value; var tiempoSalto = tiempoSaltoModifier.Value; //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var moving = false; var rotating = false; float jump = 0; //Adelante if (Input.keyDown(Key.W)) { moveForward = -velocidadCaminar; moving = true; } //Atras if (Input.keyDown(Key.S)) { moveForward = velocidadCaminar; moving = true; } //Derecha if (Input.keyDown(Key.D)) { rotate = velocidadRotacion; rotating = true; } //Izquierda if (Input.keyDown(Key.A)) { rotate = -velocidadRotacion; rotating = true; } //Jump if (!jumping && Input.keyPressed(Key.Space)) { //Se puede saltar solo si hubo colision antes if (collisionManager.Result.collisionFound) { jumping = true; jumpingElapsedTime = 0f; jump = 0; } } //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); } //Saltando if (jumping) { //Activar animacion de saltando personaje.playAnimation("Jump", true); } //Si hubo desplazamiento else if (moving) { //Activar animacion de caminando personaje.playAnimation("Walk", true); } //Si no se esta moviendo ni saltando, activar animacion de Parado else { personaje.playAnimation("StandBy", true); } //Actualizar salto if (jumping) { //El salto dura un tiempo hasta llegar a su fin jumpingElapsedTime += ElapsedTime; if (jumpingElapsedTime > tiempoSalto) { jumping = false; } else { jump = velocidadSalto * (tiempoSalto - jumpingElapsedTime); } } //Vector de movimiento var movementVector = TGCVector3.Empty; if (moving || jumping) { //Aplicar movimiento, desplazarse en base a la rotacion actual del personaje movementVector = new TGCVector3(FastMath.Sin(personaje.Rotation.Y) * moveForward, jump, FastMath.Cos(personaje.Rotation.Y) * moveForward); } //Actualizar valores de gravedad collisionManager.GravityEnabled = habilitarGravedadModifier.Value; collisionManager.GravityForce = gravedadModifier.Value /** elapsedTime*/; collisionManager.SlideFactor = slideFactorModifier.Value; collisionManager.OnGroundMinDotValue = pendienteModifier.Value; //Si esta saltando, desactivar gravedad if (jumping) { collisionManager.GravityEnabled = false; } //Mover personaje con detección de colisiones, sliding y gravedad if (collisionsModifier.Value) { //Aca se aplica toda la lógica de detección de colisiones del CollisionManager. Intenta mover el Elipsoide //del personaje a la posición deseada. Retorna la verdadera posicion (realMovement) a la que se pudo mover var realMovement = collisionManager.moveCharacter(characterElipsoid, movementVector, objetosColisionables); personaje.Move(realMovement); //Cargar desplazamiento realizar en UserVar UserVars.setValue("Movement", TGCVector3.PrintVector3(realMovement)); } else { personaje.Move(movementVector); } /* * //Si estaba saltando y hubo colision de una superficie que mira hacia abajo, desactivar salto * if (jumping && collisionManager.Result.collisionNormal.Y < 0) * { * jumping = false; * } */ //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; //Actualizar valores de la linea de movimiento directionArrow.PStart = characterElipsoid.Center; directionArrow.PEnd = characterElipsoid.Center + TGCVector3.Multiply(movementVector, 50); directionArrow.updateValues(); //Actualizar valores de normal de colision if (collisionManager.Result.collisionFound) { collisionNormalArrow.PStart = collisionManager.Result.collisionPoint; collisionNormalArrow.PEnd = collisionManager.Result.collisionPoint + TGCVector3.Multiply(collisionManager.Result.collisionNormal, 80); collisionNormalArrow.updateValues(); collisionPoint.Position = collisionManager.Result.collisionPoint; collisionPoint.updateValues(); } PostUpdate(); }
public override void Render() { PreRender(); var velocidadCaminar = 400f; var velocidadRotacion = 120f; //Calcular proxima posicion de personaje segun Input var moveForward = 0f; float rotate = 0; var d3dInput = TgcD3dInput.Instance; var moving = false; var rotating = false; //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; } //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); //Aplicar movimiento hacia adelante o atras segun la orientacion actual del Mesh var lastPos = personaje.Position; //La velocidad de movimiento tiene que multiplicarse por el elapsedTime para hacerse independiente de la velocida de CPU //Ver Unidad 2: Ciclo acoplado vs ciclo desacoplado personaje.moveOrientedY(moveForward * ElapsedTime); //Detectar colisiones var collide = false; foreach (var obstaculo in obstaculos) { var result = TgcCollisionUtils.classifyBoxBox(personaje.BoundingBox, obstaculo.BoundingBox); if (result == TgcCollisionUtils.BoxBoxResult.Adentro || result == TgcCollisionUtils.BoxBoxResult.Atravesando) { collide = true; break; } } //Si hubo colision, restaurar la posicion anterior if (collide) { personaje.Position = lastPos; } //Hacer que la camara siga al personaje en su nueva posicion camaraInterna.Target = personaje.Position; } //Si no se esta moviendo, activar animacion de Parado else { personaje.playAnimation("Parado", true); } //Ajustar la posicion de la camara segun la colision con los objetos del escenario ajustarPosicionDeCamara(obstaculos); //Render piso piso.render(); //Render de obstaculos foreach (var obstaculo in obstaculos) { obstaculo.render(); } //Render personaje personaje.animateAndRender(ElapsedTime); PostRender(); }
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(); }