A level won't move in any way, I just need to to keep the player in between the walls, on the floor and under the roofs (even walking up slopes) and able to stand on cubes.

I'm not sure how difficult this can be, but I'd really like to learn. Any advise or links where I can start learning would be greatly appreciated. Thanks! ]]>

Code :

Vec3 fwd(GetView().mat[0][2], GetView().mat[1][2], GetView().mat[2][2]);
fwd.Normalize();

I then calculate a new postion using this fwd vector, current Position, speed, and dt:

Code :

// Move Forward
m_pos += (fwd * speed * dt);

This works fine if I change fwd.y/z to negative and if I'm moving down the +Z, but if I turn the camera around 180deg, the camera dir is inverted. In fact, if I leave the fwd vector the way it is, instead of moving forward, I end up moving back, everything is inverted. Which is why I make fwd.y/z negative.

Is there a way I can calculate the new position of my camera correctly regardless if the cam is looking down the positive or negative Z? I don't think changing fwd.y/z to negative is a solution, at some point the camera is going to turn around.

Just in case you want to see how I calculate the rotation:

Code :

Quat pitch(Vec3(1,0,0), Trig::DegToRad(mouseY));
Quat yaw(Vec3(0,1,0), Trig::DegToRad(mouseX));
Quat newRot = pitch * m_transform.GetRotationQ() * yaw;
m_transform.SetRotq(newRot);
m_transform.GetRotq()->Normalize();

Right now what I do is:

Code :

hitpoint.x = targetWorldspace.x + (-delta.x / distance);
hitpoint.y = targetWorldspace.y; // Nothing special
hitpoint.z = targetWorldspace.z + (-delta.z / distance);

... this happens after intersection test passed.

This barely works, the hit point definitely ends up on the right side of the cube, and somewhat close to the correct face. If I don't give the hitpoint some offset, the hitpoint would be in the middle of the target box obviously. I'm very sure I'm doing it wrong. This is what I'm using to test intersection:

Code :

bool Collision::OBBIntersection(
Vec3 origin,
Vec3 dir,
Vec3 aabbMin,
Vec3 aabbMax,
GameObject &target,
float &distance,
Vec3 &hitpoint){
float tMin = 0.0f;
float tMax = 100000.0f;
Mat4 model = target.GetTransform().GetModel();
Vec3 targetWorldspace;
targetWorldspace.x = model.mat[0][3];
targetWorldspace.y = model.mat[1][3];
targetWorldspace.z = model.mat[2][3];
Vec3 delta = (targetWorldspace - origin);
{
Vec3 xAxis(model.mat[0][0], model.mat[1][0], model.mat[2][0]);
float e = Trig::Dot(xAxis, delta);
float f = Trig::Dot(dir, xAxis);
if (fabs(f) > 0.001f) {
float t1 = (e + aabbMin.x)/f;
float t2 = (e + aabbMax.x)/f;
if (t1 > t2) {
float w = t1;
t1 = t2;
t2 = w;
}
if (t2 < tMax) {
tMax = t2;
}
if (t1 > tMin) {
tMin = t1;
}
if (tMax < tMin) {
return false;
}
}
else {
if (-e + aabbMin.x > 0.0f || -e + aabbMax.x < 0.0f) {
return false;
}
}
}
{
Vec3 yAxis(model.mat[0][1], model.mat[1][1], model.mat[2][1]);
float e = Trig::Dot(yAxis, delta);
float f = Trig::Dot(dir, yAxis);
if (fabs(f) > 0.001f) {
float t1 = (e + aabbMin.y)/f;
float t2 = (e + aabbMax.y)/f;
if (t1 > t2) {
float w = t1;
t1 = t2;
t2 = w;
}
if (t2 < tMax) {
tMax = t2;
}
if (t1 > tMin) {
tMin = t1;
}
if (tMax < tMin) {
return false;
}
}
else {
if (-e + aabbMin.y > 0.0f || -e + aabbMax.y < 0.0f) {
return false;
}
}
}
{
Vec3 zAxis(model.mat[0][2], model.mat[1][2], model.mat[2][2]);
float e = Trig::Dot(zAxis, delta);
float f = Trig::Dot(dir, zAxis);
if (fabs(f) > 0.001f) {
float t1 = (e + aabbMin.z)/f;
float t2 = (e + aabbMax.z)/f;
if (t1 > t2) {
float w = t1;
t1 = t2;
t2 = w;
}
if (t2 < tMax) {
tMax = t2;
}
if (t1 > tMin) {
tMin = t1;
}
if (tMax < tMin) {
return false;
}
}
else {
if (-e + aabbMin.z > 0.0f || -e + aabbMax.z < 0.0f) {
return false;
}
}
}
distance = tMin;
hitpoint.x = targetWorldspace.x + (-delta.x / distance);
hitpoint.y = targetWorldspace.y;
hitpoint.z = targetWorldspace.z + (-delta.z / distance);
return true;
}