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:
@@ -101,12 +101,20 @@ export class Input {
|
||||
}
|
||||
pick(sample, rect) {
|
||||
const b = cameraBasis(this.host.camera.yaw, this.host.camera.pitch);
|
||||
return this.host
|
||||
const hit = this.host
|
||||
.engine()
|
||||
.bvh.raycast(
|
||||
add(this.world(sample, rect), mul(b.forward, 24)),
|
||||
mul(b.forward, -1),
|
||||
);
|
||||
if (!hit) return null;
|
||||
const engine = this.host.engine();
|
||||
const piece = engine.mesh.pieces?.find((p) => p.id === engine.activeId);
|
||||
return piece &&
|
||||
hit.face * 3 >= piece.indexStart &&
|
||||
hit.face * 3 < piece.indexStart + piece.indexCount
|
||||
? hit
|
||||
: null;
|
||||
}
|
||||
down(e) {
|
||||
if (this.rejectsTouch(e)) return;
|
||||
@@ -176,7 +184,10 @@ export class Input {
|
||||
canvas,
|
||||
};
|
||||
if (this.active.mode === "sculpt") {
|
||||
const settings = { ...this.host.settings };
|
||||
const settings = {
|
||||
...this.host.settings,
|
||||
activeId: this.host.engine().activeId,
|
||||
};
|
||||
if (e.shiftKey) settings.brush = "smooth";
|
||||
if (e.altKey) settings.invert = !settings.invert;
|
||||
const engine = this.host.engine(),
|
||||
@@ -193,6 +204,8 @@ export class Input {
|
||||
.begin(
|
||||
{
|
||||
positions: engine.mesh.positions.slice(),
|
||||
masks: engine.mesh.masks.slice(),
|
||||
activeId: engine.activeId,
|
||||
settings,
|
||||
camera: structuredClone(this.host.camera),
|
||||
rect: {
|
||||
@@ -208,7 +221,17 @@ export class Input {
|
||||
this.checkViewport();
|
||||
if (this.transaction !== transaction || transaction.canceling)
|
||||
return;
|
||||
const { vertices, rows, touched } = packet;
|
||||
const { vertices, masks, rows, touched } = packet;
|
||||
if (packet.type === "mask") {
|
||||
rows.forEach((v, i) => {
|
||||
engine.mesh.masks[v] = masks[i];
|
||||
engine.dirty.add(v);
|
||||
});
|
||||
for (const v of touched) engine.stroke.touched.add(v);
|
||||
engine.revision++;
|
||||
this.host.invalidate();
|
||||
return;
|
||||
}
|
||||
for (let row = 0; row < rows.length; row++) {
|
||||
const v = rows[row],
|
||||
i = row * 8,
|
||||
@@ -357,7 +380,8 @@ export class Input {
|
||||
this.host.invalidate();
|
||||
} else {
|
||||
// Repair main's face-normal cache and picking BVH only at the boundary.
|
||||
engine.changed([...engine.stroke.touched]);
|
||||
if (engine.stroke.settings.brush !== "mask")
|
||||
engine.changed([...engine.stroke.touched]);
|
||||
engine.end();
|
||||
this.host.committed();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user