Okay, I'm not sure if I understand it correct then.
Wouldn't normalizing the vector mean it gets a length of 1.0 instead of the wanted 0.7 in this example?
Okay, I'm not sure if I understand it correct then.
Wouldn't normalizing the vector mean it gets a length of 1.0 instead of the wanted 0.7 in this example?
Just be careful you don't use the same limited vector for player movement as you do for things like gravity or getting flung by a catapult or whatever, as they should be normalized under a different set of constraints.
Ie Don't do this:
playerVec += walkMovementVec
playerVec += gravityVec
playerVec= normalize(playerVec) * playerWalkSpeed
Since you have different velocities in each direction it might be even better to scale after normalization, i.e.
if(_dinput.KeyDown(DIK_W)) movement.z += 1;
if(_dinput.KeyDown(DIK_S)) movement.z -= 1;
if(_dinput.KeyDown(DIK_A)) movement.x += 1;
if(_dinput.KeyDown(DIK_D)) movement.x -= 1;
if(_dinput.KeyDown(DIK_PRIOR)) movement.y += 1;
if(_dinput.KeyDown(DIK_NEXT)) movement.y -= 1;
movement = normalized(movement); // returns 0 if original length is 0, otherwise a unit vector is returned
movement.x *= _player.GetStrafeSpeed();
movement.y *= _player.GetWalkSpeed();
movement.z *= _player.GetWalkSpeed();
I've put the changes through, seems to work fine:
Crealysm_math::VECTOR3 movement = Crealysm_math::VECTOR3(0.0f, 0.0f, 0.0f);
if(_dinput.KeyDown(DIK_W)) movement.z += 1.0f;
if(_dinput.KeyDown(DIK_S)) movement.z -= 1.0f;
if(_dinput.KeyDown(DIK_A)) movement.x -= 1.0f;
if(_dinput.KeyDown(DIK_D)) movement.x += 1.0f;
if(_dinput.KeyDown(DIK_PRIOR)) movement.y += 1.0f;
if(_dinput.KeyDown(DIK_NEXT)) movement.y -= 1.0f;
movement.normalize();
movement.x *= _player.GetStrafeSpeed() * _timer.GetDelta();
movement.y *= _player.GetWalkSpeed() * _timer.GetDelta();
movement.z *= _player.GetWalkSpeed() * _timer.GetDelta();
_player.SetPosition(_d3dcam.Move(movement));
Maybe a bit of topic, but can someone help me with the following.
I've made a inline normalize function for my vector struct, this works:
VECTOR3 normalize()
{
float mag = sqrt(x*x + y*y + z*z);
VECTOR3 normalized;
normalized.x = x / mag;
normalized.y = y / mag;
normalized.z = z / mag;
return normalized;
}
But when I try this, it doesn't:
VECTOR3 normalize()
{
float mag = sqrt(x*x + y*y + z*z);
x = x / mag;
y = y / mag;
z = z / mag;
return *this;
}
What am I doing wrong?
I've put the changes through, seems to work fine:
Maybe a bit of topic, but can someone help me with the following.Crealysm_math::VECTOR3 movement = Crealysm_math::VECTOR3(0.0f, 0.0f, 0.0f); if(_dinput.KeyDown(DIK_W)) movement.z += 1.0f; if(_dinput.KeyDown(DIK_S)) movement.z -= 1.0f; if(_dinput.KeyDown(DIK_A)) movement.x -= 1.0f; if(_dinput.KeyDown(DIK_D)) movement.x += 1.0f; if(_dinput.KeyDown(DIK_PRIOR)) movement.y += 1.0f; if(_dinput.KeyDown(DIK_NEXT)) movement.y -= 1.0f; movement.normalize(); movement.x *= _player.GetStrafeSpeed() * _timer.GetDelta(); movement.y *= _player.GetWalkSpeed() * _timer.GetDelta(); movement.z *= _player.GetWalkSpeed() * _timer.GetDelta(); _player.SetPosition(_d3dcam.Move(movement));
I've made a inline normalize function for my vector struct, this works:But when I try this, it doesn't:VECTOR3 normalize() { float mag = sqrt(x*x + y*y + z*z); VECTOR3 normalized; normalized.x = x / mag; normalized.y = y / mag; normalized.z = z / mag; return normalized; }
What am I doing wrong?VECTOR3 normalize() { float mag = sqrt(x*x + y*y + z*z); x = x / mag; y = y / mag; z = z / mag; return *this; }
if (speed > limit)
Essentially, this limits movement to anywhere inside the unit sphere, not just the edge of it. It protects from division by zero and amplified jitter when normalizing vectors that are extremely close to zero.
Thanks.
- I understand what you mean with the division by 0, strange thing is that it isn't crashing when I don't move, even when I initially start up the demo/ application
Action: I could check if mag != 0 and only if so, proceed. Is that the way to go?
- OK, so my second normalize function of my vector struct is the right way to go. I'll use that and see what it's going wrong, probably because of the division by zero :)
- I read back your earlier reply/ post and I'm chewing on it (again)
I'll let you know when it's finished and I understand it :)
Think I've got it, results below.
To make sure I understand correct, I think this is what I'm doing:
1. creating a zero vector
2. get keyboard input to determine the base movement
3. based on the magnitude of the vector, 'limit' the movement (over all axes now) to my max walking speed * delta
4. update the position of the camera and player
A few thoughts:
- DeltaT is now multiplied when 'limiting', I could also do that in the end when updating the position (difference?)
- If I wanted to distinguish walking/ strafing/ 'flying' speed I could copy this line three times, using a different 'walkspeed':
movement = movement * ((_player.GetWalkSpeed() * _timer.GetDelta()) / speed);
- "Movement = movement *" can also be "movement *="
I don't think distinguishing walking and strafe speed is necessary anymore, since I introduced it as a hack to prevent walking + strafing to be to quick )
I also remade my vector functions, I'll split it to a separate header with the prototypes and move the implementations to a new cpp file
(it's growing too large, I'll also have to add more operations, !=, == etc.).
_player.Running(_dinput.KeyDown(DIK_LSHIFT));
Crealysm_math::VECTOR3 movement = Crealysm_math::VECTOR3(0.0f, 0.0f, 0.0f);
if(_dinput.KeyDown(DIK_W)) movement.z = 1.0f;
if(_dinput.KeyDown(DIK_S)) movement.z = -1.0f;
if(_dinput.KeyDown(DIK_A)) movement.x = -1.0f;
if(_dinput.KeyDown(DIK_D)) movement.x = 1.0f;
if(_dinput.KeyDown(DIK_PRIOR)) movement.y = 1.0f;
if(_dinput.KeyDown(DIK_NEXT)) movement.y = -1.0f;
float speed = movement.magnitude();
if(speed > _player.GetWalkSpeed())
movement = movement * ((_player.GetWalkSpeed() * _timer.GetDelta()) / speed);
_player.SetPosition(_d3dcam.Move(movement));
// a few of the vector functions
// RETURN MAGNITUDE OF VECTOR
float magnitude()
{
return sqrt(x*x + y*y + z*z);
}
// NORMALIZE THE VECTOR IF MAGNITUDE != 0
VECTOR3 normalize()
{
float mag = sqrt(x*x + y*y + z*z);
if(mag != 0.0f)
{
x = x / mag;
y = y / mag;
z = z / mag;
}
return *this;
}
// MULTIPLY A VECTOR WITH A SCALAR
VECTOR3 operator* (const float pScalar)
{
VECTOR3 newVector = *this;
newVector.x *= pScalar;
newVector.y *= pScalar;
newVector.z *= pScalar;
return newVector;
}