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:
parent
30fc281a4c
commit
333f7b4fb4
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user