Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -1115,6 +1115,72 @@ function GridCalibrationHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Applies axis-aligned clipping planes (X / Y / Z) to every mesh inside the
|
||||
* registered model groups. Listens to the section state in the store; when
|
||||
* all axes are off, restores empty clipping arrays so meshes render whole. */
|
||||
function SectionClippingApplier() {
|
||||
const enabled = useModelStore((s) => s.sectionEnabled);
|
||||
const invert = useModelStore((s) => s.sectionInvert);
|
||||
const level = useModelStore((s) => s.sectionLevel);
|
||||
|
||||
const planes = useMemo(() => ({
|
||||
x: new THREE.Plane(new THREE.Vector3(1, 0, 0), 0),
|
||||
y: new THREE.Plane(new THREE.Vector3(0, 1, 0), 0),
|
||||
z: new THREE.Plane(new THREE.Vector3(0, 0, 1), 0),
|
||||
}), []);
|
||||
|
||||
useEffect(() => {
|
||||
// Configure each plane: keep the half-space on the positive side of the
|
||||
// normal. Inverting flips the normal direction.
|
||||
(['x', 'y', 'z'] as const).forEach((axis) => {
|
||||
const plane = planes[axis];
|
||||
const sign = invert[axis] ? -1 : 1;
|
||||
plane.normal.set(
|
||||
axis === 'x' ? sign : 0,
|
||||
axis === 'y' ? sign : 0,
|
||||
axis === 'z' ? sign : 0,
|
||||
);
|
||||
// For plane equation n·p + d = 0, keeping `n·p >= level*sign_axis` means
|
||||
// d = -level when normal is +axis, d = +level when normal is -axis.
|
||||
plane.constant = -sign * level[axis];
|
||||
});
|
||||
|
||||
const active: THREE.Plane[] = [];
|
||||
if (enabled.x) active.push(planes.x);
|
||||
if (enabled.y) active.push(planes.y);
|
||||
if (enabled.z) active.push(planes.z);
|
||||
|
||||
const groups = getAllModelLocalGroups();
|
||||
const touched: THREE.Material[] = [];
|
||||
const apply = (clipping: THREE.Plane[]) => {
|
||||
for (const g of groups) {
|
||||
g.traverse((obj) => {
|
||||
if (!(obj instanceof THREE.Mesh)) return;
|
||||
const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
|
||||
for (const mat of mats) {
|
||||
if (!mat) continue;
|
||||
mat.clippingPlanes = clipping;
|
||||
mat.clipShadows = true;
|
||||
mat.needsUpdate = true;
|
||||
touched.push(mat);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
apply(active);
|
||||
|
||||
return () => {
|
||||
// Cleanup: clear clipping from any material we touched.
|
||||
for (const mat of touched) {
|
||||
mat.clippingPlanes = [];
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
};
|
||||
}, [enabled.x, enabled.y, enabled.z, invert.x, invert.y, invert.z, level.x, level.y, level.z, planes]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Mouse drag handler for desktop "Posicionar" mode: translates/rotates the active model. */
|
||||
function PositionDragHandler() {
|
||||
const { camera, gl, scene } = useThree();
|
||||
|
||||
Reference in New Issue
Block a user