Add clay pieces, masking, and topology editing to sculpt
Add pastel presets, piece selection and colors, mask brushes, subdivision and conservative decimation with bounded worker operations and mixed undo history. Amp-Thread-ID: https://ampcode.com/threads/T-01a0b4b4-202c-73f1-984d-9a55c88f9c83 Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
This commit is contained in:
@@ -115,6 +115,48 @@ function setup(settings = {}, sample = { x: 400, y: 300, pressure: 0.7 }) {
|
||||
},
|
||||
};
|
||||
}
|
||||
test("mask packets are single-flight and canceled geometry is repaired before masking", () => {
|
||||
const { processor, mailbox, messages } = setup();
|
||||
// Cancel intentionally leaves provisional worker geometry.
|
||||
const before = processor.engine.mesh.positions.slice();
|
||||
processor.frame();
|
||||
assert.notDeepEqual(processor.engine.mesh.positions, before);
|
||||
processor.cancel(1);
|
||||
const sample = { x: 420, y: 290, pressure: 0.8 };
|
||||
const version = mailbox.write(2, sample);
|
||||
processor.begin({
|
||||
id: 2,
|
||||
version,
|
||||
sample,
|
||||
positions: before,
|
||||
settings: { ...defaults, brush: "mask", symmetry: false },
|
||||
camera: { yaw: 0, pitch: 0, zoom: 1.5, target: [0, 0, 0] },
|
||||
rect: { width: 800, height: 600 },
|
||||
hit: { position: [0, 0, 1], normal: [0, 0, 1] },
|
||||
});
|
||||
// Independently rebuild at the fixture's actual level.
|
||||
const fresh = new Sculpt(sphere(processor.engine.mesh.level));
|
||||
assert.deepEqual(processor.engine.mesh.positions, fresh.mesh.positions);
|
||||
assert.deepEqual(processor.engine.mesh.normals, fresh.mesh.normals);
|
||||
const start = messages.length;
|
||||
processor.frame();
|
||||
const packet = messages.at(-1);
|
||||
assert.equal(packet.type, "mask");
|
||||
const values = packet.masks.slice();
|
||||
const end = mailbox.write(2, { x: 450, y: 310, pressure: 0.9 });
|
||||
processor.end(2, end);
|
||||
processor.frame();
|
||||
assert.equal(messages.length, start + 1);
|
||||
assert.deepEqual(packet.masks, values);
|
||||
processor.acknowledge(packet.packet);
|
||||
processor.frame();
|
||||
const last = messages.at(-1);
|
||||
assert.equal(last.type, "mask");
|
||||
processor.acknowledge(last.packet);
|
||||
processor.frame();
|
||||
assert.equal(messages.at(-1).type, "complete");
|
||||
assert.deepEqual(processor.engine.mesh.positions, before);
|
||||
});
|
||||
test("latest frame target equals feeding only that target, intermediate samples create no hidden queue", () => {
|
||||
const a = setup(),
|
||||
b = setup();
|
||||
|
||||
Reference in New Issue
Block a user