Refactor path smoothing logic and remove unused functions
This commit is contained in:
@@ -219,109 +219,56 @@ function findNonZeroSegmentTangent(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const SMOOTH_PATH_SEGMENT_SUBDIVISIONS = 16;
|
const SMOOTH_PATH_CORNER_CUTTING_PASSES = 3;
|
||||||
|
|
||||||
function getPathSamplePoint(
|
function lerpVec3(start: Vec3, end: Vec3, t: number): Vec3 {
|
||||||
path: ResolvedPathLike,
|
return {
|
||||||
index: number
|
x: start.x + (end.x - start.x) * t,
|
||||||
): Vec3 {
|
y: start.y + (end.y - start.y) * t,
|
||||||
const points = path.points;
|
z: start.z + (end.z - start.z) * t
|
||||||
const pointCount = points.length;
|
};
|
||||||
|
|
||||||
if (pointCount === 0) {
|
|
||||||
return {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.loop) {
|
|
||||||
const wrappedIndex = ((index % pointCount) + pointCount) % pointCount;
|
|
||||||
return cloneVec3(points[wrappedIndex]!.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index <= 0) {
|
|
||||||
return cloneVec3(points[0]!.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= pointCount - 1) {
|
|
||||||
return cloneVec3(points[pointCount - 1]!.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloneVec3(points[index]!.position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluateCatmullRomPosition(
|
function buildSmoothedPolylinePoints(path: ResolvedPathLike): Vec3[] {
|
||||||
p0: Vec3,
|
let points = path.points.map((point) => cloneVec3(point.position));
|
||||||
p1: Vec3,
|
|
||||||
p2: Vec3,
|
|
||||||
p3: Vec3,
|
|
||||||
t: number
|
|
||||||
): Vec3 {
|
|
||||||
const t2 = t * t;
|
|
||||||
const t3 = t2 * t;
|
|
||||||
|
|
||||||
return scaleVec3(
|
for (
|
||||||
addVec3(
|
let passIndex = 0;
|
||||||
addVec3(
|
passIndex < SMOOTH_PATH_CORNER_CUTTING_PASSES;
|
||||||
scaleVec3(p1, 2),
|
passIndex += 1
|
||||||
scaleVec3(subtractVec3(p2, p0), t)
|
) {
|
||||||
),
|
if (points.length < 2) {
|
||||||
addVec3(
|
return points;
|
||||||
scaleVec3(
|
}
|
||||||
addVec3(
|
|
||||||
addVec3(scaleVec3(p0, 2), scaleVec3(p1, -5)),
|
|
||||||
addVec3(scaleVec3(p2, 4), scaleVec3(p3, -1))
|
|
||||||
),
|
|
||||||
t2
|
|
||||||
),
|
|
||||||
scaleVec3(
|
|
||||||
addVec3(
|
|
||||||
addVec3(scaleVec3(p0, -1), scaleVec3(p1, 3)),
|
|
||||||
addVec3(scaleVec3(p2, -3), p3)
|
|
||||||
),
|
|
||||||
t3
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
0.5
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function evaluateCatmullRomTangent(
|
const refined: Vec3[] = [];
|
||||||
p0: Vec3,
|
|
||||||
p1: Vec3,
|
|
||||||
p2: Vec3,
|
|
||||||
p3: Vec3,
|
|
||||||
t: number
|
|
||||||
): Vec3 {
|
|
||||||
const t2 = t * t;
|
|
||||||
|
|
||||||
return normalizeDelta(
|
if (path.loop) {
|
||||||
scaleVec3(
|
for (let pointIndex = 0; pointIndex < points.length; pointIndex += 1) {
|
||||||
addVec3(
|
const start = points[pointIndex]!;
|
||||||
subtractVec3(p2, p0),
|
const end = points[(pointIndex + 1) % points.length]!;
|
||||||
addVec3(
|
|
||||||
scaleVec3(
|
refined.push(lerpVec3(start, end, 0.25));
|
||||||
addVec3(
|
refined.push(lerpVec3(start, end, 0.75));
|
||||||
addVec3(scaleVec3(p0, 4), scaleVec3(p1, -10)),
|
}
|
||||||
addVec3(scaleVec3(p2, 8), scaleVec3(p3, -2))
|
} else {
|
||||||
),
|
refined.push(cloneVec3(points[0]!));
|
||||||
t
|
|
||||||
),
|
for (let pointIndex = 0; pointIndex < points.length - 1; pointIndex += 1) {
|
||||||
scaleVec3(
|
const start = points[pointIndex]!;
|
||||||
addVec3(
|
const end = points[pointIndex + 1]!;
|
||||||
addVec3(scaleVec3(p0, -3), scaleVec3(p1, 9)),
|
|
||||||
addVec3(scaleVec3(p2, -9), scaleVec3(p3, 3))
|
refined.push(lerpVec3(start, end, 0.25));
|
||||||
),
|
refined.push(lerpVec3(start, end, 0.75));
|
||||||
t2
|
}
|
||||||
)
|
|
||||||
)
|
refined.push(cloneVec3(points[points.length - 1]!));
|
||||||
),
|
}
|
||||||
0.5
|
|
||||||
)
|
points = refined;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSmoothedPathSamples(path: ResolvedPathLike): SmoothedPathSample[] {
|
function buildSmoothedPathSamples(path: ResolvedPathLike): SmoothedPathSample[] {
|
||||||
@@ -358,36 +305,34 @@ function buildSmoothedPathSamples(path: ResolvedPathLike): SmoothedPathSample[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
const samples: SmoothedPathSample[] = [];
|
const samples: SmoothedPathSample[] = [];
|
||||||
const segmentCount = path.loop ? path.points.length : path.points.length - 1;
|
const points = buildSmoothedPolylinePoints(path);
|
||||||
|
const segmentCount = path.loop ? points.length : points.length - 1;
|
||||||
let cumulativeDistance = 0;
|
let cumulativeDistance = 0;
|
||||||
let previousPosition: Vec3 | null = null;
|
let previousPosition = cloneVec3(points[0]!);
|
||||||
|
|
||||||
|
samples.push({
|
||||||
|
distance: 0,
|
||||||
|
position: previousPosition,
|
||||||
|
tangent: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (let segmentIndex = 0; segmentIndex < segmentCount; segmentIndex += 1) {
|
for (let segmentIndex = 0; segmentIndex < segmentCount; segmentIndex += 1) {
|
||||||
const p0 = getPathSamplePoint(path, segmentIndex - 1);
|
const nextPosition = cloneVec3(
|
||||||
const p1 = getPathSamplePoint(path, segmentIndex);
|
points[(segmentIndex + 1) % points.length]!
|
||||||
const p2 = getPathSamplePoint(path, segmentIndex + 1);
|
);
|
||||||
const p3 = getPathSamplePoint(path, segmentIndex + 2);
|
cumulativeDistance += getVec3Distance(previousPosition, nextPosition);
|
||||||
|
|
||||||
for (
|
samples.push({
|
||||||
let subdivisionIndex = segmentIndex === 0 ? 0 : 1;
|
distance: cumulativeDistance,
|
||||||
subdivisionIndex <= SMOOTH_PATH_SEGMENT_SUBDIVISIONS;
|
position: nextPosition,
|
||||||
subdivisionIndex += 1
|
tangent: normalizeDelta(subtractVec3(nextPosition, previousPosition))
|
||||||
) {
|
});
|
||||||
const t = subdivisionIndex / SMOOTH_PATH_SEGMENT_SUBDIVISIONS;
|
|
||||||
const position = evaluateCatmullRomPosition(p0, p1, p2, p3, t);
|
|
||||||
const tangent = evaluateCatmullRomTangent(p0, p1, p2, p3, t);
|
|
||||||
|
|
||||||
if (previousPosition !== null) {
|
previousPosition = nextPosition;
|
||||||
cumulativeDistance += getVec3Distance(previousPosition, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
samples.push({
|
|
||||||
distance: cumulativeDistance,
|
|
||||||
position,
|
|
||||||
tangent
|
|
||||||
});
|
|
||||||
previousPosition = position;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return samples;
|
return samples;
|
||||||
|
|||||||
Reference in New Issue
Block a user