I'm trying to make a world object that can use a camera and draw multiple models at once, each with their own position (and rotation, etc. in the future). Except it comes up with a black screen and I don't know why.
I've tried changing the way the matrices are created, adjusted the positions, and nothing.
World:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Simple3DWorld.Objects;
namespace Simple3DWorld
{
public class World
{
public Camera Camera;
public ModelObject[] Objects;
public World()
{
Camera = new Camera(new Vector3(0, 0, 1), Vector3.Zero);
Objects = new ModelObject[100];
AddObject(new Landscape(new Vector3(0, 0, -1)));
}
public void AddObject(ModelObject obj)
{
bool added = false;
for (int i = 0; i < Objects.Length && !added; i++)
{
if (Objects[i] == null)
{
Objects[i] = obj;
added = true;
}
}
}
public void Update(GameTime gt)
{
for (int i = 0; i < Objects.Length; i++)
{
if (Objects[i] != null)
{
Objects[i].Update(gt);
}
}
}
public void Draw()
{
for (int i = 0; i < Objects.Length; i++)
{
if (Objects[i] != null)
{
Objects[i].Draw(Camera);
}
}
}
}
}
Camera:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Simple3DWorld
{
public class Camera
{
public Vector3 Position;
public Vector3 LookingAt;
public float FieldOfView;
public float AspectRatio;
public Camera(Vector3 pos, Vector3 lookAt)
{
Position = pos;
LookingAt = lookAt;
FieldOfView = MathHelper.PiOver4;
AspectRatio = STDW.Width / STDW.Height;
}
}
}
ModelObject:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Simple3DWorld
{
public class ModelObject
{
public Model Model;
public Vector3 Position;
public ModelObject(Model model, Vector3 pos)
{
Model = model;
Position = pos;
}
public virtual void Update(GameTime gt)
{
}
public virtual void Draw(Camera camera)
{
foreach (ModelMesh mesh in Model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
effect.World = Matrix.CreateTranslation(Position);
effect.View = Matrix.CreateLookAt(camera.Position, camera.LookingAt, Vector3.UnitZ);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(camera.FieldOfView, camera.AspectRatio, 1f, 100f);
}
mesh.Draw();
}
}
}
}
And yes, I have made sure that all methods are being called correctly. What should be showing on screen is my landscape model.
EDIT: Solved. For some stupid, frustrating reason, MonoGame will not render your models if your camera's X and Y (not the up vector) are both 0. If anyone could somehow explain this, I would be infinitely grateful.
Your Camera's Position and LookAt vectors cannot both be equal on the two axes perpendicular to the Up vector. This results in a NaN(not a number).
This situation can also be characterized as a Gimbol Lock, since the rotations about the X(Roll) and Y(Pitch) axes are aligned, making it impossible to determine the Z(Yaw) from the information provided.
The problem occurs in the creation of the View matrix in the following line:
effect.View = Matrix.CreateLookAt(camera.Position, camera.LookingAt, Vector3.UnitZ);
Substituting the argument values:
effect.View = Matrix.CreateLookAt(new Vector3(0,0,1), new Vector3(0,0,0), new Vector3(0,0,1));
Annotated partial source for CreateLookAt at implementation(see here for pass the through call)
public static void CreateLookAt(ref Vector3 cameraPosition, ref Vector3 cameraTarget, ref Vector3 cameraUpVector, out Matrix result)
{
var vector = Vector3.Normalize(cameraPosition - cameraTarget);
Normalize((0,0,1) - (0,0,0)) -> (x,y,z)/Length
Length = (0 - 0)² + (0 - 0)² + (0 - 1)² -> 1
(0/Length,0/Length,1/Length) -> (0/1,0/1,1/1) ->(0,0,1) *OK
var vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));
Working inside out:
Cross((0,0,1),(0,0,1)) -> (y1 * z2 - z1 * y2, z1 * x2 - x1 *z2, x1 * y2 - y1 *x2) ->
(0 * 1 - 1 * 0, 1 * 0 - 0 * 1, 0 * 0 - 0 * 0) -> (0,0,0) *Mathematically OK, Geometrically undefined(does not define a plane perpendicular to the input points)
Normalize(Cross((0,0,1),(0,0,1))) -> Normalize(0,0,0)
Length = (0 - 0)² + (0 - 0)² + (0 - 0)² -> 0
(0/Length,0/Length,0/Length) -> (0/0,0/0,0/0) ->(NaN,NaN,NaN) *UH-OH
The NaN results from the division by zero with the 0 being unsigned as defined by IEEE 754.
Since any operation on a NaN results in NaN. The NaN propagates to the World and Projection matrices, resulting in a black screen.
To put it another way:
If you were standing up looking (Camera.Position=(0,0,6)), ignoring the fact your head has to tilt to see them, at your feet(Camera.LookAt =(0,0,0)), is it possible to determine the compass direction, where the Up vector equals Vector3.UnitZ, that you are facing? No. It is not possible, you could be facing any direction on the plane.
If I ask for the World coordinate one unit in front of your feet(1,0,0), I can tell which direction you are facing.
Fixed. All I had to do was move my camera off of 0,0,0. 0,1,0 1,0,0 and 1,1,0 all seemed to work, which means the camera's other two coordinates (not the one that determines whether it's up or down) can't be at the origin. Not too sure why this is a thing, but at least it's fixed now.
Related
I have 3 Spheres and a lineRenderer which is connected to the spheres. I'm using Bezier curves to get a smooth curves between the spheres.
The code is looking like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LineController : MonoBehaviour
{
private LineRenderer lineRenderer;
public Transform p0;
public Transform p1;
public Transform p2;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.sortingOrder = 1;
}
void Update()
{
DrawQuadraticBezierCurve(p0.position, p1.position, p2.position);
}
void DrawQuadraticBezierCurve(Vector3 point0, Vector3 point1, Vector3 point2)
{
lineRenderer.positionCount = 100;
float t = 0f;
Vector3 B = new Vector3(0, 0, 0);
for (int i = 0; i < lineRenderer.positionCount; i++)
{
B = (1 - t) * (1 - t) * point0 + 2 * (1 - t) * t * point1 + t * t * point2;
lineRenderer.SetPosition(i, B);
t += (1 / (float)lineRenderer.positionCount);
}
}
}
The Problem is, that the is invisible on some parts when I move the spheres.
I don't know why this is happening. I'm using Mixed Reality Toolkit. In the best case the line should be displayed as an 3D object like a long cube.
Maybe anybody is familiar with this kind of "error"?
My project is make a line between a target and a AGV.
apologize my english skill. My english is not good.
here are my code how it works.
find positions of target and AGV
get a simple linear equation by use of AGV's position x,y and target's position x,y
place dots on the simple linear equation which I just found in step 2.
when my dots meet a tag "wall" do something something... (not yet made)
so here is my problem:
my C# 'MapFile.cs' Script is installed on EmptyObject 'Map'.
When scene start, dots begin to place on the linear equation gradually AGV to target.
but i want stop placing dots when the last dot meet the 'wall' objects.
so tried to use function
void onTriggerEnter(Collider other)
but as you see, 'MapFile.cs' script is installed on EmptyObject 'Map'...
I have no idea how to my dots interaction with the walls.
here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class MapFile : Agent
{
public Transform targetPosition;
public Transform AGVposition;
public GameObject dot;
public float w, b;
public float functionTarget = 0f;
public float[] data = new float[2];
void Awake()
{
Initializing();
}
public void Initializing()
{
data[0] = AGVposition.position.x;
data[1] = AGVposition.position.y;
}
public void drawline()
{
if(data[0] < 20f && data[0] > -20f)
{
while(true)
{
data[1] = FindYValue(data[0]);
Instantiate(dot, new Vector3( data[0] , 0f , data[1] ) , Quaternion.identity);
if(targetPosition.position.x > 0 )
{
data[0] += 0.07f;
if(data[0] > 20f) break;
}
else
{
data[0] -= 0.07f;
if(data[0] < -20f)break;
}
}
}
}
void Update()
{
drawline();
}
public float FindYValue(float a)
{
float result;
float x1 = AGVposition.position.x;
float y1 = AGVposition.position.z;
float x2 = targetPosition.position.x;
float y2 = targetPosition.position.z;
result = ( (y2 - y1) / (x2 - x1) ) * (a - x1) + y1;
return result;
}
}
I started learning c# monogame a few weeks ago and i wanted to start a project.
The project I choose is a brickbreaker clone and everything goes well. But I stumbled on something that I have spent hours looking on google for without a answer.
The problem I have is with collision detection between the ball and the bricks.
Between the paddle and the ball work I have a working solution.
Which is :
// Collision between the ball and player
public void Collision(Player player, Ball ball)
{
MinX = (int)player.PlayerPosition.X - ball.Width;
MaxX = (int)player.PlayerPosition.X + player.Width + ball.Width;
MinY = 0;
MaxY = (int)player.PlayerPosition.Y - ball.Height;
Rectangle BallRectangle = new Rectangle((int)ball.BallPosition.X, (int)ball.BallPosition.Y, ball.Width, ball.Height);
Rectangle PlayerRectangle = new Rectangle((int)player.PlayerPosition.X, (int)player.PlayerPosition.Y, player.Width, player.Height);
if (BallRectangle.Intersects(PlayerRectangle))
{
ball.BallPosition.Y = MathHelper.Clamp(ball.BallPosition.Y, MinY, MaxY);
ball.BallPosition.X = MathHelper.Clamp(ball.BallPosition.X, MinX, MaxX);
ball.BallSpeed.Y *= -1;
float BallMiddlePoint = ball.BallPosition.X + (ball.Width / 2);
float PlayerMiddlePoint = player.PlayerPosition.X + (player.Width / 2);
ball.BallSpeed.X = (BallMiddlePoint - PlayerMiddlePoint) / 10 + ball.ExtraSpeedOverTime;
}
}
Now back to my problem, I use Rectangle.Intersect(Rectangle) to check for collision.
The main problem is: How do I let the ball bounce correctly on the bricks?
I hope I give enough information.
My ball class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace BrickBreakerV2
{
class Ball
{
// The texture of the ball
Texture2D BallTexture;
// The position of the ball
public Vector2 BallPosition;
// The speed of the ball
public Vector2 BallSpeed;
// The speed that gets added over time
public float ExtraSpeedOverTime;
// Time values used in incrementing the speed over time
TimeSpan IncreaseSpeed;
TimeSpan PreviousSpeedIncrease;
// The "active" state of the ball
public bool Active;
// The state of movement of the ball
public bool Moveball;
// The Width of the ball
public int Width
{
get { return BallTexture.Width; }
}
// The Height of the ball
public int Height
{
get { return BallTexture.Height; }
}
// Construct a class for Boundaries
CollisionHandler Collision = new CollisionHandler();
public void Initialize(ContentManager Content, GraphicsDevice graphicsDevice, Player player)
{
BallTexture = Content.Load<Texture2D>("Graphics\\ball.png");
BallPosition = new Vector2(player.PlayerPosition.X + (player.Width / 2) - (Width / 2),
player.PlayerPosition.Y - Height - 5);
BallSpeed = new Vector2(5.0f, -5.0f);
ExtraSpeedOverTime = 1.0f;
IncreaseSpeed = TimeSpan.FromSeconds(12f);
PreviousSpeedIncrease = TimeSpan.Zero;
Active = true;
Moveball = false;
}
public void Update(GraphicsDevice graphicsDevice, GameTime gameTime, Player player)
{
if (Moveball)
{
BallPosition += BallSpeed;
}
else
{
BallPosition = new Vector2(player.PlayerPosition.X + (player.Width / 2) - (Width / 2),
player.PlayerPosition.Y - Height - 5);
}
if (gameTime.TotalGameTime - PreviousSpeedIncrease > IncreaseSpeed)
{
ExtraSpeedOverTime += 0.01f;
BallSpeed.X *= ExtraSpeedOverTime;
BallSpeed.Y *= ExtraSpeedOverTime;
PreviousSpeedIncrease = gameTime.TotalGameTime;
}
// Makes sure that the ball doesn't go to fast
if (BallSpeed.X > 10.50f)
BallSpeed.X = 10.50f;
if (BallSpeed.Y > 10.50f)
BallSpeed.Y = 10.50f;
if (BallSpeed.X < -10.50f)
BallSpeed.X = -10.50f;
if (BallSpeed.Y < -10.50f)
BallSpeed.Y = -10.50f;
// Keep the ball in the boundaries
Collision.GetBoundaries(graphicsDevice, this);
// Detect collision between ball and player
Collision.Collision(player, this);
}
public void Update(Brick brick)
{
// Detect collision between ball and brick
Collision.Collision(this, brick);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(BallTexture, BallPosition, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 1f);
}
}
}
My Brick class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace BrickBreakerV2
{
class Brick
{
// The texture of the brick
public Texture2D BrickTexture;
// The position of the bricks
public Vector2 BrickPosition;
// The color tint of the brick
public Color ColorTint;
// The "active" state of the brick
public bool Active;
// The width of the brick
public int Width
{
get { return BrickTexture.Width; }
}
// The height of the brick
public int Height
{
get { return BrickTexture.Height; }
}
// Construct a class for collisionhandler
CollisionHandler Collision;
public void Initialize(ContentManager Content)
{
BrickTexture = Content.Load<Texture2D>("Graphics\\brick.png");
BrickPosition = new Vector2(600, 500);
Active = true;
ColorTint = Color.White;
Collision = new CollisionHandler();
}
public void Update(Ball ball)
{
Collision.Collision(ball, this);
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(BrickTexture, BrickPosition, null, ColorTint, 0f, Vector2.Zero, 1f, SpriteEffects.None, 1f);
}
}
}
And my code block that handles the collision between the ball and bricks in CollisionHandler.cs:
// Collision between ball and brick
public void Collision(Ball ball, Brick brick)
{
Rectangle BallRectangle = new Rectangle((int)ball.BallPosition.X, (int)ball.BallPosition.Y, ball.Width, ball.Height);
Rectangle BrickRectangle = new Rectangle((int)brick.BrickPosition.X, (int)brick.BrickPosition.Y, brick.Width, brick.Height);
if (BallRectangle.Intersects(BrickRectangle))
{
int XOverlap;
int YOverlap;
if (BallRectangle.Center.X < BrickRectangle.Center.X)
{
XOverlap = (BallRectangle.X + ball.Width) - BrickRectangle.X;
}
else
{
XOverlap = (BrickRectangle.X + brick.Width) - BallRectangle.X;
}
if (BallRectangle.Center.Y < BrickRectangle.Center.Y)
{
YOverlap = (BallRectangle.Y + ball.Height) - BrickRectangle.Y;
}
else
{
YOverlap = (BrickRectangle.Y + brick.Height) - BallRectangle.Y;
}
if (XOverlap == YOverlap)
{
ball.BallSpeed.X *= -1;
ball.BallSpeed.Y *= -1;
}
else if (XOverlap < YOverlap)
{
ball.BallSpeed.X *= -1;
}
else
{
ball.BallSpeed.Y *= -1;
}
brick.Active = false;
}
}
I want to help you, but I'm not going to debug your code. Fortunately basic 2D collision detection and brick breaker clones have been done many many times before.
A quick google search turned up the following tutorial. I haven't done it myself but if I where you I would start here:
http://xnagpa.net/xna4beginner.php
Good luck.
I have the player moving towards where i have clicked. But when i arrive at the position of where i clicked, the sprite just flickers back and forth. I assume its because the sprite is going past this point, going back to it, going past it again, then going back constantly creating a 'flickering'. Any ideas why?
****SOLVED********
***UPDATED CODE***
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace AsteroidAvoider
{
class Player
{
public Vector2 position, distance, mousePosition;
public float speed;
public float rotation;
public Texture2D playerImage;
public MouseState mouseState;
public Player(Texture2D playerImage, Vector2 position, float speed)
{
this.playerImage = playerImage;
this.position = position;
this.speed = speed;
}
public void Update(GameTime gameTime)
{
mouseState = Mouse.GetState();
float speedForThisFrame = speed;
if (mouseState.LeftButton == ButtonState.Pressed)
{
mousePosition.X = mouseState.X;
mousePosition.Y = mouseState.Y;
}
if ((mousePosition - position).Length() < speed)
speedForThisFrame = 0;
if ((mousePosition - position).Length() > speed)
speedForThisFrame = 2.0f;
distance = mousePosition - position;
distance.Normalize();
rotation = (float)Math.Atan2(distance.Y, distance.X);
position += distance * speedForThisFrame;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(playerImage, position, null, Color.White, rotation, new Vector2(playerImage.Width / 2, playerImage.Height / 2), 1.0f, SpriteEffects.None, 1f);
}
}
}
The normalized vector , if I remember correctly should always have a total length of 1 (Vector2.Length() returns the length of the entire vector2 by the way)
A simple solution would be making your unit reduce the speed of movement if within the range of the mouse , for example
float speedForThisFrame = speed;
if((mousePosition-position).Length() < speed) speedForThisFrame = (mousePosition-position).Length();
and use speedForThisFrame for the position offsetting.
You need a collider, a Rectangle that represents your player, so when this collider contains your mousePosition or the click coordinate (you can easily detect it using Rectangle.Contains method) you simply set player's speed as 0, avoiding the flickering.
Of course, when the clicked coordinate changes, you have to set the previous player's speed.
I'm trying to rotate a sprite to face the mouse by incrementing and decrementing the Rotation using a turning radius. It works fine up until the point where the mouse is top-left and moves to the top-right. I have it so that if the angle difference is greater than the current Rotation value, the sprite's Rotation gets incremented, otherwise it gets decremented. So when it goes from 6.5 radians to 0, it rotates counterclockwise by 350-some degrees, instead of clockwise by 15-some degrees. Me and others have been working on this all day and have no idea how to solve this. My code is below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.IO;
namespace Physics
{
public class Ship
{
public Texture2D Texture { get; set; }
public Vector2 Position { get; set; }
public double Rotation { get; set; }
MouseState prevState, currState;
Vector2 A, B;
public const double NINETY_DEGREES = 1.57079633;
double turningRadius = 2 * (Math.PI / 180);
double targetRotation, rotationDifferential;
public Ship(Texture2D texture, Vector2 position)
{
Texture = texture;
Position = position;
A = new Vector2(Position.X, Position.Y);
B = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
Rotation = 0;
}
public void Update()
{
currState = Mouse.GetState();
A.X = Position.X;
A.Y = Position.Y;
B.X = currState.X;
B.Y = currState.Y;
if (B.Y > A.Y)
if (B.X > A.X) //Bottom-right
targetRotation = Math.Atan((B.Y - A.Y) / (B.X - A.X)) + NINETY_DEGREES;
else //Bottom-left
targetRotation = (Math.Atan((A.X - B.X) / (B.Y - A.Y))) + (NINETY_DEGREES * 2);
else
if (B.X > A.X) //Top-right
targetRotation = Math.Atan((B.X - A.X) / (A.Y - B.Y));
else //Top-Left
targetRotation = Math.Atan((A.Y - B.Y) / (A.X - B.X)) + (NINETY_DEGREES * 3);
if (Rotation > targetRotation)
Rotation -= turningRadius;
else
Rotation += turningRadius;
prevState = currState;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, Position, null, Color.White, (float)Rotation, new Vector2(Texture.Width / 2, Texture.Height / 2), 0.5f,
SpriteEffects.None, 0.0f);
}
}
}
Let me make sure I understand. You have a vector (Cos(Rotation), Sin(Rotation) representing which direction your object is facing; another vector (B.X-A.X, B.Y-A.Y) representing the direction you want your object to face; and you want to know whether to rotate your object (the first vector) clockwise or counter-clockwise to face it in the
direction of the second vector?
Simple, just treat them both as 3D vectors (set Z = 0) and take their cross product.
If the resulting vector has a positive Z component, rotate counter-clockwise
If it has a positive Z component, rotate clockwise
If the Z component is 0, the two vectors are parallel, so just check if they are facing opposite directions (and rotate either way) or the same direction (nothing to do!)
This works because of the right-hand rule which defines cross-products.
This should just reverse direction to whichever is faster.
spin = targetRotation - Rotation;
if (abs(spin) > Math.PI)
spin *= -1;
if (spin > 0
Rotation += turningRadius;
else
Rotation -= turningRadius;
Edit: Changed 180 to Math.PI
Try the following (This is some code from a tank game I made, not sure if it still applies in this scenario). I trimmed it down to the essentials:
using System;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace Physics
{
public class Ship
{
public Texture2D Texture { get; set; }
public Vector2 Position { get; set; }
public double Rotation { get; set; }
private MouseState currState;
public Ship(Texture2D texture, Vector2 position)
{
Texture = texture;
Position = position;
Rotation = 0;
}
public void Update()
{
currState = Mouse.GetState();
var mouseloc = new Vector2(currState.X, currState.Y);
Vector2 direction = Position - mouseloc;
Rotation = Math.Atan2(direction.Y, direction.X) + MathHelper.PiOver2;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, Position, null, Color.White, (float) Rotation,
new Vector2(Texture.Width/2, Texture.Height/2), 0.5f,
SpriteEffects.None, 0.0f);
}
}
}
I think you just need a little more math to modify the rate of the rotation, I'll come back if I come up with a solution.
Also, this code will vary based on the default rotation of the sprite. In my example, it assumes that the sprite is facing downwards (6 o'clock). Hope this points you in the right direction!
Edit my apologies I removed my head from my posterior and actually read the question this time. So here's a nice little method that I spent ~3 hours writing up tonight.
private float AngleLerp(float nowrap, float wraps, float lerp) {
float c, d;
if (wraps < nowrap) {
c = wraps + MathHelper.TwoPi;
//c > nowrap > wraps
d = c - nowrap > nowrap - wraps
? MathHelper.Lerp(nowrap, wraps, lerp)
: MathHelper.Lerp(nowrap, c, lerp);
} else if (wraps > nowrap) {
c = wraps - MathHelper.TwoPi;
//wraps > nowrap > c
d = wraps - nowrap > nowrap - c
? MathHelper.Lerp(nowrap, c, lerp)
: MathHelper.Lerp(nowrap, wraps, lerp);
} else { return nowrap; } //Same angle already
return MathHelper.WrapAngle(d);
}
It lerps the nowrap towards the wraps value. The wraps angle can be the one that jumps from 0 to TwoPi and back so in this case the angle of the mouse. nowrap should be your objects angle.
Hope I was actually helpful this time.