Setting the file. One moment.
Geometry · Frost Sequence Camera Orbit · heygen-com/hyperframes · Skills Docs
ContentsBack to the top of the page Three Mesh BVH LICENSE
source/src/shape/geometry.ts
source/src/shape/ geometry.ts
TypeScript · 164 lines · 5 KB
=
4
) {
8 const pos = geo.attributes.position as THREE . BufferAttribute ;
9 const nrm = new Float32Array (pos.count * 3 );
10 for ( let i = 0 ; i < pos.count; i ++ ) {
11 let x = pos. getX (i),
12 y = pos. getY (i),
13 z = pos. getZ (i);
14 for ( let k = 0 ; k < steps; k ++ ) {
15 const d = s. sdf (x, y, z);
16 const n = sdfNormal (s, x, y, z);
17 x -= n[ 0 ] * d;
18 y -= n[ 1 ] * d;
19 z -= n[ 2 ] * d;
20 }
21 const n = sdfNormal (s, x, y, z, 0.004 );
22 pos. setXYZ (i, x, y, z);
23 nrm[i * 3 ] = n[ 0 ];
24 nrm[i * 3 + 1 ] = n[ 1 ];
25 nrm[i * 3 + 2 ] = n[ 2 ];
26 }
27 pos.needsUpdate = true ;
28 geo. setAttribute ( "normal" , new THREE . BufferAttribute (nrm, 3 ));
29 return geo;
30 }
31
32 export function buildGeometry (
33 s : ShapeSpec ,
34 segments : number ,
35 logoGeometry ?: THREE . BufferGeometry ,
36 ) : THREE . BufferGeometry {
37 const R = s.size,
38 r = s.size * s.tubeRatio;
39 switch (s.name) {
40 case "torus" : {
41 const g = new THREE . TorusGeometry ( R , r, Math. max ( 24 , Math. round (segments * 0.4 )), segments);
42 // TorusGeometry lies in XY with the hole along Z — matches the sdf.
43 return g;
44 }
45 case "sphere" :
46 return projectOntoSDF (
47 new THREE . SphereGeometry ( 1 , segments, Math. round (segments * 0.6 )),
48 s,
49 2 ,
50 );
51 case "roundedBox" : {
52 const seg = Math. max ( 8 , Math. round (segments / 4 ));
53 const h = s.size * 0.92 ;
54 const g = new THREE . BoxGeometry (
55 2 * h,
56 2 * h,
57 2 * h * 0.55 ,
58 seg,
59 seg,
60 Math. max ( 4 , Math. round (seg * 0.55 )),
61 );
62 // pre-round: blend vertices toward a sphere before projecting so the corners get tessellation
63 const pos = g.attributes.position as THREE . BufferAttribute ;
64 for ( let i = 0 ; i < pos.count; i ++ ) {
65 const x = pos. getX (i),
66 y = pos. getY (i),
67 z = pos. getZ (i);
68 const l = Math. hypot (x, y, z) || 1 ;
69 const t = 0.35 ;
70 pos. setXYZ (
71 i,
72 x * ( 1 - t) + (x / l) * h * t,
73 y * ( 1 - t) + (y / l) * h * t,
74 z * ( 1 - t) + (z / l) * h * t,
75 );
76 }
77 return projectOntoSDF (g, s, 6 );
78 }
79 case "pyramid" : {
80 const g = new THREE . IcosahedronGeometry (s.size * 1.4 , 6 );
81 return projectOntoSDF (g, s, 8 );
82 }
83 case "icosahedron" : {
84 const g = new THREE . IcosahedronGeometry (s.size * 1.2 , 6 );
85 return projectOntoSDF (g, s, 6 );
86 }
87 case "logo" : {
88 const g = (logoGeometry ?? new THREE . TorusGeometry ( R , r, 64 , segments)). clone ();
89 if (logoGeometry)
90 g. scale (s.size, s.size, s.size); // normals are unaffected by a uniform scale
91 else g. computeVertexNormals ();
92 return g;
93 }
94 }
95 }
96
97 /** Small irregular grain meshes (lumpy icospheres and shards). */
98 export function buildGrainVariants (
99 count : number ,
100 rand : () => number ,
101 faceted = false ,
102 ) : THREE . BufferGeometry [] {
103 const out : THREE . BufferGeometry [] = [];
104 for ( let v = 0 ; v < count; v ++ ) {
105 if (faceted) {
106 out. push ( buildFacetedShard (v, rand));
107 continue ;
108 }
109 const shard = v % 3 === 2 ;
110 const g = shard
111 ? new THREE . TetrahedronGeometry ( 1 , 1 ) // 16 tris
112 : new THREE . IcosahedronGeometry ( 1 , v % 2 ); // 20 / 80 tris
113 const pos = g.attributes.position as THREE . BufferAttribute ;
114 const sx = 0.7 + rand () * 0.6 ,
115 sy = 0.7 + rand () * 0.6 ,
116 sz = shard ? 0.35 + rand () * 0.3 : 0.7 + rand () * 0.6 ;
117 const seed = rand () * 100 ;
118 for ( let i = 0 ; i < pos.count; i ++ ) {
119 const x = pos. getX (i),
120 y = pos. getY (i),
121 z = pos. getZ (i);
122 const l =
123 1 + 0.28 * Math. sin (seed + x * 5.1 + y * 3.7 ) * Math. cos (seed * 0.7 + z * 4.3 + x * 2.2 );
124 pos. setXYZ (i, x * l * sx, y * l * sy, z * l * sz);
125 }
126 g. computeVertexNormals ();
127 out. push (g);
128 }
129 return out;
130 }
131
132 /** Flat-shaded shard: a low-poly convex solid with per-vertex jitter and hard edges, so every face catches
133 * the key light separately (glass-splinter look). 8-20 tris, no more than the smooth variants. */
134 function buildFacetedShard ( v : number , rand : () => number ) : THREE . BufferGeometry {
135 const kind = v % 3 ;
136 const g =
137 kind === 0
138 ? new THREE . IcosahedronGeometry ( 1 , 0 )
139 : kind === 1
140 ? new THREE . OctahedronGeometry ( 1 , 0 )
141 : new THREE . TetrahedronGeometry ( 1 , 0 );
142 const pos = g.attributes.position as THREE . BufferAttribute ;
143 // elongated splinter proportions; one axis thin
144 const sx = 0.55 + rand () * 0.9 ,
145 sy = 0.55 + rand () * 0.9 ,
146 sz = 0.25 + rand () * 0.4 ;
147 // jitter shared per unique vertex position so the faces stay planar and closed
148 const jit = new Map < string , [ number , number , number ]>();
149 for ( let i = 0 ; i < pos.count; i ++ ) {
150 const x = pos. getX (i),
151 y = pos. getY (i),
152 z = pos. getZ (i);
153 const k = `${ x . toFixed ( 4 ) },${ y . toFixed ( 4 ) },${ z . toFixed ( 4 ) }` ;
154 let j = jit. get (k);
155 if ( ! j) {
156 j = [( rand () - 0.5 ) * 0.5 , ( rand () - 0.5 ) * 0.5 , ( rand () - 0.5 ) * 0.5 ];
157 jit. set (k, j);
158 }
159 pos. setXYZ (i, (x + j[ 0 ]) * sx, (y + j[ 1 ]) * sy, (z + j[ 2 ]) * sz);
160 }
161 const flat = g.index ? g. toNonIndexed () : g;
162 flat. computeVertexNormals ();
163 return flat;
164 }