@lark-apaas/coding-steering 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,717 @@
1
+ # React Three Fiber Geometry
2
+
3
+ ## Quick Start
4
+
5
+ ```tsx
6
+ import { Canvas } from '@react-three/fiber'
7
+
8
+ function Scene() {
9
+ return (
10
+ <Canvas>
11
+ <ambientLight />
12
+ <mesh position={[0, 0, 0]}>
13
+ <boxGeometry args={[1, 1, 1]} />
14
+ <meshStandardMaterial color="hotpink" />
15
+ </mesh>
16
+ </Canvas>
17
+ )
18
+ }
19
+ ```
20
+
21
+ ## Built-in Geometries
22
+
23
+ All Three.js geometries are available as JSX elements. The `args` prop passes constructor arguments.
24
+
25
+ ### Basic Shapes
26
+
27
+ ```tsx
28
+ // BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)
29
+ <boxGeometry args={[1, 1, 1]} />
30
+ <boxGeometry args={[2, 1, 0.5, 2, 2, 2]} />
31
+
32
+ // SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength)
33
+ <sphereGeometry args={[1, 32, 32]} />
34
+ <sphereGeometry args={[1, 64, 64]} /> // High quality
35
+ <sphereGeometry args={[1, 32, 32, 0, Math.PI]} /> // Hemisphere
36
+
37
+ // PlaneGeometry(width, height, widthSegments, heightSegments)
38
+ <planeGeometry args={[10, 10]} />
39
+ <planeGeometry args={[10, 10, 32, 32]} /> // Subdivided for displacement
40
+
41
+ // CircleGeometry(radius, segments, thetaStart, thetaLength)
42
+ <circleGeometry args={[1, 32]} />
43
+ <circleGeometry args={[1, 32, 0, Math.PI]} /> // Semicircle
44
+
45
+ // CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded)
46
+ <cylinderGeometry args={[1, 1, 2, 32]} />
47
+ <cylinderGeometry args={[0, 1, 2, 32]} /> // Cone
48
+ <cylinderGeometry args={[1, 1, 2, 6]} /> // Hexagonal prism
49
+
50
+ // ConeGeometry(radius, height, radialSegments, heightSegments, openEnded)
51
+ <coneGeometry args={[1, 2, 32]} />
52
+
53
+ // TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)
54
+ <torusGeometry args={[1, 0.4, 16, 100]} />
55
+
56
+ // TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q)
57
+ <torusKnotGeometry args={[1, 0.4, 100, 16, 2, 3]} />
58
+
59
+ // RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments)
60
+ <ringGeometry args={[0.5, 1, 32]} />
61
+ ```
62
+
63
+ ### Advanced Shapes
64
+
65
+ ```tsx
66
+ // CapsuleGeometry(radius, length, capSegments, radialSegments)
67
+ <capsuleGeometry args={[0.5, 1, 4, 16]} />
68
+
69
+ // Polyhedrons
70
+ <dodecahedronGeometry args={[1, 0]} /> // radius, detail
71
+ <icosahedronGeometry args={[1, 0]} />
72
+ <octahedronGeometry args={[1, 0]} />
73
+ <tetrahedronGeometry args={[1, 0]} />
74
+
75
+ // Higher detail = more subdivisions
76
+ <icosahedronGeometry args={[1, 4]} /> // Approximates sphere
77
+ ```
78
+
79
+ ### Path-Based Shapes
80
+
81
+ ```tsx
82
+ import * as THREE from 'three'
83
+
84
+ // LatheGeometry - revolve points around Y axis
85
+ function LatheShape() {
86
+ const points = [
87
+ new THREE.Vector2(0, 0),
88
+ new THREE.Vector2(0.5, 0),
89
+ new THREE.Vector2(0.5, 0.5),
90
+ new THREE.Vector2(0.3, 1),
91
+ new THREE.Vector2(0, 1),
92
+ ]
93
+
94
+ return (
95
+ <mesh>
96
+ <latheGeometry args={[points, 32]} />
97
+ <meshStandardMaterial color="gold" side={THREE.DoubleSide} />
98
+ </mesh>
99
+ )
100
+ }
101
+
102
+ // TubeGeometry - extrude along a curve
103
+ function TubeShape() {
104
+ const curve = new THREE.CatmullRomCurve3([
105
+ new THREE.Vector3(-2, 0, 0),
106
+ new THREE.Vector3(-1, 1, 0),
107
+ new THREE.Vector3(1, -1, 0),
108
+ new THREE.Vector3(2, 0, 0),
109
+ ])
110
+
111
+ return (
112
+ <mesh>
113
+ <tubeGeometry args={[curve, 64, 0.2, 8, false]} />
114
+ <meshStandardMaterial color="blue" />
115
+ </mesh>
116
+ )
117
+ }
118
+
119
+ // ExtrudeGeometry - extrude a 2D shape
120
+ function ExtrudedShape() {
121
+ const shape = new THREE.Shape()
122
+ shape.moveTo(0, 0)
123
+ shape.lineTo(1, 0)
124
+ shape.lineTo(1, 1)
125
+ shape.lineTo(0, 1)
126
+ shape.lineTo(0, 0)
127
+
128
+ const extrudeSettings = {
129
+ steps: 2,
130
+ depth: 0.5,
131
+ bevelEnabled: true,
132
+ bevelThickness: 0.1,
133
+ bevelSize: 0.1,
134
+ bevelSegments: 3,
135
+ }
136
+
137
+ return (
138
+ <mesh>
139
+ <extrudeGeometry args={[shape, extrudeSettings]} />
140
+ <meshStandardMaterial color="purple" />
141
+ </mesh>
142
+ )
143
+ }
144
+ ```
145
+
146
+ ## Drei Shape Helpers
147
+
148
+ @react-three/drei provides convenient shape components.
149
+
150
+ ```tsx
151
+ import {
152
+ Box, Sphere, Plane, Circle, Cylinder, Cone,
153
+ Torus, TorusKnot, Ring, Capsule, Dodecahedron,
154
+ Icosahedron, Octahedron, Tetrahedron, RoundedBox
155
+ } from '@react-three/drei'
156
+
157
+ function DreiShapes() {
158
+ return (
159
+ <>
160
+ {/* All shapes accept mesh props directly */}
161
+ <Box args={[1, 1, 1]} position={[-3, 0, 0]}>
162
+ <meshStandardMaterial color="red" />
163
+ </Box>
164
+
165
+ <Sphere args={[0.5, 32, 32]} position={[-1, 0, 0]}>
166
+ <meshStandardMaterial color="blue" />
167
+ </Sphere>
168
+
169
+ <Cylinder args={[0.5, 0.5, 1, 32]} position={[1, 0, 0]}>
170
+ <meshStandardMaterial color="green" />
171
+ </Cylinder>
172
+
173
+ {/* RoundedBox - box with rounded edges */}
174
+ <RoundedBox
175
+ args={[1, 1, 1]} // width, height, depth
176
+ radius={0.1} // border radius
177
+ smoothness={4} // smoothness of rounded edges
178
+ position={[3, 0, 0]}
179
+ >
180
+ <meshStandardMaterial color="orange" />
181
+ </RoundedBox>
182
+ </>
183
+ )
184
+ }
185
+ ```
186
+
187
+ ## Custom BufferGeometry
188
+
189
+ ### Basic Custom Geometry
190
+
191
+ ```tsx
192
+ import { useMemo, useRef } from 'react'
193
+ import * as THREE from 'three'
194
+
195
+ function CustomTriangle() {
196
+ const geometry = useMemo(() => {
197
+ const geo = new THREE.BufferGeometry()
198
+
199
+ // Vertices (3 floats per vertex: x, y, z)
200
+ const vertices = new Float32Array([
201
+ -1, -1, 0, // vertex 0
202
+ 1, -1, 0, // vertex 1
203
+ 0, 1, 0, // vertex 2
204
+ ])
205
+
206
+ // Normals (pointing toward camera)
207
+ const normals = new Float32Array([
208
+ 0, 0, 1,
209
+ 0, 0, 1,
210
+ 0, 0, 1,
211
+ ])
212
+
213
+ // UVs
214
+ const uvs = new Float32Array([
215
+ 0, 0,
216
+ 1, 0,
217
+ 0.5, 1,
218
+ ])
219
+
220
+ geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
221
+ geo.setAttribute('normal', new THREE.BufferAttribute(normals, 3))
222
+ geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
223
+
224
+ return geo
225
+ }, [])
226
+
227
+ return (
228
+ <mesh geometry={geometry}>
229
+ <meshStandardMaterial color="cyan" side={THREE.DoubleSide} />
230
+ </mesh>
231
+ )
232
+ }
233
+ ```
234
+
235
+ ### Indexed Geometry
236
+
237
+ ```tsx
238
+ function CustomQuad() {
239
+ const geometry = useMemo(() => {
240
+ const geo = new THREE.BufferGeometry()
241
+
242
+ // 4 vertices for a quad
243
+ const vertices = new Float32Array([
244
+ -1, -1, 0, // 0: bottom-left
245
+ 1, -1, 0, // 1: bottom-right
246
+ 1, 1, 0, // 2: top-right
247
+ -1, 1, 0, // 3: top-left
248
+ ])
249
+
250
+ // Indices to form 2 triangles
251
+ const indices = new Uint16Array([
252
+ 0, 1, 2, // triangle 1
253
+ 0, 2, 3, // triangle 2
254
+ ])
255
+
256
+ const normals = new Float32Array([
257
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
258
+ ])
259
+
260
+ const uvs = new Float32Array([
261
+ 0, 0, 1, 0, 1, 1, 0, 1,
262
+ ])
263
+
264
+ geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
265
+ geo.setAttribute('normal', new THREE.BufferAttribute(normals, 3))
266
+ geo.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
267
+ geo.setIndex(new THREE.BufferAttribute(indices, 1))
268
+
269
+ return geo
270
+ }, [])
271
+
272
+ return (
273
+ <mesh geometry={geometry}>
274
+ <meshStandardMaterial color="lime" side={THREE.DoubleSide} />
275
+ </mesh>
276
+ )
277
+ }
278
+ ```
279
+
280
+ ### Dynamic Geometry
281
+
282
+ ```tsx
283
+ import { useRef } from 'react'
284
+ import { useFrame } from '@react-three/fiber'
285
+
286
+ function WavyPlane() {
287
+ const meshRef = useRef()
288
+
289
+ useFrame(({ clock }) => {
290
+ const positions = meshRef.current.geometry.attributes.position
291
+ const time = clock.elapsedTime
292
+
293
+ for (let i = 0; i < positions.count; i++) {
294
+ const x = positions.getX(i)
295
+ const y = positions.getY(i)
296
+ positions.setZ(i, Math.sin(x * 2 + time) * Math.cos(y * 2 + time) * 0.5)
297
+ }
298
+
299
+ positions.needsUpdate = true
300
+ meshRef.current.geometry.computeVertexNormals()
301
+ })
302
+
303
+ return (
304
+ <mesh ref={meshRef} rotation={[-Math.PI / 2, 0, 0]}>
305
+ <planeGeometry args={[10, 10, 32, 32]} />
306
+ <meshStandardMaterial color="royalblue" side={THREE.DoubleSide} />
307
+ </mesh>
308
+ )
309
+ }
310
+ ```
311
+
312
+ ## Drei Instancing
313
+
314
+ Efficient rendering of many identical objects.
315
+
316
+ ### Instances Component
317
+
318
+ ```tsx
319
+ import { Instances, Instance } from '@react-three/drei'
320
+ import { useFrame } from '@react-three/fiber'
321
+ import { useRef } from 'react'
322
+
323
+ function InstancedBoxes() {
324
+ const count = 1000
325
+
326
+ return (
327
+ <Instances limit={count} range={count}>
328
+ <boxGeometry args={[0.5, 0.5, 0.5]} />
329
+ <meshStandardMaterial />
330
+
331
+ {Array.from({ length: count }, (_, i) => (
332
+ <AnimatedInstance key={i} index={i} />
333
+ ))}
334
+ </Instances>
335
+ )
336
+ }
337
+
338
+ function AnimatedInstance({ index }) {
339
+ const ref = useRef()
340
+
341
+ // Random initial position
342
+ const position = useMemo(() => [
343
+ (Math.random() - 0.5) * 20,
344
+ (Math.random() - 0.5) * 20,
345
+ (Math.random() - 0.5) * 20,
346
+ ], [])
347
+
348
+ const color = useMemo(() =>
349
+ ['red', 'blue', 'green', 'yellow', 'purple'][index % 5],
350
+ [index])
351
+
352
+ useFrame(({ clock }) => {
353
+ const t = clock.elapsedTime
354
+ ref.current.rotation.x = t + index
355
+ ref.current.rotation.y = t * 0.5 + index
356
+ })
357
+
358
+ return (
359
+ <Instance
360
+ ref={ref}
361
+ position={position}
362
+ color={color}
363
+ scale={0.5 + Math.random() * 0.5}
364
+ />
365
+ )
366
+ }
367
+ ```
368
+
369
+ ### Merged Geometry
370
+
371
+ For static instances, merge geometry for best performance:
372
+
373
+ ```tsx
374
+ import { Merged } from '@react-three/drei'
375
+ import { useMemo } from 'react'
376
+ import * as THREE from 'three'
377
+
378
+ function MergedMeshes() {
379
+ // Create geometries to merge
380
+ const meshes = useMemo(() => ({
381
+ Sphere: new THREE.SphereGeometry(0.5, 32, 32),
382
+ Box: new THREE.BoxGeometry(1, 1, 1),
383
+ Cone: new THREE.ConeGeometry(0.5, 1, 32),
384
+ }), [])
385
+
386
+ return (
387
+ <Merged meshes={meshes}>
388
+ {({ Sphere, Box, Cone }) => (
389
+ <>
390
+ <Sphere position={[-2, 0, 0]} color="red" />
391
+ <Sphere position={[-2, 2, 0]} color="orange" />
392
+ <Box position={[0, 0, 0]} color="blue" />
393
+ <Box position={[0, 2, 0]} color="cyan" />
394
+ <Cone position={[2, 0, 0]} color="green" />
395
+ <Cone position={[2, 2, 0]} color="lime" />
396
+ </>
397
+ )}
398
+ </Merged>
399
+ )
400
+ }
401
+ ```
402
+
403
+ ## Points (Particle Systems)
404
+
405
+ ### Basic Points
406
+
407
+ ```tsx
408
+ import { Points, Point, PointMaterial } from '@react-three/drei'
409
+
410
+ function ParticleField() {
411
+ const count = 5000
412
+
413
+ return (
414
+ <Points limit={count}>
415
+ <PointMaterial
416
+ transparent
417
+ vertexColors
418
+ size={0.05}
419
+ sizeAttenuation
420
+ depthWrite={false}
421
+ />
422
+ {Array.from({ length: count }, (_, i) => (
423
+ <Point
424
+ key={i}
425
+ position={[
426
+ (Math.random() - 0.5) * 10,
427
+ (Math.random() - 0.5) * 10,
428
+ (Math.random() - 0.5) * 10,
429
+ ]}
430
+ color={`hsl(${Math.random() * 360}, 100%, 50%)`}
431
+ />
432
+ ))}
433
+ </Points>
434
+ )
435
+ }
436
+ ```
437
+
438
+ ### Buffer-Based Points (High Performance)
439
+
440
+ ```tsx
441
+ import { useMemo, useRef } from 'react'
442
+ import { useFrame } from '@react-three/fiber'
443
+ import * as THREE from 'three'
444
+
445
+ function BufferParticles() {
446
+ const count = 10000
447
+ const pointsRef = useRef()
448
+
449
+ const { positions, colors } = useMemo(() => {
450
+ const positions = new Float32Array(count * 3)
451
+ const colors = new Float32Array(count * 3)
452
+
453
+ for (let i = 0; i < count; i++) {
454
+ positions[i * 3] = (Math.random() - 0.5) * 10
455
+ positions[i * 3 + 1] = (Math.random() - 0.5) * 10
456
+ positions[i * 3 + 2] = (Math.random() - 0.5) * 10
457
+
458
+ colors[i * 3] = Math.random()
459
+ colors[i * 3 + 1] = Math.random()
460
+ colors[i * 3 + 2] = Math.random()
461
+ }
462
+
463
+ return { positions, colors }
464
+ }, [])
465
+
466
+ useFrame(({ clock }) => {
467
+ pointsRef.current.rotation.y = clock.elapsedTime * 0.1
468
+ })
469
+
470
+ return (
471
+ <points ref={pointsRef}>
472
+ <bufferGeometry>
473
+ <bufferAttribute
474
+ attach="attributes-position"
475
+ count={count}
476
+ array={positions}
477
+ itemSize={3}
478
+ />
479
+ <bufferAttribute
480
+ attach="attributes-color"
481
+ count={count}
482
+ array={colors}
483
+ itemSize={3}
484
+ />
485
+ </bufferGeometry>
486
+ <pointsMaterial size={0.05} vertexColors sizeAttenuation />
487
+ </points>
488
+ )
489
+ }
490
+ ```
491
+
492
+ ## Lines
493
+
494
+ ### Basic Line
495
+
496
+ ```tsx
497
+ import { Line } from '@react-three/drei'
498
+
499
+ function BasicLine() {
500
+ const points = [
501
+ [0, 0, 0],
502
+ [1, 1, 0],
503
+ [2, 0, 0],
504
+ [3, 1, 0],
505
+ ]
506
+
507
+ return (
508
+ <Line
509
+ points={points}
510
+ color="red"
511
+ lineWidth={2}
512
+ />
513
+ )
514
+ }
515
+ ```
516
+
517
+ ### Curved Line
518
+
519
+ ```tsx
520
+ import { CatmullRomLine, QuadraticBezierLine, CubicBezierLine } from '@react-three/drei'
521
+
522
+ function CurvedLines() {
523
+ return (
524
+ <>
525
+ {/* Smooth curve through points */}
526
+ <CatmullRomLine
527
+ points={[[0, 0, 0], [1, 1, 0], [2, 0, 0], [3, 1, 0]]}
528
+ color="blue"
529
+ lineWidth={2}
530
+ segments={64}
531
+ />
532
+
533
+ {/* Quadratic bezier */}
534
+ <QuadraticBezierLine
535
+ start={[0, 0, 0]}
536
+ mid={[1, 2, 0]}
537
+ end={[2, 0, 0]}
538
+ color="green"
539
+ lineWidth={2}
540
+ />
541
+
542
+ {/* Cubic bezier */}
543
+ <CubicBezierLine
544
+ start={[0, 0, 0]}
545
+ midA={[0.5, 2, 0]}
546
+ midB={[1.5, -1, 0]}
547
+ end={[2, 0, 0]}
548
+ color="purple"
549
+ lineWidth={2}
550
+ />
551
+ </>
552
+ )
553
+ }
554
+ ```
555
+
556
+ ### Dashed Line
557
+
558
+ ```tsx
559
+ <Line
560
+ points={[[0, 0, 0], [5, 0, 0]]}
561
+ color="white"
562
+ lineWidth={2}
563
+ dashed
564
+ dashScale={50}
565
+ dashSize={0.5}
566
+ dashOffset={0}
567
+ gapSize={0.2}
568
+ />
569
+ ```
570
+
571
+ ## Edges and Wireframe
572
+
573
+ ```tsx
574
+ import { Edges } from '@react-three/drei'
575
+
576
+ function BoxWithEdges() {
577
+ return (
578
+ <mesh>
579
+ <boxGeometry />
580
+ <meshStandardMaterial color="orange" />
581
+ <Edges
582
+ scale={1.1}
583
+ threshold={15} // Display edges with angle > 15 degrees
584
+ color="black"
585
+ />
586
+ </mesh>
587
+ )
588
+ }
589
+
590
+ // Wireframe material
591
+ function WireframeBox() {
592
+ return (
593
+ <mesh>
594
+ <boxGeometry />
595
+ <meshBasicMaterial color="cyan" wireframe />
596
+ </mesh>
597
+ )
598
+ }
599
+ ```
600
+
601
+ ## Text Geometry
602
+
603
+ ### Using Drei Text3D
604
+
605
+ ```tsx
606
+ import { Text3D, Center } from '@react-three/drei'
607
+
608
+ function Text3DExample() {
609
+ return (
610
+ <Center>
611
+ <Text3D
612
+ font="/fonts/helvetiker_regular.typeface.json"
613
+ size={1}
614
+ height={0.2}
615
+ curveSegments={12}
616
+ bevelEnabled
617
+ bevelThickness={0.02}
618
+ bevelSize={0.02}
619
+ bevelOffset={0}
620
+ bevelSegments={5}
621
+ >
622
+ Hello R3F
623
+ <meshStandardMaterial color="gold" />
624
+ </Text3D>
625
+ </Center>
626
+ )
627
+ }
628
+ ```
629
+
630
+ ## Geometry Utilities
631
+
632
+ ### Center Geometry
633
+
634
+ ```tsx
635
+ import { Center } from '@react-three/drei'
636
+
637
+ function CenteredModel() {
638
+ return (
639
+ <Center>
640
+ <mesh>
641
+ <boxGeometry args={[2, 1, 0.5]} />
642
+ <meshStandardMaterial />
643
+ </mesh>
644
+ </Center>
645
+ )
646
+ }
647
+
648
+ // With options
649
+ <Center top left> {/* Align to top-left */}
650
+ <Model />
651
+ </Center>
652
+
653
+ // Get bounding info
654
+ <Center onCentered={({ width, height, depth, boundingBox }) => {
655
+ console.log('Dimensions:', width, height, depth)
656
+ }}>
657
+ <Model />
658
+ </Center>
659
+ ```
660
+
661
+ ### Compute Bounds
662
+
663
+ ```tsx
664
+ import { useBounds, Bounds } from '@react-three/drei'
665
+
666
+ function FitToView() {
667
+ return (
668
+ <Bounds fit clip observe margin={1.2}>
669
+ <SelectToZoom />
670
+ </Bounds>
671
+ )
672
+ }
673
+
674
+ function SelectToZoom() {
675
+ const bounds = useBounds()
676
+
677
+ return (
678
+ <mesh
679
+ onClick={(e) => {
680
+ e.stopPropagation()
681
+ bounds.refresh(e.object).fit()
682
+ }}
683
+ >
684
+ <boxGeometry />
685
+ <meshStandardMaterial />
686
+ </mesh>
687
+ )
688
+ }
689
+ ```
690
+
691
+ ## Performance Tips
692
+
693
+ 1. **Reuse geometries**: Same geometry instance = better batching
694
+ 2. **Use Instances**: For many identical objects
695
+ 3. **Merge static meshes**: Use `<Merged>` for static scenes
696
+ 4. **Appropriate segment counts**: Balance quality vs performance
697
+ 5. **Dispose unused geometry**: R3F handles this automatically
698
+
699
+ ```tsx
700
+ // Good segment counts
701
+ <sphereGeometry args={[1, 32, 32]} /> // Standard quality
702
+ <sphereGeometry args={[1, 64, 64]} /> // High quality
703
+ <sphereGeometry args={[1, 16, 16]} /> // Performance mode
704
+
705
+ // Reuse geometry
706
+ const sharedGeometry = useMemo(() => new THREE.BoxGeometry(), [])
707
+
708
+ <mesh geometry={sharedGeometry} position={[0, 0, 0]} />
709
+ <mesh geometry={sharedGeometry} position={[2, 0, 0]} />
710
+ <mesh geometry={sharedGeometry} position={[4, 0, 0]} />
711
+ ```
712
+
713
+ ## See Also
714
+
715
+ - `r3f-fundamentals` - JSX elements and refs
716
+ - `r3f-materials` - Materials for meshes
717
+ - `r3f-shaders` - Custom vertex manipulation