-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added TriangleGeometry Class #29882
Added TriangleGeometry Class #29882
Conversation
New class to create triangular planes.
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
The height is now a literal value.
After giving it some thought, I can see how normalizing the height could be confusing. Height is now a literal unit and the UV maps to the base and apex of the geometry. |
Do you mind moving This kind of geometry generator has not been requested so far so I do not see it as a core module. |
Moved, as requested. For what it's worth, because a triangle is the most fundamental geometry, I (personally) would expect a triangle to be a primitive. Coupled with it being the only geometry that easily creates the Three JS logo, it seems like src/geometry/ is a better fit, but not a big deal either way. |
related: #29690 (comment) |
How about do this.
--- a/examples/jsm/geometries/TriangleGeometry.js
+++ b/examples/jsm/geometries/TriangleGeometry.js
@@ -3,17 +3,19 @@ import { Float32BufferAttribute } from '../core/BufferAttribute.js';
class TriangleGeometry extends BufferGeometry {
- constructor( width = 1, height = Math.sqrt( 3 ) / 2, skew = 0, detail = 0 ) {
+ constructor( width = 1, height = Math.sqrt( 3 ) / 2, skew = 0, segments = 1 ) {
super();
this.type = 'TriangleGeometry';
+ segments = Math.max( Math.floor( segments ), 1 );
+
this.parameters = {
width: width,
height: height,
skew: skew,
- detail: detail
+ segments: segments
};
// buffers
@@ -25,7 +27,6 @@ class TriangleGeometry extends BufferGeometry {
// vertex helper variables
- const segments = Math.max( Math.floor( detail + 1 ), 1 );
const offsetX = width / 2;
const offsetY = height / 3; |
|
I'm considering updating the class to minimize UV distortion. Is this closer to what you're expecting @linbingquan ? // vertex helper variables
+ const widthHalf = width / 2;
+ const skewHalf = skew / 2;
- const offsetX = width / 2;
+ const offsetX = ( width + widthHalf + skewHalf ) / 3;
const offsetY = height / 3;
+ const length = Math.max( Math.abs( skewHalf ) + widthHalf, width );
+ const maxU = Math.min( length / height, 1);
+ const maxV = Math.min( height / length, 1);
+ const offsetU = skew + width > 0 ? (1 - maxU) / 2 : (length - width) / length;
+ const offsetV = (1 - maxV) / 2;
// vertices, normals, and uvs
for ( let i = 0; i < segments + 1; i ++ ) {
for ( let j = 0; j < i + 1; j ++ ) {
- const uvX = ( i + j ) / segments / 2;
- const uvY = ( i - j ) / segments;
+ const normX = ( i + j ) / segments / 2;
+ const normY = ( i - j ) / segments;
- const x = uvX * width - offsetX + uvY * skew / 2;
- const y = uvY * height - offsetY;
+ const x = normX * width + normY * skewHalf;
+ const y = normY * height;
+ const u = maxU * x / length;
+ const v = maxV * normY;
- vertices.push( x, y, 0 );
+ vertices.push( x - offsetX, y - offsetY, 0 );
normals.push( 0, 0, 1 );
- uvs.push( uvX );
- uvs.push( uvY );
+ uvs.push( u + offsetU, v + offsetV );
}
} |
In both test cases, there was no problem with the results.
|
@Mugen87 - Anything else needed on my end? Would love to get this merged. |
Curious to hear about use cases for this geometry...? |
We've been a bit more strict when adding new modules to the repository compared to earlier days. With that policy in mind, I tend to place IMO, the existing geometry generators in the repository are more than sufficient. |
Completely understand (and appreciate) you both safeguarding the quality of Three JS. If this were my project, I would do the same. @mrdoob - I am currently using this in a project, which is how I noticed its absence. Specifically, I'm generating the base shape and programmatically manipulating the vertices, which allows me to instantiate game assets without having to model each. That aside, any planar example where 1 less vertex allows 25% more stuff (think grass, particle shards, billboards, etc.). This kind of efficiency is notable in procedural applications. Generating the library logo was more of a discovery than the intention. @Mugen87 - I agree the existing generators capture many applications. Three JS is awesome. I love it. Triangles are a primitive. The library doesn't have them. And I respect everyone's time enough to not waste it on a feature request I could do, allowing core contributors to focus on more important things. If triangles are something the library would like to consciously omit, please let me know. I'm trying to be helpful (not a nuisance). |
To be fair, currently any regular polygon can be generated, and then optionally transformed. const geometry = new THREE.CircleGeometry( 1, 3 ); // triangle
geometry.rotateZ( Math.PI / 2 );
geometry.translate( 0, 0.5, 0 );
geometry.scale( 10, 10, 1 ); |
Charitably, I take your point. Also, I would have hoped the context clarified I was talking about a generator akin to the one in this PR. |
@pxninja We do appreciate the contribution but it seems the consensus is to maintain such a generator not in this repository. I recommend you put |
Should anything change, the code is available. |
Description
I noticed Three JS primitives do not include a triangular plane. This PR adds that primitive with the following parameters: width, height, skew, and detail.
While the default parameters create an equilateral triangle, adjusting the width / height / skew will produce any type (isosceles, scalene, right, obtuse). Increasing the detail uniformly subdivides the plane, where "detail" is the number of edge divisions, and the number of facets per division is ( detail + 1 ) ^ 2.
Example of uniform subdivision (aka. what to expect):