1
0
forked from 0ad/0ad

Fixes building snapping for non-square foundations. Fixes #5976

Tested By: Freagarach, Langbart, Stan
Differential Revision: https://code.wildfiregames.com/D3510
This was SVN commit r24827.
This commit is contained in:
Vladislav Belov 2021-02-03 17:03:44 +00:00
parent 30fc281a4c
commit 333f7b4fb4
2 changed files with 21 additions and 10 deletions

View File

@ -68,13 +68,25 @@ class ObstructionSnap
return scoreA - scoreB; return scoreA - scoreB;
} }
getNearestSizeAlongNormal(width, depth, angle, normal)
{
// Front face direction.
let direction = new Vector2D(0.0, 1.0);
direction.rotate(angle);
let dot = direction.dot(normal);
const threshold = Math.cos(Math.PI / 4.0);
if (Math.abs(dot) > threshold)
return [depth, width];
return [width, depth];
}
getPosition(data, template) getPosition(data, template)
{ {
if (!data.snapToEdges || !template.Obstruction || !template.Obstruction.Static) if (!data.snapToEdges || !template.Obstruction || !template.Obstruction.Static)
return undefined; return undefined;
let width = template.Obstruction.Static["@depth"] / 2; const width = template.Obstruction.Static["@width"] / 2;
let depth = template.Obstruction.Static["@width"] / 2; const depth = template.Obstruction.Static["@depth"] / 2;
const maxSide = Math.max(width, depth); const maxSide = Math.max(width, depth);
let templatePos = Vector2D.from3D(data); let templatePos = Vector2D.from3D(data);
let templateAngle = data.angle || 0; let templateAngle = data.angle || 0;
@ -97,16 +109,15 @@ class ObstructionSnap
difference = Math.min(difference, Math.PI * 2 - difference); difference = Math.min(difference, Math.PI * 2 - difference);
if (difference < Math.PI / 4 + this.EPS) if (difference < Math.PI / 4 + this.EPS)
{ {
// We need to swap sides for orthogonal cases.
if (dir % 2 == 0)
[width, depth] = [depth, width];
templateAngle = angleCandidate; templateAngle = angleCandidate;
break; break;
} }
} }
let [sizeToBaseEdge, sizeToPairedEdge] =
this.getNearestSizeAlongNormal(width, depth, templateAngle, baseEdge.normal);
let distance = Vector2D.dot(baseEdge.normal, templatePos) - Vector2D.dot(baseEdge.normal, baseEdge.begin); let distance = Vector2D.dot(baseEdge.normal, templatePos) - Vector2D.dot(baseEdge.normal, baseEdge.begin);
templatePos.sub(Vector2D.mult(baseEdge.normal, distance - width - this.getPadding(baseEdge))); templatePos.sub(Vector2D.mult(baseEdge.normal, distance - sizeToBaseEdge - this.getPadding(baseEdge)));
edges = this.getValidEdges(data.snapToEdges, templatePos, maxSide); edges = this.getValidEdges(data.snapToEdges, templatePos, maxSide);
if (edges.length > 1) if (edges.length > 1)
{ {
@ -136,7 +147,7 @@ class ObstructionSnap
if (this.compareEdges(edge, secondEdge) < 0) if (this.compareEdges(edge, secondEdge) < 0)
secondEdge = edge; secondEdge = edge;
let distance = Vector2D.dot(secondEdge.normal, templatePos) - Vector2D.dot(secondEdge.normal, secondEdge.begin); let distance = Vector2D.dot(secondEdge.normal, templatePos) - Vector2D.dot(secondEdge.normal, secondEdge.begin);
templatePos.sub(Vector2D.mult(secondEdge.normal, distance - depth - this.getPadding(secondEdge))); templatePos.sub(Vector2D.mult(secondEdge.normal, distance - sizeToPairedEdge - this.getPadding(secondEdge)));
} }
} }
return { return {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2020 Wildfire Games. /* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -156,7 +156,7 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter
halfSize, halfSize,
CFixedVector2D(halfSize.X, -halfSize.Y) CFixedVector2D(halfSize.X, -halfSize.Y)
}; };
fixed angle = cmpPosition->GetRotation().Y; const fixed angle = cmpPosition->GetRotation().Y;
for (CFixedVector2D& corner : corners) for (CFixedVector2D& corner : corners)
corner = corner.Rotate(angle) + cmpPosition->GetPosition2D(); corner = corner.Rotate(angle) + cmpPosition->GetPosition2D();
@ -166,7 +166,7 @@ JS::Value JSI_Simulation::GetEdgesOfStaticObstructionsOnScreenNearTo(ScriptInter
const CFixedVector2D& corner = corners[i]; const CFixedVector2D& corner = corners[i];
const CFixedVector2D& nextCorner = corners[(i + 1) % corners.size()]; const CFixedVector2D& nextCorner = corners[(i + 1) % corners.size()];
fixed distanceToEdge = const fixed distanceToEdge =
Geometry::DistanceToSegment(entityPos, corner, nextCorner); Geometry::DistanceToSegment(entityPos, corner, nextCorner);
if (distanceToEdge.ToFloat() > distanceThreshold) if (distanceToEdge.ToFloat() > distanceThreshold)
continue; continue;