navmeshes can use any convex polygons, not just triangles
parent
491a5b3331
commit
4c62c864ea
|
@ -5,8 +5,14 @@ _, inpath, outpath, basename = sys.argv
|
||||||
|
|
||||||
tree = lxml.etree.parse(inpath)
|
tree = lxml.etree.parse(inpath)
|
||||||
|
|
||||||
tris = []
|
polys = []
|
||||||
edge2tri = {}
|
edge2poly = {}
|
||||||
|
|
||||||
|
# Polygons must be convex to work correctly, but we don't verify that
|
||||||
|
|
||||||
|
def points_to_edges(points):
|
||||||
|
points = points + [points[0]]
|
||||||
|
return zip(points[:-1], points[1:])
|
||||||
|
|
||||||
for polygon in tree.findall("objectgroup[@name='navmesh']/object/polygon"):
|
for polygon in tree.findall("objectgroup[@name='navmesh']/object/polygon"):
|
||||||
basex = int(polygon.getparent().attrib["x"])
|
basex = int(polygon.getparent().attrib["x"])
|
||||||
|
@ -26,33 +32,32 @@ for polygon in tree.findall("objectgroup[@name='navmesh']/object/polygon"):
|
||||||
cross = abx*acy-acx*aby
|
cross = abx*acy-acx*aby
|
||||||
# positive for clockwise winding order. Example clockwise winding order: (0,0), (1,0), (0,1)
|
# positive for clockwise winding order. Example clockwise winding order: (0,0), (1,0), (0,1)
|
||||||
if cross < 0:
|
if cross < 0:
|
||||||
points = points[0],points[2],points[1]
|
points = points[::-1]
|
||||||
bx,by,cx,cy=cx,cy,bx,by
|
|
||||||
cross = -cross
|
|
||||||
|
|
||||||
assert len(points)==3, "triangles only"
|
poly_id = len(polys)
|
||||||
tri_id = len(tris)
|
polys.append(points)
|
||||||
tris.append(points)
|
|
||||||
|
|
||||||
for edge in [(points[0],points[1]), (points[1],points[2]), (points[2],points[0])]:
|
print(points)
|
||||||
|
for edge in points_to_edges(points):
|
||||||
edge_id = tuple(sorted(edge))
|
edge_id = tuple(sorted(edge))
|
||||||
if edge_id not in edge2tri: edge2tri[edge_id] = []
|
print(edge, edge_id)
|
||||||
edge2tri[edge_id].append(tri_id)
|
if edge_id not in edge2poly: edge2poly[edge_id] = []
|
||||||
assert len(edge2tri[edge_id]) <= 2, "more than 2 triangles share edge "+str(edge_id)
|
edge2poly[edge_id].append(poly_id)
|
||||||
|
assert len(edge2poly[edge_id]) <= 2, "more than 2 polygons share edge "+str(edge_id)
|
||||||
|
|
||||||
pathfind_edges = [[] for _ in range(len(tris))]
|
pathfind_edges = [[] for _ in range(len(polys))]
|
||||||
for edgetris in edge2tri.values():
|
for edgepolys in edge2poly.values():
|
||||||
assert len(edgetris) in (1,2)
|
assert len(edgepolys) in (1,2)
|
||||||
if len(edgetris) == 1: continue
|
if len(edgepolys) == 1: continue
|
||||||
t1,t2 = edgetris
|
p1,p2 = edgepolys
|
||||||
pathfind_edges[t1].append(t2)
|
pathfind_edges[p1].append(p2)
|
||||||
pathfind_edges[t2].append(t1)
|
pathfind_edges[p2].append(p1)
|
||||||
|
|
||||||
pathfind_matrix = [[255 for _1 in range(len(tris))] for _2 in range(len(tris))]
|
pathfind_matrix = [[255 for _1 in range(len(polys))] for _2 in range(len(polys))]
|
||||||
# pathfind_matrix[source][dest] is how to get to dest from source
|
# pathfind_matrix[source][dest] is how to get to dest from source
|
||||||
|
|
||||||
for dest in range(len(tris)):
|
for dest in range(len(polys)):
|
||||||
# Find paths to tri by breadth-first search. We don't take the size of the triangle into account yet.
|
# Find paths to poly by breadth-first search. We don't take the size of the polygon into account yet.
|
||||||
openset = [dest]
|
openset = [dest]
|
||||||
while len(openset)>0:
|
while len(openset)>0:
|
||||||
cur, openset = openset[0], openset[1:]
|
cur, openset = openset[0], openset[1:]
|
||||||
|
@ -66,11 +71,13 @@ for dest in range(len(tris)):
|
||||||
out = open(outpath,"w")
|
out = open(outpath,"w")
|
||||||
|
|
||||||
out.write("#include \"compiled_structures.h\"\n")
|
out.write("#include \"compiled_structures.h\"\n")
|
||||||
out.write(f"static const struct navmesh_tri {basename}_triangles[{len(tris)}] = {{\n");
|
out.write(f"static const struct navmesh_tri {basename}_triangles[{len(polys)}] = {{\n");
|
||||||
for tri_id,points in enumerate(tris):
|
for poly_id,points in enumerate(polys):
|
||||||
out.write("\t{\n\t\t{\n");
|
out.write("\t{\n")
|
||||||
for a,b,c in [(points[0],points[1],points[2]), (points[1],points[2],points[0]), (points[2],points[0],points[1])]:
|
out.write("\t\t"+str(len(points))+",\n")
|
||||||
(ax,ay),(bx,by),(cx,cy) = a,b,c
|
out.write("\t\t(const struct navmesh_tri_edge[]){\n")
|
||||||
|
for a,b in points_to_edges(points):
|
||||||
|
(ax,ay),(bx,by) = a,b
|
||||||
# edge a-b and c is the other point
|
# edge a-b and c is the other point
|
||||||
# Line equation Px+Qy+R=0 from https://math.stackexchange.com/questions/422602/convert-two-points-to-line-eq-ax-by-c-0
|
# Line equation Px+Qy+R=0 from https://math.stackexchange.com/questions/422602/convert-two-points-to-line-eq-ax-by-c-0
|
||||||
P,Q,R=ay-by,bx-ax,ax*by-bx*ay
|
P,Q,R=ay-by,bx-ax,ax*by-bx*ay
|
||||||
|
@ -82,29 +89,29 @@ for tri_id,points in enumerate(tris):
|
||||||
R *= norm
|
R *= norm
|
||||||
|
|
||||||
edge_id = tuple(sorted((a,b)))
|
edge_id = tuple(sorted((a,b)))
|
||||||
tris_on_edge = edge2tri[edge_id]
|
polys_on_edge = edge2poly[edge_id]
|
||||||
assert len(tris_on_edge) in (1,2)
|
assert len(polys_on_edge) in (1,2)
|
||||||
assert tri_id in tris_on_edge
|
assert poly_id in polys_on_edge
|
||||||
if len(tris_on_edge) == 2:
|
if len(polys_on_edge) == 2:
|
||||||
other_tri_id = [x for x in tris_on_edge if x!=tri_id][0]
|
other_poly_id = [x for x in polys_on_edge if x!=poly_id][0]
|
||||||
else:
|
else:
|
||||||
other_tri_id = -1
|
other_poly_id = -1
|
||||||
|
|
||||||
centx, centy = (ax+bx)/2, (ay+by)/2
|
centx, centy = (ax+bx)/2, (ay+by)/2
|
||||||
|
|
||||||
out.write(f"\t\t\t{{{P},{Q},{R},{other_tri_id},{{{int(centx)},{int(centy)}}}}},\n")
|
out.write(f"\t\t\t{{{P},{Q},{R},{other_poly_id},{{{int(centx)},{int(centy)}}}}},\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
out.write("\t\t},\n")
|
out.write("\t\t},\n")
|
||||||
out.write("\t\t{" + ",".join(f"{{{x},{y}}}" for x,y in points) + "},\n")
|
out.write("\t\t(const struct navmesh_point[]){" + ",".join(f"{{{x},{y}}}" for x,y in points) + "},\n")
|
||||||
out.write("\t},\n");
|
out.write("\t},\n");
|
||||||
out.write("};\n")
|
out.write("};\n")
|
||||||
out.write(f"static const unsigned char {basename}_pathfind[{len(tris)*len(tris)}] = {{\n")
|
out.write(f"static const unsigned char {basename}_pathfind[{len(polys)*len(polys)}] = {{\n")
|
||||||
for dest in range(len(tris)):
|
for dest in range(len(polys)):
|
||||||
out.write("\t")
|
out.write("\t")
|
||||||
for source in range(len(tris)):
|
for source in range(len(polys)):
|
||||||
out.write(str(pathfind_matrix[source][dest])+",")
|
out.write(str(pathfind_matrix[source][dest])+",")
|
||||||
out.write("\n")
|
out.write("\n")
|
||||||
out.write("};\n")
|
out.write("};\n")
|
||||||
out.write(f"extern const struct navmesh {basename} = {{{len(tris)}, {basename}_triangles, {basename}_pathfind}};\n")
|
out.write(f"extern const struct navmesh {basename} = {{{len(polys)}, {basename}_triangles, {basename}_pathfind}};\n")
|
||||||
|
|
|
@ -11,8 +11,10 @@ struct navmesh_tri_edge {
|
||||||
struct navmesh_point center; // intermediate point for use in routing. could be improved later.
|
struct navmesh_point center; // intermediate point for use in routing. could be improved later.
|
||||||
};
|
};
|
||||||
struct navmesh_tri {
|
struct navmesh_tri {
|
||||||
struct navmesh_tri_edge edges[3];
|
int num_verts;
|
||||||
struct navmesh_point points[3];
|
const struct navmesh_tri_edge *edges;
|
||||||
|
const struct navmesh_point *points;
|
||||||
|
// For a triangle:
|
||||||
// edges[0]: points[0]-points[1]
|
// edges[0]: points[0]-points[1]
|
||||||
// edges[1]: points[1]-points[2]
|
// edges[1]: points[1]-points[2]
|
||||||
// edges[2]: points[2]-points[0]
|
// edges[2]: points[2]-points[0]
|
||||||
|
|
20
game.cpp
20
game.cpp
|
@ -44,20 +44,22 @@ static void transition_scene_on_walk_finish(struct script *scr, int wakeupMode,
|
||||||
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
|
assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void start_player_walk_to_point_then_transition_scene(int x, int y, int scene) {
|
||||||
|
start_player_walk_to_point(x, y);
|
||||||
|
|
||||||
|
struct script *scr = scene_add_script(OBJID_PLAYER_WALK_TO_DOOR_SCRIPT, true);
|
||||||
|
scr->wakeupMode = SCRIPT_WAKEUP_OTHER_SCRIPT;
|
||||||
|
scr->wakeupArg1 = OBJID_PLAYER_WALK_SCRIPT;
|
||||||
|
scr->wakeupFn = transition_scene_on_walk_finish;
|
||||||
|
scr->vars[0] = scene;
|
||||||
|
}
|
||||||
|
|
||||||
void onclick(int curscene, int objid) {
|
void onclick(int curscene, int objid) {
|
||||||
switch(curscene) {
|
switch(curscene) {
|
||||||
case SCENE_LOBBY:
|
case SCENE_LOBBY:
|
||||||
switch(objid) {
|
switch(objid) {
|
||||||
case OBJID_DOOR_TO_MANAGERS_OFFICE_FROM_LOBBY:
|
case OBJID_DOOR_TO_MANAGERS_OFFICE_FROM_LOBBY:
|
||||||
{
|
start_player_walk_to_point_then_transition_scene(312, 441, SCENE_MANAGERS_OFFICE);
|
||||||
start_player_walk_to_point(312, 441);
|
|
||||||
|
|
||||||
struct script *scr = scene_add_script(OBJID_PLAYER_WALK_TO_DOOR_SCRIPT, true);
|
|
||||||
scr->wakeupMode = SCRIPT_WAKEUP_OTHER_SCRIPT;
|
|
||||||
scr->wakeupArg1 = OBJID_PLAYER_WALK_SCRIPT;
|
|
||||||
scr->wakeupFn = transition_scene_on_walk_finish;
|
|
||||||
scr->vars[0] = SCENE_MANAGERS_OFFICE;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -41,28 +41,22 @@
|
||||||
<polygon points="0,0 135,85 191,-1"/>
|
<polygon points="0,0 135,85 191,-1"/>
|
||||||
</object>
|
</object>
|
||||||
<object id="11" x="213" y="441">
|
<object id="11" x="213" y="441">
|
||||||
<polygon points="0,0 -211,301 135,85"/>
|
<polygon points="0,0 -211,301 134,176 135,85"/>
|
||||||
</object>
|
|
||||||
<object id="12" x="2" y="741">
|
|
||||||
<polygon points="0,1 345,-124 346,-215"/>
|
|
||||||
</object>
|
</object>
|
||||||
<object id="13" x="2" y="742">
|
<object id="13" x="2" y="742">
|
||||||
<polygon points="0,0 0,57 345,-125"/>
|
<polygon points="0,0 0,57 330,58 345,-125"/>
|
||||||
</object>
|
</object>
|
||||||
<object id="14" x="2" y="799">
|
<object id="14" x="2" y="799">
|
||||||
<polygon points="0,0 1278,1 345,-182"/>
|
<polygon points="330,1 959,1 933,-174 345,-182"/>
|
||||||
</object>
|
|
||||||
<object id="15" x="348" y="617">
|
|
||||||
<polygon points="-1,0 587,8 932,183"/>
|
|
||||||
</object>
|
</object>
|
||||||
<object id="16" x="860" y="440">
|
<object id="16" x="860" y="440">
|
||||||
<polygon points="0,0 77,118 180,0"/>
|
<polygon points="0,0 76,118 180,0"/>
|
||||||
</object>
|
</object>
|
||||||
<object id="17" x="937" y="558">
|
<object id="17" x="937" y="558">
|
||||||
<polygon points="0,0 343,242 103,-118"/>
|
<polygon points="-1,0 -2,67 245,95 103,-118"/>
|
||||||
</object>
|
</object>
|
||||||
<object id="18" x="939" y="559">
|
<object id="18" x="939" y="559">
|
||||||
<polygon points="-2,-1 -4,66 341,241"/>
|
<polygon points="243,94 -4,66 22,241 341,241"/>
|
||||||
</object>
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="32" tileheight="32" infinite="0" nextlayerid="4" nextobjectid="19">
|
||||||
|
<layer id="1" name="Tile Layer 1" width="30" height="20">
|
||||||
|
<data encoding="csv">
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
<imagelayer id="2" name="Image Layer 1">
|
||||||
|
<image source="../build/default/managers_office.png" width="1280" height="800"/>
|
||||||
|
</imagelayer>
|
||||||
|
<objectgroup id="3" name="navmesh">
|
||||||
|
<object id="1" x="305" y="491">
|
||||||
|
<polygon points="0,0 42,73 -93,163"/>
|
||||||
|
</object>
|
||||||
|
<object id="2" x="177" y="715">
|
||||||
|
<polygon points="35,-61 170,-151 133,-61"/>
|
||||||
|
</object>
|
||||||
|
<object id="3" x="312" y="654">
|
||||||
|
<polygon points="-2,0 -27,60 148,0"/>
|
||||||
|
</object>
|
||||||
|
<object id="4" x="212" y="654">
|
||||||
|
<polygon points="0,0 -33,60 73,60"/>
|
||||||
|
</object>
|
||||||
|
<object id="5" x="212" y="654">
|
||||||
|
<polygon points="0,0 98,0 73,60"/>
|
||||||
|
</object>
|
||||||
|
<object id="6" x="285" y="714">
|
||||||
|
<polygon points="0,0 175,0 175,-60"/>
|
||||||
|
</object>
|
||||||
|
<object id="7" x="305" y="491">
|
||||||
|
<polygon points="0,0 187,1 169,71"/>
|
||||||
|
</object>
|
||||||
|
<object id="8" x="305" y="491">
|
||||||
|
<polygon points="0,0 42,73 169,71"/>
|
||||||
|
</object>
|
||||||
|
<object id="9" x="595" y="417">
|
||||||
|
<polygon points="0,0 0,75 189,0"/>
|
||||||
|
</object>
|
||||||
|
<object id="10" x="595" y="492">
|
||||||
|
<polygon points="0,0 229,0 189,-75"/>
|
||||||
|
</object>
|
||||||
|
<object id="11" x="824" y="492">
|
||||||
|
<polygon points="0,0 105,222 278,222"/>
|
||||||
|
</object>
|
||||||
|
<object id="12" x="825" y="493">
|
||||||
|
<polygon points="-1,-1 149,-1 277,221"/>
|
||||||
|
</object>
|
||||||
|
<object id="13" x="595" y="492">
|
||||||
|
<polygon points="0,0 334,222 229,0"/>
|
||||||
|
</object>
|
||||||
|
<object id="14" x="595" y="492">
|
||||||
|
<polygon points="0,0 0,222 334,222"/>
|
||||||
|
</object>
|
||||||
|
<object id="15" x="474" y="562">
|
||||||
|
<polygon points="0,0 18,-70 121,-70"/>
|
||||||
|
</object>
|
||||||
|
<object id="16" x="474" y="562">
|
||||||
|
<polygon points="0,0 121,-70 121,152"/>
|
||||||
|
</object>
|
||||||
|
<object id="17" x="474" y="562">
|
||||||
|
<polygon points="0,0 -14,92 121,152"/>
|
||||||
|
</object>
|
||||||
|
<object id="18" x="460" y="654">
|
||||||
|
<polygon points="0,0 0,60 135,60"/>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
|
</map>
|
|
@ -228,7 +228,7 @@ static void closest_point_inside_tri(int *x, int *y, const struct navmesh_tri *t
|
||||||
// If this happens, we must be in a corner region.
|
// If this happens, we must be in a corner region.
|
||||||
// Repeated normal-vector moves don't necessarily bring us to the corner, but we can just hardcode the corner.
|
// Repeated normal-vector moves don't necessarily bring us to the corner, but we can just hardcode the corner.
|
||||||
for(int j = 0; j < 2; j++) {
|
for(int j = 0; j < 2; j++) {
|
||||||
for(int i = 0; i < 3; i++) {
|
for(int i = 0; i < tri->num_verts; i++) {
|
||||||
double edgeval = fx*tri->edges[i].a + fy*tri->edges[i].b + tri->edges[i].c;
|
double edgeval = fx*tri->edges[i].a + fy*tri->edges[i].b + tri->edges[i].c;
|
||||||
if(edgeval <= 0) {
|
if(edgeval <= 0) {
|
||||||
// edge.a,b is normalized so that moving 1 unit of a and 1 unit of b changes edgeval by 1.
|
// edge.a,b is normalized so that moving 1 unit of a and 1 unit of b changes edgeval by 1.
|
||||||
|
@ -239,6 +239,16 @@ static void closest_point_inside_tri(int *x, int *y, const struct navmesh_tri *t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < tri->num_verts; i++) {
|
||||||
|
int next = (i+1) % tri->num_verts;
|
||||||
|
int mask = (1 << i) | (1 << next);
|
||||||
|
if((edgeHitMask & mask) == mask) {
|
||||||
|
*x = tri->points[next].x;
|
||||||
|
*y = tri->points[next].y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
switch(edgeHitMask) {
|
switch(edgeHitMask) {
|
||||||
case 3: // hit edge 0-1 and 1-2
|
case 3: // hit edge 0-1 and 1-2
|
||||||
*x = tri->points[1].x;
|
*x = tri->points[1].x;
|
||||||
|
@ -252,7 +262,7 @@ static void closest_point_inside_tri(int *x, int *y, const struct navmesh_tri *t
|
||||||
*x = tri->points[2].x;
|
*x = tri->points[2].x;
|
||||||
*y = tri->points[2].y;
|
*y = tri->points[2].y;
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// may be slightly outside of triangle due to rounding errors, but good enough for us
|
// may be slightly outside of triangle due to rounding errors, but good enough for us
|
||||||
*x = (int)(fx + 0.5);
|
*x = (int)(fx + 0.5);
|
||||||
|
@ -267,16 +277,33 @@ static double point_to_point_dist(int x, int y, const struct navmesh_point *pt)
|
||||||
|
|
||||||
// Returns distance from triangle, 0 if inside.
|
// Returns distance from triangle, 0 if inside.
|
||||||
static double is_point_in_tri(int x, int y, const struct navmesh_tri *tri) {
|
static double is_point_in_tri(int x, int y, const struct navmesh_tri *tri) {
|
||||||
double edgedist[3]; // positive if outside
|
/*double edgedist[3]; // positive if outside
|
||||||
for(int edge = 0; edge < 3; edge++)
|
for(int edge = 0; edge < 3; edge++)
|
||||||
edgedist[edge] = -(x*tri->edges[edge].a + y*tri->edges[edge].b + tri->edges[edge].c);
|
edgedist[edge] = -(x*tri->edges[edge].a + y*tri->edges[edge].b + tri->edges[edge].c);
|
||||||
if(edgedist[0] < 0 && edgedist[1] < 0 && edgedist[2] < 0) return 0; // inside
|
if(edgedist[0] < 0 && edgedist[1] < 0 && edgedist[2] < 0) return 0; // inside
|
||||||
if(edgedist[0] >= 0 && edgedist[1] >= 0) return point_to_point_dist(x, y, &tri->points[0]);
|
if(edgedist[0] >= 0 && edgedist[1] >= 0) return point_to_point_dist(x, y, &tri->points[0]); // are these correct? shouldn't it be points 1,2,0?
|
||||||
if(edgedist[1] >= 0 && edgedist[2] >= 0) return point_to_point_dist(x, y, &tri->points[1]);
|
if(edgedist[1] >= 0 && edgedist[2] >= 0) return point_to_point_dist(x, y, &tri->points[1]);
|
||||||
if(edgedist[2] >= 0 && edgedist[0] >= 0) return point_to_point_dist(x, y, &tri->points[2]);
|
if(edgedist[2] >= 0 && edgedist[0] >= 0) return point_to_point_dist(x, y, &tri->points[2]);
|
||||||
if(edgedist[0] >= 0) return edgedist[0];
|
if(edgedist[0] >= 0) return edgedist[0];
|
||||||
if(edgedist[1] >= 0) return edgedist[1];
|
if(edgedist[1] >= 0) return edgedist[1];
|
||||||
if(edgedist[2] >= 0) return edgedist[2];
|
if(edgedist[2] >= 0) return edgedist[2];*/
|
||||||
|
|
||||||
|
double edgedist[tri->num_verts];
|
||||||
|
bool all_inside = true;
|
||||||
|
for(int edge = 0; edge < tri->num_verts; edge++) {
|
||||||
|
edgedist[edge] = -(x*tri->edges[edge].a + y*tri->edges[edge].b + tri->edges[edge].c);
|
||||||
|
if(edgedist[edge] > 0)
|
||||||
|
all_inside = false;
|
||||||
|
}
|
||||||
|
if(all_inside) return 0;
|
||||||
|
for(int edge = 0; edge < tri->num_verts; edge++) {
|
||||||
|
int next = (edge+1)%tri->num_verts;
|
||||||
|
if(edgedist[edge] >= 0 && edgedist[next] >= 0) return point_to_point_dist(x, y, &tri->points[next]);
|
||||||
|
}
|
||||||
|
for(int edge = 0; edge < tri->num_verts; edge++)
|
||||||
|
if(edgedist[edge] >= 0)
|
||||||
|
return edgedist[edge];
|
||||||
|
|
||||||
return 0; // branch should be unreachable; maybe within epsilon of triangle border?
|
return 0; // branch should be unreachable; maybe within epsilon of triangle border?
|
||||||
}
|
}
|
||||||
static int find_navmesh_tri(int x, int y, int tolerance) {
|
static int find_navmesh_tri(int x, int y, int tolerance) {
|
||||||
|
@ -378,7 +405,7 @@ static void update_player_walk_script_on_frame(struct script *scr, int wakeupMod
|
||||||
} else {
|
} else {
|
||||||
nextTri = cur_navmesh->pathfindgrid[player_walk_script->targetNavmeshTri * cur_navmesh->num_tris + nmtri];
|
nextTri = cur_navmesh->pathfindgrid[player_walk_script->targetNavmeshTri * cur_navmesh->num_tris + nmtri];
|
||||||
nextX = -1;
|
nextX = -1;
|
||||||
for(int edge = 0; edge < 3; edge++) {
|
for(int edge = 0; edge < cur_navmesh->tris[nmtri].num_verts; edge++) {
|
||||||
if(cur_navmesh->tris[nmtri].edges[edge].other_tri == nextTri) {
|
if(cur_navmesh->tris[nmtri].edges[edge].other_tri == nextTri) {
|
||||||
nextX = cur_navmesh->tris[nmtri].edges[edge].center.x;
|
nextX = cur_navmesh->tris[nmtri].edges[edge].center.x;
|
||||||
nextY = cur_navmesh->tris[nmtri].edges[edge].center.y;
|
nextY = cur_navmesh->tris[nmtri].edges[edge].center.y;
|
||||||
|
|
Loading…
Reference in New Issue