Skip to content

Commit 4ca54c1

Browse files
authored
Merge pull request #20632 from gkjohnson/rounded-box-uvs
Fix RoundedBoxBufferGeometry UVs
2 parents 8142669 + 7e6649c commit 4ca54c1

File tree

1 file changed

+70
-12
lines changed

1 file changed

+70
-12
lines changed

examples/jsm/geometries/RoundedBoxBufferGeometry.js

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,40 @@ import {
33
Vector3
44
} from "../../../build/three.module.js";
55

6+
const tempNormal = new Vector3();
7+
function getUv( faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength ) {
8+
9+
const totArcLength = 2 * Math.PI * radius / 4;
10+
11+
// length of the planes between the arcs on each axis
12+
const centerLength = Math.max( sideLength - 2 * radius, 0 );
13+
const halfArc = Math.PI / 4;
14+
15+
// Get the vector projected onto the Y plane
16+
tempNormal.copy( normal );
17+
tempNormal[ projectionAxis ] = 0;
18+
tempNormal.normalize();
19+
20+
// total amount of UV space alloted to a single arc
21+
const arcUvRatio = 0.5 * totArcLength / ( totArcLength + centerLength );
22+
23+
// the distance along one arc the point is at
24+
const arcAngleRatio = 1.0 - ( tempNormal.angleTo( faceDirVector ) / halfArc );
25+
26+
if ( Math.sign( tempNormal[ uvAxis ] ) === 1 ) {
27+
28+
return arcAngleRatio * arcUvRatio;
29+
30+
} else {
31+
32+
// total amount of UV space alloted to the plane between the arcs
33+
const lenUv = centerLength / ( totArcLength + centerLength );
34+
return lenUv + arcUvRatio + arcUvRatio * ( 1.0 - arcAngleRatio );
35+
36+
}
37+
38+
}
39+
640
class RoundedBoxBufferGeometry extends BoxBufferGeometry {
741

842
constructor( width = 1, height = 1, depth = 1, segments = 1, radius = 1 ) {
@@ -28,6 +62,7 @@ class RoundedBoxBufferGeometry extends BoxBufferGeometry {
2862
const uvs = this.attributes.uv.array;
2963

3064
const faceTris = positions.length / 6;
65+
const faceDirVector = new Vector3();
3166

3267
for ( let i = 0, j = 0; i < positions.length; i += 3, j += 2 ) {
3368

@@ -47,28 +82,51 @@ class RoundedBoxBufferGeometry extends BoxBufferGeometry {
4782
switch ( side ) {
4883

4984
case 0: // right
50-
uvs[ j + 0 ] = 0.5 - ( positions[ i + 2 ] / ( depth - radius ) );
51-
uvs[ j + 1 ] = 0.5 + ( positions[ i + 1 ] / ( height - radius ) );
85+
86+
// generate UVs along Z then Y
87+
faceDirVector.set( 1, 0, 0 );
88+
uvs[ j + 0 ] = getUv( faceDirVector, normal, 'z', 'y', radius, depth );
89+
uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
5290
break;
91+
5392
case 1: // left
54-
uvs[ j + 0 ] = 0.5 + ( positions[ i + 2 ] / ( depth - radius ) );
55-
uvs[ j + 1 ] = 0.5 + ( positions[ i + 1 ] / ( height - radius ) );
93+
94+
// generate UVs along Z then Y
95+
faceDirVector.set( - 1, 0, 0 );
96+
uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'y', radius, depth );
97+
uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'z', radius, height );
5698
break;
99+
57100
case 2: // top
58-
uvs[ j + 0 ] = 0.5 + ( positions[ i + 0 ] / ( width - radius ) );
59-
uvs[ j + 1 ] = 0.5 - ( positions[ i + 2 ] / ( depth - radius ) );
101+
102+
// generate UVs along X then Z
103+
faceDirVector.set( 0, 1, 0 );
104+
uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
105+
uvs[ j + 1 ] = getUv( faceDirVector, normal, 'z', 'x', radius, depth );
60106
break;
107+
61108
case 3: // bottom
62-
uvs[ j + 0 ] = 0.5 + ( positions[ i + 0 ] / ( width - radius ) );
63-
uvs[ j + 1 ] = 0.5 + ( positions[ i + 2 ] / ( depth - radius ) );
109+
110+
// generate UVs along X then Z
111+
faceDirVector.set( 0, -1, 0 );
112+
uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'z', radius, width );
113+
uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'z', 'x', radius, depth );
64114
break;
115+
65116
case 4: // front
66-
uvs[ j + 0 ] = 0.5 + ( positions[ i + 0 ] / ( width - radius ) );
67-
uvs[ j + 1 ] = 0.5 + ( positions[ i + 1 ] / ( height - radius ) );
117+
118+
// generate UVs along X then Y
119+
faceDirVector.set( 0, 0, 1 );
120+
uvs[ j + 0 ] = 1.0 - getUv( faceDirVector, normal, 'x', 'y', radius, width );
121+
uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
68122
break;
123+
69124
case 5: // back
70-
uvs[ j + 0 ] = 0.5 - ( positions[ i + 0 ] / ( width - radius ) );
71-
uvs[ j + 1 ] = 0.5 + ( positions[ i + 1 ] / ( height - radius ) );
125+
126+
// generate UVs along X then Y
127+
faceDirVector.set( 0, 0, - 1 );
128+
uvs[ j + 0 ] = getUv( faceDirVector, normal, 'x', 'y', radius, width );
129+
uvs[ j + 1 ] = 1.0 - getUv( faceDirVector, normal, 'y', 'x', radius, height );
72130
break;
73131

74132
}

0 commit comments

Comments
 (0)