XNA 2D Cam Zoom not correct - c#

I built a camera based on the class from http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/ . I'm currently making a kinda space-shooter game (but with story and this stuff) and want to have the camera working fine first. But the Zoom doesn't work as I want. I don't really know why, but I hope you can help me ^^
The Issue is, that the sprite moves around for like 30 pixels in some direction. Propbably i didn't set the Position of the main-spaceship properly or the camera is just bugging.
The game is running in full-screen.
Game1 Method:
InputHandler.Update(gameTime, graphics.GraphicsDevice);
World.Camera.Position = new Vector2(Player.Ship.Position.X + Player.Ship.Texture.Width/2, Player.Ship.Position.Y+Player.Ship.Texture.Height/2);
World.Camera.Zoom = InputHandler.ZoomValue;
I add half the size of the texture of the main-spaceship to the cameraposition so that the middle of the texture should be in the middle. It doesn't work either without it..
How I set fullscreen (I know... It's not the way I should have done it but it doesn't work with the normal code.)
graphics.PreferredBackBufferHeight = 10000;
graphics.PreferredBackBufferWidth = 10000;
graphics.ToggleFullScreen();
graphics.PreferMultiSampling = true;
graphics.IsFullScreen = true;
graphics.ApplyChanges();
The InputHandler Class:
public static void Update(GameTime gameTime, GraphicsDevice graphics)
{
_oldKeyboardState = keyboardState;
_oldMouseState = mouseState;
keyboardState = Keyboard.GetState();
mouseState = Mouse.GetState();
MousePosition = new Vector2(mouseState.X, mouseState.Y);
MatrixMousePosition = Vector2.Transform(MousePosition, Matrix.Invert(World.Camera.GetTransformation(graphics)));
OldScrollWheelValue = ScrollWheelValue;
ScrollWheelValue = mouseState.ScrollWheelValue;
if (ScrollWheelValue > OldScrollWheelValue) ZoomValue += 0.1f;
if (ScrollWheelValue < OldScrollWheelValue) ZoomValue -= 0.1f;
ZoomValue = MathHelper.Clamp(ZoomValue, 0.5f, 1.5f);
}
And finally the camera class:
protected float _zoom; // Camera Zoom
public Matrix _transform; // Matrix Transform
public Vector2 _pos; // Camera Position
protected float _rotation; // Camera Rotation
public float Zoom
{
get { return _zoom; }
set { _zoom = value; if (_zoom < 0.1f) _zoom = 0.1f; }
}
public float Rotation
{
get { return _rotation; }
set { _rotation = value; }
}
public Vector2 Position
{
get { return _pos; }
set { _pos = value; }
}
public Camera()
{
_zoom = 1.0f;
_rotation = 0.0f;
_pos = Vector2.Zero;
}
public Matrix GetTransformation(GraphicsDevice graphicsDevice)
{
var viewport = graphicsDevice.Viewport;
_transform =
Matrix.CreateTranslation(new Vector3(-_pos.X*Zoom, -_pos.Y*Zoom, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(viewport.Width * 0.5f, viewport.Height * 0.5f, 0));
return _transform;
}

I see what you did wrong, this line:
transform = Matrix.CreateTranslation(new Vector3(-_pos.X*Zoom, -_pos.Y*Zoom, 0)) * ....
should be:
transform = Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) * ....
Because right now when you zoom you also translate the image, which is causing the moving sprites.

Related

Offscreen target indicators - Unity 2D

I'm trying to point to an object when it's off-screen. The objects are static.
public class SpawnIndicator : MonoBehaviour
{
public Camera UIcamera;
public GameObject point;
public Canvas canvas;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (point.GetComponent<Renderer>().isVisible)
{
gameObject.GetComponent<SpriteRenderer>().color = Color.clear;
}
else
{
gameObject.GetComponent<SpriteRenderer>().color = Color.white;
//POSITION
Vector3 pointPos = UIcamera.WorldToScreenPoint(point.transform.position);
pointPos.z = 0;
pointPos.x = Mathf.Clamp(pointPos.x, (Screen.width * 0.01f), (Screen.width * 0.99f));
pointPos.y = Mathf.Clamp(pointPos.y, (Screen.height * 0.01f), (Screen.height * 0.99f));
pointPos -= new Vector3((Screen.width/2), (Screen.height/2), 0);
gameObject.transform.localPosition = pointPos;
//ROTATION
gameObject.GetComponent<SpriteRenderer>().color = Color.white;
Vector3 vectorToTarget = point.transform.position - gameObject.transform.position;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
angle -= 90;
Quaternion newRotation = Quaternion.AngleAxis(angle, Vector3.forward);
gameObject.transform.rotation = newRotation;
}
}
}
This works fine when the screen size is 1920x1080 (the reference size for my canvas). However at lower sizes, the objects sit awawy from the edges, and in larger sizes they sit outside of the edges.
Figured it out.
WorldToScreenPoint was returning a value based on the reference resolution (1920x1080) so different resolutions ended up mismatched. I think that's what was going wrong, regardless, I've got the solution.
I found this method to convert a world position to canvas position.
public static Vector3 WorldToScreenSpace(Vector3 worldPos, Camera cam, RectTransform area)
{
Vector3 screenPoint = cam.WorldToScreenPoint(worldPos);
screenPoint.z = 0;
Vector2 screenPos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screenPoint, cam, out screenPos))
{
return screenPos;
}
return screenPoint;
}
I'd also changed the rest of the code a bit while trying to fix this before finding that solution (and coincidentally was using the canvas size) so here's the full script:
public class SpawnIndicator : MonoBehaviour
{
public Camera UIcamera;
public GameObject point;
public Canvas canvas;
Vector3 pointPos;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (point.GetComponent<Renderer>().isVisible)
{
gameObject.GetComponent<SpriteRenderer>().color = Color.clear;
}
else
{
gameObject.GetComponent<SpriteRenderer>().color = Color.white;
Vector3[] canvasPoints = new Vector3[4];
canvas.GetComponent<RectTransform>().GetLocalCorners(canvasPoints);
Vector3 pointPos = WorldToScreenSpace(point.transform.position, UIcamera, canvas.GetComponent<RectTransform>());
float xMin = canvasPoints[0].x * 0.98f;
float xMax = canvasPoints[2].x * 0.98f;
float yMin = canvasPoints[0].y * 0.8f;
float yMax = canvasPoints[2].y * 0.98f;
//POSITION
if (pointPos.x <= xMin) pointPos.x = xMin;
if (pointPos.x >= xMax) pointPos.x = xMax;
if (pointPos.y <= yMin) pointPos.y = yMin;
if (pointPos.y >= yMax) pointPos.y = yMax;
pointPos.z = 0f;
gameObject.transform.localPosition = pointPos;
//ROTATION
gameObject.GetComponent<SpriteRenderer>().color = Color.white;
Vector3 vectorToTarget = point.transform.position - gameObject.transform.position;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
angle -= 90;
Quaternion newRotation = Quaternion.AngleAxis(angle, Vector3.forward);
gameObject.transform.rotation = newRotation;
}
}
public static Vector3 WorldToScreenSpace(Vector3 worldPos, Camera cam, RectTransform area)
{
Vector3 screenPoint = cam.WorldToScreenPoint(worldPos);
screenPoint.z = 0;
Vector2 screenPos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screenPoint, cam, out screenPos))
{
return screenPos;
}
return screenPoint;
}
}

How to draw a sprite on a moving canvas

I generally figure this sort of thing out normally but I am stumped. I suspect theres a mathematical combination I have missed but anyway.
I have a moving background (currently goes up and down from top to bottom)
I have a moving object (currently moves left and right from the centre of the canvas programatically).
So this is the question, How can I make an object move relatively to the position on the canvas in x and y directions?
Here is my relevant codes:
//Helper method
private Vector2 CalculateDirection()
{
Vector2 calculatedDirection = new Vector2((float)Math.Cos(direction),
(float)Math.Sin(direction));
calculatedDirection.Normalize();
return calculatedDirection;
}
object on canvas
public void Update(GameTime gameTime, Vector2 center)
{
this.currentCentre = originalCentre - center;
//movement logic here
Vector2 calculatedDirection = CalculateDirection();
//deltaTime = ((float)gameTime.ElapsedGameTime.TotalMilliseconds) / 15f;
if (speed > 0f || speed < 0f)
{
///TODO: work this out!!
Velocity = calculatedDirection * speed;
float dir = (originalCentre.Y - currentCentre.Y);
position.X += Velocity.X * (1.0f - 0.9f);
position.Y = dir;// *(1.0f - 0.9f);
}
}
canvas moving methods
private void determinePitchSize()
{
int newHeight = Convert.ToInt32(pitch.Height * ratio);
this.canvas = new Rectangle(
0, posHeight,
device.PresentationParameters.BackBufferWidth,
newHeight
);
}
public void increasePosHeight()
{
posHeight++;
}
public void decreasePosHeight()
{
posHeight--;
}
private void determineDirection()
{
if (!direction)
{
if (this.canvas.Height + this.canvas.Y <= this.screenY)
direction = true;
}
else
{
if (this.canvas.Y >= 0)
direction = false;
}
}
private void useDirection()
{
this.determineDirection();
if (direction)
this.increasePosHeight();
else decreasePosHeight();
}
If you need any more info I can add it here.
Thanks
Ok so thanks to Nico, I was able to answer this.
Vector2 Velocity { get; set; }
Vector2 relative { get; set; }
public void Update(GameTime gameTime, Vector2 center)
{
this.currentCentre = center;
Vector2 calculatedDirection = CalculateDirection();
if (speed > 0f || speed < 0f)
{
Velocity = calculatedDirection * speed * 0.1f;
relative = relative - Velocity;
position = currentCentre + relative;
}
}
The velocity creates object movement to test that it ends up in a different place.
Relative starts at 0,0 (the center) and is adjusted by the velocity.
Position is then set to the centre plus the relative position. which has been set by the velocity.

wander & chase AI code not working

Put together an enemy AI system for an enemy in which it should wander around idly when the player is not within distance to the enemy and when player is within enemy distance it should initiate chase behaviour and chase after player until player has managed to exit out of the enemy's chase radius.
Currently the enemy is able to wonder freely yet when the player comes within proximity of the enemy the enemy will carry on wandering instead of chasing player.
Anyone help me fix this problem?
Code is as follows.
public enum AIState
{
Chasing,
Wander
}
private float maxSpeed;
private float maxRotation;
private float chaseDistance;
private float hysteresis;
private Texture2D texture;
private Vector2 drawingOrigin;
private Vector2 position;
public AIState aiState = AIState.Wander;
private float orientation;
private Random random = new Random();
private Rectangle viewportbounds;
public Rectangle boundingBox;
public Vector2 playerPosition;
private Vector2 heading;
public Virtual_Aliens(Rectangle pos, Rectangle b)
{
position = new Vector2(300, 400);
boundingBox = new Rectangle(pos.X, pos.Y, pos.Width, pos.Height);
viewportbounds = new Rectangle(b.X, b.Y, b.Width, b.Height);
orientation = 0.0f;
heading = new Vector2(0, 0);
maxSpeed = 2.0f;
maxRotation = 0.20f;
hysteresis = 15.0f;
chaseDistance = 250.0f;
Thread.Sleep(200);
random = new Random();
}
public void LoadContent(ContentManager Content)
{
texture = Content.Load<Texture2D>("images/asteroid");
}
private Vector2 OrientationAsVector(float orien)
{
Vector2 orienAsVect;
orienAsVect.X = (float)Math.Cos(orien);
orienAsVect.Y = (float)Math.Sin(orien);
return orienAsVect;
}
Vector2 wanderPosition = new Vector2();
public void Wander()
{
// the max +/- the agent will wander from its current position
float wanderLimits = 0.5f;
// this defines what proportion of its maxRotation speed the agent will turn
float turnFactor = 0.15f;
// randomly define a new position
wanderPosition.X += MathHelper.Lerp(-wanderLimits, wanderLimits, (float)random.NextDouble());
wanderPosition.Y += MathHelper.Lerp(-wanderLimits, wanderLimits, (float)random.NextDouble());
if (wanderPosition != Vector2.Zero)
{
wanderPosition.Normalize();
}
orientation = TurnToFace(wanderPosition, orientation, turnFactor * maxRotation);
heading = OrientationAsVector(orientation);
position += heading * 0.5f * maxSpeed;
WrapForViewport();
}
private void WrapForViewport()
{
if (position.X < 0)
{
position.X = viewportbounds.Width;
}
else if (position.X > viewportbounds.Width)
{
position.X = 0;
}
if (position.Y < 0)
{
position.Y = viewportbounds.Height;
}
else if (position.Y > viewportbounds.Height)
{
position.Y = 0;
}
}
private float WrapAngle(float radian)
{
while (radian < -MathHelper.Pi)
{
radian += MathHelper.TwoPi;
}
while (radian > MathHelper.Pi)
{
radian -= MathHelper.TwoPi;
}
return radian;
}
private float TurnToFace(Vector2 steering, float currentOrientation, float turnSpeed)
{
float newOrientation;
float desiredOrientation;
float orientationDifference;
float x = steering.X;
float y = steering.Y;
// the desiredOrientation is given by the steering vector
desiredOrientation = (float)Math.Atan2(y, x);
// find the difference between the orientation we need to be
// and our current Orientation
orientationDifference = desiredOrientation - currentOrientation;
// now using WrapAngle to get result from -Pi to Pi
// ( -180 degrees to 180 degrees )
orientationDifference = WrapAngle(orientationDifference);
// clamp that between -turnSpeed and turnSpeed.
orientationDifference = MathHelper.Clamp(orientationDifference, -turnSpeed, turnSpeed);
// the closest we can get to our target is currentAngle + orientationDifference.
// return that, using WrapAngle again.
newOrientation = WrapAngle(currentOrientation + orientationDifference);
return newOrientation;
}
public void Update(GameTime gameTime)
{
if (aiState == AIState.Wander)
{
chaseDistance -= hysteresis / 2;
}
else if (aiState == AIState.Chasing)
{
chaseDistance += hysteresis / 2;
}
float distanceFromPlayer = Vector2.Distance(position, playerPosition);
if (distanceFromPlayer > chaseDistance)
{
aiState = AIState.Wander;
}
else
{
aiState = AIState.Chasing;
}
float currentSpeed;
if (aiState == AIState.Chasing)
{
orientation = TurnToFace(playerPosition, orientation, maxRotation);
currentSpeed = maxSpeed;
}
else if (aiState == AIState.Wander)
{
Wander();
}
}
public void Draw(SpriteBatch spriteBatch)
{
boundingBox.X = (int)position.X;
boundingBox.Y = (int)position.Y;
drawingOrigin = new Vector2(texture.Width / 2, texture.Height / 2);
spriteBatch.Draw(texture, boundingBox, null, Color.White, orientation, drawingOrigin, SpriteEffects.None, 0.0f);
}
public Vector2 PlayerPosition
{
set
{
playerPosition = value;
}
get
{
return playerPosition;
}
}
You get the distance from the player using:
float distanceFromPlayer = Vector2.Distance(position, playerPosition);
But you never actually set the variable playerPosition in your class. So effectively if the enemy is within the chase radius from the point (0,0) they will chase your player, but otherwise will they will just wander around.
I would recommend doing one of two things to solve this issue.
First off you could change the parameters of your Update method to take in the Vector2 of the players position.
A second approach (the one I would personally choose) would be to add a new field (class variable) that is of type Player and then in your Virtual_Aliens' constructor pass in an instance of the player class. That way any time you reference playerPosition you would be able to just say player.Position (or however you have your position field named).

I tried to make the camera to move the same way in first person game but its not moving why?

This is my Game1.cs code i marked the areas of the camera movement code parts:
Added the camera code in my Game1.cs i used the riemers tutorials camera code here:
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series4/Mouse_camera.php
I also tried the code in the bottom by user31911 but same results the camera pointer/cursor is dancing/shaking in the middle and not responding.
Im trying to use the Camera class to move the camera around using the mouse.
http://pastebin.com/SF3iiftq
In the constructor i have this line:
viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraFinalTarget, cameraRotatedUpVector);
If i use this line instead assign the viewMatrix variable later in my code then i dont see the terrain at all.
And the big main problem is that the mouse is not responding at all what i get is the mouse pointer dancing/shaking in the middle.
The only thing that responding is my ProcessInput method i did the keys there are working but the method ProcessInputCamera the kkeys and mouse there are not resopnding when im moving the camera the mouse cursor is shaking/dancing in the middle.
I can't figure out why it happen.
But the mouse is not moving the camera.
Pls edit your Question! There are to many unnecessary informations...
here is my camera (1st person) class
class Camera
{ // up in here normal needed vars
public Vector3 cameraPosition;
public float moveSpeed, rotateSpeed;
public bool playing = true;
public GraphicsDevice device;
public Matrix view, projection;
Matrix rotation;
float yaw = 0;
float pitch = 0;
int oldX, oldY;
public Camera(Vector3 cameraPosition, float moveSpeed, float rotateSpeed, float filedOfView, GraphicsDevice device, float PerspectiveFieldOfView)
{
this.cameraPosition = cameraPosition;
this.moveSpeed = moveSpeed;
this.rotateSpeed = rotateSpeed;
this.device = device;
view = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(PerspectiveFieldOfView), device.Viewport.AspectRatio, 0.1f, filedOfView);
ResetMouseCursor();
}
public void Update()
{
KeyboardState kState = Keyboard.GetState(); // make is able to use your keys
Vector3 v = new Vector3(0, 0, -50) * moveSpeed; // let you permanent walk
move(v); // isnt essential could be deleted if you wont that
}
if (kState.IsKeyDown(Keys.W))
{
Vector3 v = new Vector3(0, 0, -100) * moveSpeed;
move(v);
}
if (kState.IsKeyDown(Keys.S))
{
Vector3 v = new Vector3(0, 0, 50) * moveSpeed;
move(v);
}
if (kState.IsKeyDown(Keys.A))
{
Vector3 v = new Vector3(-50, 0, 0) * moveSpeed;
move(v);
projection = Matrix.
}
if (kState.IsKeyDown(Keys.D))
{
Vector3 v = new Vector3(50, 0, 0) * moveSpeed;
move(v);
}
pitch = MathHelper.Clamp(pitch, -1.5f, 1.5f);
MouseState mState = Mouse.GetState();
int dx = mState.X - oldX; /* is for turning you objekt / camera
yaw -= rotateSpeed * dx; *
*
int dy = mState.Y - oldY; *
pitch -= rotateSpeed * dy; */
ResetMouseCursor(); // this makes your mouse "dancing" in the middle
UpdateMatrices();
}
private void ResetMouseCursor() // mouse settings for the camera
{
int centerX = device.Viewport.Width / 2;
int centerY = device.Viewport.Height / 2;
Mouse.SetPosition(centerX, centerY);
oldX = centerX;
oldY = centerY;
}
private void UpdateMatrices() //standart camera things
{
rotation = Matrix.CreateRotationY(yaw) * Matrix.CreateRotationX(pitch);
Vector3 transformedReference = Vector3.Transform(new Vector3(0, 0, -1), rotation);
Vector3 lookAt = cameraPosition + transformedReference;
view = Matrix.CreateLookAt(cameraPosition, lookAt, Vector3.Up);
}
public void move(Vector3 v) // is the self programmed method to let you move
{
Matrix yRotation = Matrix.CreateRotationY(yaw);
v = Vector3.Transform(v, yRotation);
cameraPosition += v;
}
}
It's pretty standart, but good.
In most cases this class is all you need for the Camera and it's configuration.
Rewrite/Fix it, like however you need it...
Tipp: You could also consider a Arc-Ball-Cam..

Ground and model are flickering and somewhat invisable

I really don't know whats is going wrong here. The game seams to be drawing funny. The first thing I notice is that when the player moves, the camera move before the avatar does so the camera comes out of the avatars head a bit. Then I noticed that when you look at the avatar from the side you can see though his shoulder and into his cheast cavity (it does not do this in the animation player I build and also in Maya). The next thing I notice is when the player moves forward, the ground starts to flicker. Am I calling the draw method wrong or something?
here is the camera class I am using
public class Camera : Microsoft.Xna.Framework.GameComponent
{
//Cam Matrices
//viw is composed of position, direction, and up vectors
public Matrix view { get; protected set; }
public Matrix projection { get; protected set; }
//to move the camera
//used to recreate view matrix each frame
public Vector3 cameraPosition { get; protected set; }
public Vector3 cameraDirection; //not the target/ point camera is looking at a relative direction camrea is faceing
//to find target add the cameraPosition and cameraDirection togeater
public Vector3 cameraUp;
public Vector3 target;
//camera controls
float speed = 3;
MouseState prevMouseState;
// Pi/180 = 1 degree
// Max yaw/pitch variables
//this is for moving the head only not the body
float totalYaw = MathHelper.PiOver2;
public float currentYaw = 0;
float totalPitch = MathHelper.PiOver2;
public float currentPitch = 0;
public float leftTrigYaw;
public float rightTrigYaw;
//constructor
public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up)
: base(game)
{
//build camera view matrix
cameraPosition = pos;
cameraDirection = target - pos;
cameraDirection.Normalize(); //Convert to magintue 1
//make it easy to apply differt speeds to movement of camera
cameraUp = up;
CreateLookAt();
projection = Matrix.CreatePerspectiveFieldOfView
(
MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width / (float)Game.Window.ClientBounds.Height,
1, 3000);
}
private void CreateLookAt()
{
//middle variable is the target!
view = Matrix.CreateLookAt(cameraPosition, cameraPosition + cameraDirection, cameraUp);
}
public override void Initialize()
{
Mouse.SetPosition(Game.Window.ClientBounds.Width / 2,
Game.Window.ClientBounds.Height / 2);
prevMouseState = Mouse.GetState();
base.Initialize();
}
public override void Update(GameTime gameTime)
{
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
//move forward
if (currentState.ThumbSticks.Left.Y > 0 || Keyboard.GetState().IsKeyDown(Keys.W))
{
//move just on x and x axis Y is controled other places.
cameraPosition += new Vector3(cameraDirection.X, 0, cameraDirection.Z) * speed;
}
//move backward
if (currentState.ThumbSticks.Left.Y < 0 || Keyboard.GetState().IsKeyDown(Keys.S))
{
//move just on x and x axis Y is controled other places.
cameraPosition -= new Vector3(cameraDirection.X, 0, cameraDirection.Z) * speed;
}
//move left
if (currentState.ThumbSticks.Left.X < 0 || Keyboard.GetState().IsKeyDown(Keys.A))
{
//cross product of the up and direction vectors can give the side direction
cameraPosition += Vector3.Cross(cameraUp, cameraDirection) * speed;
}
//move right
if (currentState.ThumbSticks.Left.X > 0 || Keyboard.GetState().IsKeyDown(Keys.D))
{
cameraPosition -= Vector3.Cross(cameraUp, cameraDirection) * speed;
}
//mouse movements
// Yaw rotation
float yawAngle = (-MathHelper.PiOver4 / 150) *
(Mouse.GetState().X - prevMouseState.X);
float padYaw = (-MathHelper.PiOver2 / 50) *
(currentState.ThumbSticks.Right.X);
if (Math.Abs(currentYaw + yawAngle) < totalYaw)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, yawAngle));
currentYaw += yawAngle;
}
//rotate left and right
if (currentState.ThumbSticks.Right.X < 0 || currentState.ThumbSticks.Right.X > 0)
{
if (Math.Abs(currentYaw + padYaw) < totalYaw)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, padYaw));
currentYaw += padYaw;
}
}
leftTrigYaw = (MathHelper.PiOver2 / 50) *
(currentState.Triggers.Left);
if (currentState.Triggers.Left > 0.0f)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, leftTrigYaw));
}
rightTrigYaw = (-MathHelper.PiOver2 / 50) *
(currentState.Triggers.Right);
if (currentState.Triggers.Right > 0.0f)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, rightTrigYaw));
}
// Pitch rotation
float pitchAngle = (MathHelper.PiOver4 / 150) *
(Mouse.GetState().Y - prevMouseState.Y);
float padPitch = (-MathHelper.PiOver2 / 50) *
(currentState.ThumbSticks.Right.Y);
if (Math.Abs(currentPitch + pitchAngle) < totalPitch)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(
Vector3.Cross(cameraUp, cameraDirection),
pitchAngle));
currentPitch += pitchAngle;
}
if (currentState.ThumbSticks.Right.Y < 0 || currentState.ThumbSticks.Right.Y > 0)
{
if (Math.Abs(currentPitch + padPitch) < totalPitch)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(
Vector3.Cross(cameraUp, cameraDirection),
padPitch));
currentPitch += padPitch;
}
}
//reset mouse state
target = cameraPosition + cameraDirection;
prevMouseState = Mouse.GetState();
//for testing only!! get rid of this when done
if (currentState.Buttons.A == ButtonState.Pressed)
{
//fly upwar
cameraPosition += new Vector3(0, 15, 0);
}
if (currentState.Buttons.B == ButtonState.Pressed)
{
//fly upwar
cameraPosition -= new Vector3(0, 15, 0);
}
//call camera creat look at method to build new view matrix
CreateLookAt();
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
{
Game.Exit();
}
base.Update(gameTime);
}
}
}
I am also using a custom model handler to draw the ground and the avatar
public class CModel
{
public Vector3 Position { get; set; }
public Vector3 Rotation { get; set; }
public Vector3 Scale { get; set; }
public Model Model { get; private set; }
private Matrix[] modelTransforms;
private GraphicsDevice graphicsDevice;
public CModel(Model Model, Vector3 Position, Vector3 Rotation,
Vector3 Scale, GraphicsDevice graphicsDevice)
{
this.Model = Model;
modelTransforms = new Matrix[Model.Bones.Count];
Model.CopyAbsoluteBoneTransformsTo(modelTransforms);
this.Position = Position;
this.Rotation = Rotation;
this.Scale = Scale;
this.graphicsDevice = graphicsDevice;
}
public void Draw(Matrix View, Matrix Projection)
{
// Calculate the base transformation by combining
// translation, rotation, and scaling
Matrix baseWorld = Matrix.CreateScale(Scale)
* Matrix.CreateFromYawPitchRoll(
Rotation.Y, Rotation.X, Rotation.Z)
* Matrix.CreateTranslation(Position);
foreach (ModelMesh mesh in Model.Meshes)
{
Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
* baseWorld;
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
BasicEffect effect = (BasicEffect)meshPart.Effect;
effect.World = localWorld;
effect.View = View;
effect.Projection = Projection;
effect.EnableDefaultLighting();
}
mesh.Draw();
}
}
}
}
I dont know where the problem is originating from but these are the only two things that I can think of that would give the problem.
Thanks for any help with this.
Here is what is going on with the model. I am sure that the normal are right in maya because I used the simple model drawer that Microsoft has up on the tutorials but then you can somewhat see though the guys shoulder and arm. I could not get a picture of the ground flickering because it happens too fast to really screen capture it.But every time i move the camera, the ground jumps up and down a lot. and then stops when I stop moving the camera to look around. am I not calling the the camera.Update() method because its a game component and is linked up with the game1 class.
This is how I am drawing the models
it is a draw method in the custom model class
public void Draw(Matrix View, Matrix Projection)
{
// Calculate the base transformation by combining
// translation, rotation, and scaling
Matrix baseWorld = Matrix.CreateScale(Scale)
* Matrix.CreateFromYawPitchRoll(
Rotation.Y, Rotation.X, Rotation.Z)
* Matrix.CreateTranslation(Position);
foreach (ModelMesh mesh in Model.Meshes)
{
Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
* baseWorld;
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
BasicEffect effect = (BasicEffect)meshPart.Effect;
effect.World = localWorld;
effect.View = View;
effect.Projection = Projection;
effect.EnableDefaultLighting();
}
mesh.Draw();
}
}
For the artifacts on the model: The model doesn't look like it's being rendered properly. Your DrawPrimitives call probably isn't feeding the graphics card the right data (either your vertex/index buffers are filled in wrong or you have the primitive type/count wrong). Try rendering it in wireframe mode, you should be able to see the triangles that are getting distorted, producing these artifacts.
As for the ground - I will look some more through the code and see if I can think of anything.

Categories