worked on nav-mesh
added dijkstra support for nav mesh some minor changes to distributions minor fixes
This commit is contained in:
@@ -4,6 +4,11 @@
|
||||
#include "../geo/Point3.h"
|
||||
#include "../geo/Point2.h"
|
||||
|
||||
// fast barycentric code
|
||||
// https://stackoverflow.com/questions/25385361/point-within-a-triangle-barycentric-co-ordinates#25386102
|
||||
// https://i.stack.imgur.com/8VODS.png
|
||||
// https://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates
|
||||
|
||||
namespace NM {
|
||||
|
||||
/**
|
||||
@@ -29,12 +34,13 @@ namespace NM {
|
||||
|
||||
private: // precalculated stuff
|
||||
|
||||
Point2 v0;
|
||||
Point2 v1;
|
||||
float dot00;
|
||||
float dot01;
|
||||
float dot11;
|
||||
double invDenom;
|
||||
// Point2 v0;
|
||||
// Point2 v1;
|
||||
// float dot00;
|
||||
// float dot01;
|
||||
// float dot11;
|
||||
// double invDenom;
|
||||
|
||||
float area;
|
||||
|
||||
float minZ;
|
||||
@@ -44,13 +50,16 @@ namespace NM {
|
||||
const Point3 v12;
|
||||
const Point3 v13;
|
||||
|
||||
const double _det;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
NavMeshTriangle(const Point3 p1, const Point3 p2, const Point3 p3, const uint8_t type) :
|
||||
p1(p1), p2(p2), p3(p3), type(type),
|
||||
_neighbors(), _numNeighbors(0),
|
||||
center((p1+p2+p3)/3), v12(p2-p1), v13(p3-p1) {
|
||||
center((p1+p2+p3)/3), v12(p2-p1), v13(p3-p1),
|
||||
_det(1.0*(p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y)) {
|
||||
|
||||
precompute();
|
||||
|
||||
@@ -66,6 +75,13 @@ namespace NM {
|
||||
Point3 getP3() const {return p3;}
|
||||
|
||||
|
||||
/** get the number of known neighbors for this triangle */
|
||||
int getNumNeighbors() const {return _numNeighbors;}
|
||||
|
||||
/** get the idx-th neighbor */
|
||||
const NavMeshTriangle* getNeighbor(const int idx) const {return _neighbors[idx];}
|
||||
|
||||
|
||||
/** get the distance between the given point and the triangle using approximate tests */
|
||||
float getDistanceApx(const Point3 pt) const {
|
||||
|
||||
@@ -123,6 +139,61 @@ namespace NM {
|
||||
return p1 + (v12*u) + (v13*v);
|
||||
}
|
||||
|
||||
|
||||
/** 2D UV */
|
||||
void getUV(const Point2 p, float& u, float& v) const {
|
||||
|
||||
// https://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates
|
||||
const Point2 v0 = p2.xy() - p1.xy();
|
||||
const Point2 v1 = p3.xy() - p1.xy();
|
||||
const Point2 v2 = p - p1.xy();
|
||||
const float den = v0.x * v1.y - v1.x * v0.y;
|
||||
u = (v2.x * v1.y - v1.x * v2.y) / den;
|
||||
v = (v0.x * v2.y - v2.x * v0.y) / den;
|
||||
|
||||
}
|
||||
|
||||
/** 2D UVW */
|
||||
void getUVW(const Point2 p, float& u, float& v, float& w) const {
|
||||
getUV(p,u,v);
|
||||
w = 1-u-v;
|
||||
}
|
||||
|
||||
/** 3D UV */
|
||||
void getUV(const Point3 p, float& u, float& v) const {
|
||||
|
||||
const Point3 v0 = p2 - p1;
|
||||
const Point3 v1 = p3 - p1;
|
||||
const Point3 v2 = p - p1;
|
||||
const float d00 = dot(v0, v0);
|
||||
const float d01 = dot(v0, v1);
|
||||
const float d11 = dot(v1, v1);
|
||||
const float d20 = dot(v2, v0);
|
||||
const float d21 = dot(v2, v1);
|
||||
const float denom = d00 * d11 - d01 * d01;
|
||||
u = (d11 * d20 - d01 * d21) / denom;
|
||||
v = (d00 * d21 - d01 * d20) / denom;
|
||||
//w = 1.0f - v - w;
|
||||
|
||||
int xx = 0; (void) xx;
|
||||
|
||||
}
|
||||
|
||||
/** 3D UVW */
|
||||
void getUVW(const Point3 p, float& u, float& v, float& w) const {
|
||||
getUV(p,u,v);
|
||||
w = 1-u-v;
|
||||
}
|
||||
|
||||
template <typename T> T interpolate(const Point3 p, const T val1, const T val2, const T val3) const {
|
||||
|
||||
float u, v, w;
|
||||
getUVW(p.xy(),u,v,w);
|
||||
|
||||
return (w*val1) + (u*val2) + (v*val3);
|
||||
|
||||
}
|
||||
|
||||
/** does the triangle contain the given 3D point? */
|
||||
bool contains(const Point3 p) const {
|
||||
return (minZ <= p.z) && (maxZ >= p.z) && contains(p.xy());
|
||||
@@ -131,15 +202,18 @@ namespace NM {
|
||||
/** does the triangle contain the given 2D point? */
|
||||
bool contains(const Point2 p) const {
|
||||
|
||||
const Point2 v2 = p - p1.xy();
|
||||
// const Point2 v2 = p - p1.xy();
|
||||
|
||||
// Compute dot products
|
||||
float dot02 = dot(v0, v2);
|
||||
float dot12 = dot(v1, v2);
|
||||
// // Compute dot products
|
||||
// float dot02 = dot(v0, v2);
|
||||
// float dot12 = dot(v1, v2);
|
||||
|
||||
// Compute barycentric coordinates
|
||||
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
// // Compute barycentric coordinates
|
||||
// float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
// float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
|
||||
float u, v;
|
||||
getUV(p, u, v);
|
||||
|
||||
// Check if point is in triangle
|
||||
return (u >= 0) && (v >= 0) && (u + v <= 1);
|
||||
@@ -149,17 +223,20 @@ namespace NM {
|
||||
/** estimate the correct z-value for the given 2D point */
|
||||
Point3 toPoint3(const Point2 p) const {
|
||||
|
||||
const Point2 v2 = p - p1.xy();
|
||||
// const Point2 v2 = p - p1.xy();
|
||||
|
||||
// Compute dot products
|
||||
float dot02 = dot(v0, v2);
|
||||
float dot12 = dot(v1, v2);
|
||||
// // Compute dot products
|
||||
// float dot02 = dot(v0, v2);
|
||||
// float dot12 = dot(v1, v2);
|
||||
|
||||
// Compute barycentric coordinates
|
||||
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
// // Compute barycentric coordinates
|
||||
// float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
// float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
|
||||
const Point3 res = getPoint(v,u);
|
||||
float u, v;
|
||||
getUV(p, u, v);
|
||||
|
||||
const Point3 res = getPoint(u,v);
|
||||
Assert::isNear(res.x, p.x, 1.0f, "TODO: high difference while mapping from 2D to 3D");
|
||||
Assert::isNear(res.y, p.y, 1.0f, "TODO: high difference while mapping from 2D to 3D");
|
||||
|
||||
@@ -180,6 +257,14 @@ namespace NM {
|
||||
return center;
|
||||
}
|
||||
|
||||
/** cast to string */
|
||||
operator std::string() const {return asString();}
|
||||
|
||||
/** get as string */
|
||||
std::string asString() const {
|
||||
return "(" + std::to_string(center.x) + "," + std::to_string(center.y) + "," + std::to_string(center.z) + ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
@@ -191,17 +276,17 @@ namespace NM {
|
||||
minZ = std::min(p1.z, std::min(p2.z, p3.z)) - 0.15; // TODO the builder does not align on the same height as we did
|
||||
maxZ = std::max(p1.z, std::max(p2.z, p3.z)) + 0.15;
|
||||
|
||||
// Compute vectors
|
||||
v0 = p3.xy() - p1.xy();
|
||||
v1 = p2.xy() - p1.xy();
|
||||
// // Compute vectors
|
||||
// v0 = p3.xy() - p1.xy();
|
||||
// v1 = p2.xy() - p1.xy();
|
||||
|
||||
// Compute dot products
|
||||
dot00 = dot(v0, v0);
|
||||
dot01 = dot(v0, v1);
|
||||
dot11 = dot(v1, v1);
|
||||
// // Compute dot products
|
||||
// dot00 = dot(v0, v0);
|
||||
// dot01 = dot(v0, v1);
|
||||
// dot11 = dot(v1, v1);
|
||||
|
||||
// Compute barycentric coordinates
|
||||
invDenom = 1.0 / ((double)dot00 * (double)dot11 - (double)dot01 * (double)dot01);
|
||||
// // Compute barycentric coordinates
|
||||
// invDenom = 1.0 / ((double)dot00 * (double)dot11 - (double)dot01 * (double)dot01);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user