Alright, so whatever the reason the previous way I approached that was incorrect, so I looked for the mathematical definition of how to find the barycentric coordinates, which involved the vector lengths and the cross product. While the square rooting is slow, it works, I will be tweaking the way this function works in the future and trying to clean and optimize it to my best ability, however this is how I went about fixing this issue.
UtilityFunctions.h
#include "DataTypes.h"
namespace Util{
float map(float in, float minA, float maxA, float minB, float maxB);
float dot(float ax, float ay, float az, float bx, float by, float bz);
float dot(Point3D a, Point3D b);
float length(Point3D p);
Point3D sub(Point3D a, Point3D b);
Point3D toBarycentric(Point3D a, Point3D b, Point3D c, Point3D p);
Point3D cross(Point3D a, Point3D b);
};
UtilityFunctions.cpp
#include <vector>
#include <stdio.h>
#include <math.h>
#include "UtilityFunctions.h"
float Util::map(float in, float minA, float maxA, float minB, float maxB){
float ratio = 0.0f;
if (abs(maxA - minA)>0){
ratio = (maxB - minB) / (maxA - minA);
}
return (in - minA)*ratio + minB;
}
float Util::dot(float ax, float ay, float az, float bx, float by, float bz){ return (ax*bx) + (ay*by) + (az*bz); }
float Util::dot(Point3D a, Point3D b){ return (a.X*b.X) + (a.Y*b.Y) + (a.Z*b.Z); }
float Util::length(Point3D p){
return ((p.X*p.X) + (p.Y*p.Y) + (p.Z*p.Z));
}
Point3D Util::cross(Point3D a, Point3D b){
return{ ((a.Y*b.Z) - (a.Z*b.Y)), ((a.X*b.Z) - (a.Z*b.X)), ((a.X*b.Y) - (a.Y*b.X)) };
}
Point3D Util::sub(Point3D a, Point3D b){
return{ a.X - b.X, a.Y - b.Y, a.Z - b.Z };
}
Point3D Util::toBarycentric(Point3D a, Point3D b, Point3D c, Point3D p){
Point3D v0 = sub(c, a);
Point3D v1 = sub(b, a);
Point3D v2 = sub(p, a);
Point3D v12 = cross(v1, v2);
Point3D v10 = cross(v1, v0);
if (dot(v12, v10) < 0){ return{ 0, 0, -1 }; }
Point3D v02 = cross(v0, v2);
Point3D v01 = cross(v0, v1);
if (dot(v02, v01) < 0){ return{ 0, 0, -1 }; }
float denom = length(v01);
return{ length(v12) / denom, length(v02) / denom, 0 };
}
PhysicsFunctions.cpp
#include "PhysicsHandler.h"
bool Physics::PolyPointCollision(Point3D a,Point3D b,Point3D c,Point3D p){
Point3D w = Util::toBarycentric(a, b, c, p);
if (w.X+w.Y<=1&&w.Z>=0){
return true;
}
return false;
}
The topmost function:
bool D3DHandler::IsCollidingWithTerrain(D3DXVECTOR3 pos){
Point3D pointPos = { pos.x, pos.y, pos.z };
for (unsigned int i = 1; i < chunk.at(0).GetWidth() - 1; i++){
for (unsigned int ii = 1; ii < chunk.at(0).GetWidth() - 1; ii++){
Point3D originVertex = chunk.at(0).GetVertex(i, ii);
if (Physics::PolyPointCollision(originVertex,chunk.at(0).GetVertex(i + 1, ii),
chunk.at(0).GetVertex(i, ii + 1),pointPos)){
return true;
}
if (Physics::PolyPointCollision(originVertex,chunk.at(0).GetVertex(i - 1, ii),
chunk.at(0).GetVertex(i, ii - 1),pointPos)){
return true;
}
}
}
return false;
}
Proof / test results: http://imgur.com/a/HH2pp