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;
}
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)
{
if (!data.snapToEdges || !template.Obstruction || !template.Obstruction.Static)
return undefined;
let width = template.Obstruction.Static["@depth"] / 2;
let depth = template.Obstruction.Static["@width"] / 2;
const width = template.Obstruction.Static["@width"] / 2;
const depth = template.Obstruction.Static["@depth"] / 2;
const maxSide = Math.max(width, depth);
let templatePos = Vector2D.from3D(data);
let templateAngle = data.angle || 0;
@ -97,16 +109,15 @@ class ObstructionSnap
difference = Math.min(difference, Math.PI * 2 - difference);
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;
break;
}
}
let [sizeToBaseEdge, sizeToPairedEdge] =
this.getNearestSizeAlongNormal(width, depth, templateAngle, baseEdge.normal);
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);
if (edges.length > 1)
{
@ -136,7 +147,7 @@ class ObstructionSnap
if (this.compareEdges(edge, secondEdge) < 0)
secondEdge = edge;
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 {

View File

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