Skip to content

Commit 7a6d471

Browse files
authored
Merge pull request #9271 from Srinidhi444/feat/keep-connections
feat: introduce KEEP_CONNECTIONS and deprecate FLAT
2 parents f694279 + fa23b18 commit 7a6d471

3 files changed

Lines changed: 88 additions & 12 deletions

File tree

‎src/core/constants.js‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,12 +1131,22 @@ export const CLAMP = 'clamp';
11311131
export const MIRROR = 'mirror';
11321132

11331133
// WEBGL GEOMETRY SHADING
1134+
1135+
/**
1136+
* @typedef {'keep_connections'} KEEP_CONNECTIONS
1137+
* @property {KEEP_CONNECTIONS} KEEP_CONNECTIONS
1138+
* @final
1139+
*/
1140+
export const KEEP_CONNECTIONS = 'keep_connections';
1141+
11341142
/**
1135-
* @typedef {'flat'} FLAT
1143+
* @typedef {'keep_connections'} FLAT
11361144
* @property {FLAT} FLAT
11371145
* @final
1146+
* @deprecated Use `KEEP_CONNECTIONS` instead. May be removed in p5.js 3.0.
11381147
*/
1139-
export const FLAT = 'flat';
1148+
export const FLAT = KEEP_CONNECTIONS;
1149+
11401150
/**
11411151
* @typedef {'smooth'} SMOOTH
11421152
* @property {SMOOTH} SMOOTH

‎src/webgl/p5.Geometry.js‎

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -919,20 +919,28 @@ class Geometry {
919919
* <a href="#/p5.Geometry/vertexNormals">myGeometry.vertexNormals</a> array.
920920
*
921921
* The first parameter, `shadingType`, is optional. Passing the constant
922-
* `FLAT`, as in `myGeometry.computeNormals(FLAT)`, provides neighboring
923-
* faces with their own copies of the vertices they share. Surfaces appear
924-
* tiled with flat shading. Passing the constant `SMOOTH`, as in
925-
* `myGeometry.computeNormals(SMOOTH)`, makes neighboring faces reuse their
926-
* shared vertices. Surfaces appear smoother with smooth shading. By
927-
* default, `shadingType` is `FLAT`.
922+
* `KEEP_CONNECTIONS`, as in `myGeometry.computeNormals(KEEP_CONNECTIONS)`,
923+
* preserves the geometry's existing vertex connections. Each vertex normal
924+
* is calculated by averaging the face normals of its connected faces.
925+
* This may produce smooth transitions between connected faces rather
926+
* than true flat shading.
927+
*
928+
* Passing the constant `SMOOTH`, as in
929+
* `myGeometry.computeNormals(SMOOTH)`, calculates smooth normals by
930+
* grouping vertices with approximately matching positions, without
931+
* modifying the original vertices or their attributes.
932+
*
933+
* The constant `FLAT` is deprecated and behaves identically to
934+
* `KEEP_CONNECTIONS`. It is retained for backward compatibility.
935+
* By default, `shadingType` is `KEEP_CONNECTIONS`.
928936
*
929937
* The second parameter, `options`, is also optional. If an object with a
930938
* `roundToPrecision` property is passed, as in
931939
* `myGeometry.computeNormals(SMOOTH, { roundToPrecision: 5 })`, it sets the
932940
* number of decimal places to use for calculations. By default,
933941
* `roundToPrecision` uses 3 decimal places.
934942
*
935-
* @param {(FLAT|SMOOTH)} [shadingType=FLAT] shading type. either FLAT or SMOOTH. Defaults to `FLAT`.
943+
* @param {(KEEP_CONNECTIONS|SMOOTH)} [shadingType=KEEP_CONNECTIONS] shading type. Defaults to `KEEP_CONNECTIONS`.
936944
* @param {Object} [options] shading options.
937945
* @chainable
938946
*
@@ -1055,8 +1063,8 @@ class Geometry {
10551063
* // Create a p5.Geometry object.
10561064
* myGeometry = buildGeometry(createShape);
10571065
*
1058-
* // Compute normals using default (FLAT) shading.
1059-
* myGeometry.computeNormals(FLAT);
1066+
* // Compute normals while preserving existing vertex connections.
1067+
* myGeometry.computeNormals(KEEP_CONNECTIONS);
10601068
*
10611069
* describe('A white, helical structure drawn on a dark gray background. Its faces appear faceted.');
10621070
* }
@@ -1191,7 +1199,7 @@ class Geometry {
11911199
* endShape();
11921200
* }
11931201
*/
1194-
computeNormals(shadingType = constants.FLAT, { roundToPrecision = 3 } = {}) {
1202+
computeNormals(shadingType = constants.KEEP_CONNECTIONS, { roundToPrecision = 3 } = {}) {
11951203
const vertexNormals = this.vertexNormals;
11961204
const vertices = this.vertices;
11971205
const faces = this.faces;

‎test/unit/webgl/p5.Geometry.js‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,64 @@ suite('p5.Geometry', function () {
4747
expect(geom.uvs).toEqual(originalUvs);
4848
expect(geom.vertexNormals[0]).toEqual(geom.vertexNormals[3]);
4949
});
50+
test('KEEP_CONNECTIONS preserves the existing FLAT behavior', function () {
51+
const createGeometry = () => {
52+
const geom = new p5.Geometry();
53+
54+
geom.vertices.push(
55+
myp5.createVector(0, 0, 0),
56+
myp5.createVector(1, 0, 0),
57+
myp5.createVector(0, 1, 0),
58+
myp5.createVector(0, 0, 1)
59+
);
60+
61+
geom.faces.push(
62+
[0, 1, 2],
63+
[0, 3, 1]
64+
);
65+
66+
return geom;
67+
};
68+
69+
const flatGeom = createGeometry();
70+
const keepConnectionsGeom = createGeometry();
71+
const defaultGeom = createGeometry();
72+
73+
flatGeom.computeNormals(myp5.FLAT);
74+
keepConnectionsGeom.computeNormals(myp5.KEEP_CONNECTIONS);
75+
defaultGeom.computeNormals();
76+
77+
// FLAT and KEEP_CONNECTIONS should produce identical normals.
78+
expect(flatGeom.vertexNormals).toEqual(
79+
keepConnectionsGeom.vertexNormals
80+
);
81+
82+
// Default behavior should match KEEP_CONNECTIONS.
83+
expect(defaultGeom.vertexNormals).toEqual(
84+
keepConnectionsGeom.vertexNormals
85+
);
86+
87+
// Vertex connections should remain unchanged.
88+
for (const geom of [flatGeom, keepConnectionsGeom, defaultGeom]) {
89+
expect(geom.vertices.length).toBe(4);
90+
expect(geom.faces).toEqual([
91+
[0, 1, 2],
92+
[0, 3, 1]
93+
]);
94+
expect(geom.vertexNormals.length).toBe(4);
95+
}
96+
97+
// Shared vertices should have averaged face normals.
98+
const expected = 1 / Math.sqrt(2);
99+
100+
for (const index of [0, 1]) {
101+
const normal = keepConnectionsGeom.vertexNormals[index];
102+
103+
expect(normal.x).toBeCloseTo(0, 5);
104+
expect(normal.y).toBeCloseTo(expected, 5);
105+
expect(normal.z).toBeCloseTo(expected, 5);
106+
}
107+
});
50108
});
51109

52110
suite('computeTangents', function () {

0 commit comments

Comments
 (0)