Skip to content

Commit ab0a001

Browse files
committed
fix: planeNormal used to aligned floddfill and brush was wrong if the local coord space was not aligned with the global (e.g. x and z inverted for example, which is common).
1 parent a27b7ed commit ab0a001

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/layer/vox/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { TrackableValue, WatchableValue } from "#src/trackable_value.js";
3939
import type { UserLayerWithAnnotations } from "#src/ui/annotations.js";
4040
import { randomUint64 } from "#src/util/bigint.js";
4141
import { RefCounted } from "#src/util/disposable.js";
42+
import { vec3 } from "#src/util/geom.js";
4243
import {
4344
parseUint64,
4445
verifyFiniteFloat,
@@ -141,6 +142,29 @@ export class VoxelEditingContext
141142
if (!ok) return undefined;
142143
return this.cachedVoxelPosition;
143144
}
145+
146+
transformGlobalToVoxelNormal(globalNormal: vec3): vec3 {
147+
const chunkTransform = this.cachedChunkTransform;
148+
if (chunkTransform === undefined)
149+
throw new Error("Chunk transform not computed");
150+
const { modelTransform, layerToChunkTransform, layerRank } = chunkTransform;
151+
const { globalToRenderLayerDimensions } = modelTransform;
152+
const globalRank = globalToRenderLayerDimensions.length;
153+
const voxelNormal = vec3.create();
154+
155+
for (let chunkDim = 0; chunkDim < 3; ++chunkDim) {
156+
let sum = 0;
157+
for (let globalDim = 0; globalDim < Math.min(globalRank, 3); ++globalDim) {
158+
const layerDim = globalToRenderLayerDimensions[globalDim];
159+
if (layerDim !== -1) {
160+
sum += layerToChunkTransform[chunkDim + layerDim * (layerRank + 1)] * globalNormal[globalDim];
161+
}
162+
}
163+
voxelNormal[chunkDim] = sum;
164+
}
165+
vec3.normalize(voxelNormal, voxelNormal);
166+
return voxelNormal;
167+
}
144168
}
145169

146170
export declare abstract class UserLayerWithVoxelEditing extends UserLayer {

src/ui/voxel_annotations.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ abstract class BaseVoxelTool extends LayerTool<UserLayerWithVoxelEditing> {
4848
| Float32Array
4949
| undefined;
5050
if (!mouseState?.active || !vox) return undefined;
51-
const planeNormal = mouseState?.planeNormal;
51+
if(!mouseState.planeNormal) return;
52+
const planeNormal = editContext.transformGlobalToVoxelNormal(mouseState.planeNormal);
5253
if (!mouseState?.active || !vox || !planeNormal) return undefined;
5354
const CHUNK_POSITION_EPSILON = 1e-3;
5455
const shiftedVox = new Float32Array(3);
@@ -288,10 +289,14 @@ export class VoxelBrushTool extends BaseVoxelTool {
288289
1,
289290
Math.floor(this.layer.voxBrushRadius.value ?? 3),
290291
);
292+
const editContext = this.getEditingContext();
293+
if (editContext === undefined) {
294+
throw new Error("editContext is undefined");
295+
}
291296
const shapeEnum = this.layer.voxBrushShape.value;
292297
let basis = undefined as undefined | { u: Float32Array; v: Float32Array };
293298
if (shapeEnum === BrushShape.DISK && this.currentMouseState?.planeNormal) {
294-
const n = this.currentMouseState.planeNormal;
299+
const n = editContext.transformGlobalToVoxelNormal(this.currentMouseState.planeNormal);
295300
const u = vec3.create();
296301
const tempVec =
297302
Math.abs(vec3.dot(n, vec3.fromValues(1, 0, 0))) < 0.9
@@ -304,10 +309,7 @@ export class VoxelBrushTool extends BaseVoxelTool {
304309
basis = { u, v };
305310
}
306311

307-
const editContext = this.getEditingContext();
308-
if (editContext === undefined) {
309-
throw new Error("editContext is undefined");
310-
}
312+
311313
for (const p of points)
312314
editContext.controller?.paintBrushWithShape(
313315
p,
@@ -361,7 +363,8 @@ export class VoxelFloodFillTool extends BaseVoxelTool {
361363
return;
362364
}
363365
const seed = this.getPoint(this.mouseState);
364-
const planeNormal = this.mouseState.planeNormal;
366+
if(!this.mouseState.planeNormal) return;
367+
const planeNormal = editContext.transformGlobalToVoxelNormal(this.mouseState.planeNormal);
365368
if (!seed || !planeNormal) return;
366369
try {
367370
const value = this.layer.getVoxelPaintValue(

0 commit comments

Comments
 (0)