docs: [bim-viewer] Phase 3 SAM Show Effects 20종 문서 추가
- Show Effects 아키텍처 (클로저 기반 update 패턴) - 헬퍼 메서드 (_mkItem, _mkFlash, _setOp, mkMix) - 20종 효과 목록 및 설명 - UI 구성 (드롭다운 + 재생 버튼) - 메모리 관리 (_cleanupShow) - 향후 계획 Phase 번호 업데이트
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# BIM 뷰어 — Three.js + web-ifc 기반 웹 3D BIM 뷰어
|
||||
|
||||
> **작성일**: 2026-03-12
|
||||
> **상태**: Phase 2 완료 (IFC 업로드 + 다운로드)
|
||||
> **상태**: Phase 3 완료 (SAM Show Effects 20종)
|
||||
> **소스**: `mng/resources/views/juil/bim-viewer.blade.php`
|
||||
|
||||
---
|
||||
@@ -23,6 +23,7 @@
|
||||
| **IFC 파일 업로드** | `.ifc` 파일 업로드 → 실제 BIM 모델 렌더링 | **Phase 2** |
|
||||
| **IFC 파일 다운로드** | 현재 모델을 IFC 파일로 내보내기 | **Phase 2** |
|
||||
| **드래그 앤 드롭** | IFC 파일을 뷰포트에 드래그하여 로드 | **Phase 2** |
|
||||
| **SAM Show Effects** | SAM/샘 텍스트 3D 애니메이션 20종 선택/재생 | **Phase 3** |
|
||||
|
||||
### 1.3 핵심 기술 스택
|
||||
|
||||
@@ -367,20 +368,177 @@ Three.js → React: bim.onSelect = setSelected (요소 선택 콜백)
|
||||
|
||||
| 파일 | 위치 | 설명 |
|
||||
|------|------|------|
|
||||
| `bim-viewer.blade.php` | `mng/resources/views/juil/` | BIM 뷰어 전체 (~900줄, Three.js + web-ifc + React) |
|
||||
| `bim-viewer.blade.php` | `mng/resources/views/juil/` | BIM 뷰어 전체 (~1300줄, Three.js + web-ifc + React + Show Effects) |
|
||||
| `PlanningController.php` | `mng/app/Http/Controllers/Juil/` | `bimViewer()` 메서드 |
|
||||
| `web.php` | `mng/routes/` | `GET /juil/construction-pmis/bim-viewer` |
|
||||
|
||||
---
|
||||
|
||||
## 9. 향후 계획 (Phase 3+)
|
||||
## 9. SAM Show Effects (Phase 3)
|
||||
|
||||
| Phase | 기능 | 기술 |
|
||||
|-------|------|------|
|
||||
| ~~Phase 1~~ | ~~데모 건물 + 3D 뷰어~~ | ~~Three.js r128~~ (완료) |
|
||||
| ~~Phase 2~~ | ~~IFC 업로드/다운로드 + 실제 BIM 렌더링~~ | ~~web-ifc 0.0.66~~ (완료) |
|
||||
| **Phase 3** | 요소 속성 패널 고도화, 2D 평면도 모드 | Three.js Orthographic Camera |
|
||||
| **Phase 4** | 모델 파일 관리, 버전 이력, 협력업체 조회 | Laravel API + DB |
|
||||
### 9.1 개요
|
||||
|
||||
BIM 뷰어에 SAM 브랜드 3D 애니메이션 효과 20종을 추가했다. 툴바 드롭다운에서 효과를 선택하고 재생 버튼을 누르면 3D 뷰포트 위에 "SAM"(3D TextGeometry)과 "샘"(Canvas Sprite) 텍스트가 다양한 패턴으로 애니메이션된다.
|
||||
|
||||
### 9.2 아키텍처
|
||||
|
||||
```
|
||||
사용자 → 드롭다운(sam1~sam20) 선택 → ▶ 재생 버튼
|
||||
↓
|
||||
playShow(id)
|
||||
↓ FontLoader로 3D 폰트 로드 (최초 1회)
|
||||
_initEffect(id)
|
||||
↓ switch(id): 20개 케이스
|
||||
↓ 각 케이스: items[] 생성 + update(s, elapsed) 클로저 정의
|
||||
↓
|
||||
this._show = { type, items, extras, startTime, duration, update }
|
||||
↓
|
||||
animate() 루프에서 _updateShow() 호출
|
||||
↓ s.update(s, elapsed) — 클로저가 애니메이션 계산
|
||||
↓ elapsed >= duration → _cleanupShow()
|
||||
↓
|
||||
_cleanupShow()
|
||||
↓ items[].geometry.dispose() + material.dispose()
|
||||
↓ extras[].geometry.dispose() + material.dispose()
|
||||
↓ scene.remove(item/extra)
|
||||
```
|
||||
|
||||
**핵심 설계 원칙**: 각 효과는 클로저 기반 `update` 함수로 자기 완결적이다. `_updateShow()`는 단순 디스패처로, `s.update(s, elapsed)`만 호출하고 시간 초과 시 `_cleanupShow()`를 호출한다.
|
||||
|
||||
### 9.3 헬퍼 메서드
|
||||
|
||||
| 메서드 | 역할 |
|
||||
|--------|------|
|
||||
| `_makeTextSprite(text, color, size)` | Canvas 2D로 한글 텍스트("샘") 스프라이트 생성 |
|
||||
| `_mkItem(text, color, size, pos)` | "SAM" → 3D TextGeometry, "샘" → Canvas Sprite 통합 생성 |
|
||||
| `_mkFlash(pos)` | 흰색 반투명 SphereGeometry (폭발/번쩍 효과용) |
|
||||
| `_setOp(item, value)` | 아이템 투명도 설정 (0~1 클램핑) |
|
||||
| `mkMix(n, sMin, sMax)` | SAM/샘 혼합 아이템 N개 일괄 생성 (효과 내부 헬퍼) |
|
||||
|
||||
### 9.4 아이템 생성 패턴
|
||||
|
||||
```javascript
|
||||
// 3D TextGeometry (영문 "SAM")
|
||||
const geo = new THREE.TextGeometry('SAM', { font, size, height:size*0.2 });
|
||||
const mat = new THREE.MeshPhongMaterial({ color, transparent:true, opacity:1 });
|
||||
const mesh = new THREE.Mesh(geo, mat);
|
||||
|
||||
// Canvas Sprite (한글 "샘")
|
||||
const canvas = document.createElement('canvas');
|
||||
ctx.fillText('샘', ...); // 한글 렌더링
|
||||
const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map:texture }));
|
||||
```
|
||||
|
||||
각 아이템에 `size`, `color`, `idx`, `targetPos`, `burstSpeed` 등 애니메이션용 커스텀 속성을 부착한다.
|
||||
|
||||
### 9.5 효과 목록 (20종)
|
||||
|
||||
| ID | 이름 | 설명 | 패턴 |
|
||||
|----|------|------|------|
|
||||
| 1 | Star Gathering | 사방에서 별처럼 모여 폭발 | gather → burst |
|
||||
| 2 | Spiral Galaxy | 은하 소용돌이 | 나선 회전 → 수축 |
|
||||
| 3 | Fireworks | 불꽃놀이 | 상승 → 방사 폭발 |
|
||||
| 4 | Matrix Rain | 매트릭스 문자비 | 상단에서 하강 |
|
||||
| 5 | DNA Helix | DNA 이중나선 | 쌍 나선 회전 |
|
||||
| 6 | Wormhole | 웜홀 통과 | 원형 터널 돌진 |
|
||||
| 7 | Constellation | 별자리 연결 | 점 배치 → 선 연결 |
|
||||
| 8 | Heartbeat | 심장 박동 | 하트 형태 펄스 |
|
||||
| 9 | Tornado | 토네이도 | 원뿔형 회전 상승 |
|
||||
| 10 | Domino Wave | 도미노 파동 | 순차 기울어짐 |
|
||||
| 11 | Gravity Well | 중력 우물 | 공전 → 흡입 |
|
||||
| 12 | Northern Lights | 오로라 커튼 | 수평 웨이브 컬러 변화 |
|
||||
| 13 | Clock Mechanism | 시계 톱니바퀴 | 동심원 역방향 회전 |
|
||||
| 14 | Particle Storm | 입자 폭풍 | 격렬한 랜덤 이동 |
|
||||
| 15 | Bloom Garden | 꽃 피어남 | 중심에서 방사 성장 |
|
||||
| 16 | Ocean Waves | 해양 파도 | 사인파 물결 |
|
||||
| 17 | Lightning Storm | 번개 | 번쩍 + 분산 |
|
||||
| 18 | Pendulum | 진자 시계 | 좌우 스윙 |
|
||||
| 19 | Flock of Birds | 새 떼 비행 | Boids 군집 이동 |
|
||||
| 20 | Grand Finale | 그랜드 피날레 | 나선 → 모임 → 대폭발 |
|
||||
|
||||
### 9.6 애니메이션 시간 관리
|
||||
|
||||
```javascript
|
||||
// 정규화된 시간 t (0.0 ~ 1.0)
|
||||
const t = elapsed / s.duration;
|
||||
|
||||
// 페이즈 분할 예시 (Star Gathering)
|
||||
if (t < 0.6) {
|
||||
// GATHER 페이즈: 사방에서 중심으로 모임
|
||||
const p = t / 0.6; // 0~1 정규화
|
||||
} else if (t < 0.7) {
|
||||
// FLASH 페이즈: 흰색 번쩍
|
||||
} else {
|
||||
// BURST 페이즈: 폭발 분산
|
||||
const bp = (t - 0.7) / 0.3;
|
||||
}
|
||||
```
|
||||
|
||||
- `performance.now()` 기준 절대 시간 사용
|
||||
- 각 효과의 `duration`은 3~6초 범위
|
||||
- 프레임 독립적 (delta time 기반)
|
||||
|
||||
### 9.7 UI 구성
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ BimToolbar │
|
||||
│ ┌──────────────────┐ ┌──┐ │
|
||||
│ │ sam1 Star Gather ▼│ │▶│ ... 기존 버튼 │
|
||||
│ └──────────────────┘ └──┘ │
|
||||
│ (드롭다운 select) (재생) │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| UI 요소 | React 상태 | 설명 |
|
||||
|---------|-----------|------|
|
||||
| 효과 드롭다운 | `effectId` | `SHOW_EFFECTS` 배열(20개) 중 선택 |
|
||||
| 재생 버튼 | — | `sceneRef.current.playShow(effectId)` 호출 |
|
||||
|
||||
`SHOW_EFFECTS` 상수:
|
||||
|
||||
```javascript
|
||||
const SHOW_EFFECTS = [
|
||||
{ id:1, name:'sam1 Star Gathering' },
|
||||
{ id:2, name:'sam2 Spiral Galaxy' },
|
||||
// ... 20개
|
||||
];
|
||||
```
|
||||
|
||||
### 9.8 메모리 관리
|
||||
|
||||
`_cleanupShow()`가 모든 효과의 리소스를 통일적으로 정리한다:
|
||||
|
||||
```javascript
|
||||
_cleanupShow() {
|
||||
if (!this._show) return;
|
||||
const { items, extras } = this._show;
|
||||
// items: TextGeometry 또는 Sprite
|
||||
[items, extras].forEach(arr => arr.forEach(it => {
|
||||
if (it.geometry) it.geometry.dispose();
|
||||
if (it.material) {
|
||||
if (it.material.map) it.material.map.dispose();
|
||||
it.material.dispose();
|
||||
}
|
||||
this.scene.remove(it);
|
||||
}));
|
||||
this._show = null;
|
||||
}
|
||||
```
|
||||
|
||||
`dispose()` (BimScene 전체 정리) 시에도 `_cleanupShow()`를 호출하여 누수를 방지한다.
|
||||
|
||||
---
|
||||
|
||||
## 10. 향후 계획 (Phase 4+)
|
||||
|
||||
| Phase | 기능 | 기술 | 상태 |
|
||||
|-------|------|------|------|
|
||||
| ~~Phase 1~~ | ~~데모 건물 + 3D 뷰어~~ | ~~Three.js r128~~ | 완료 |
|
||||
| ~~Phase 2~~ | ~~IFC 업로드/다운로드 + 실제 BIM 렌더링~~ | ~~web-ifc 0.0.66~~ | 완료 |
|
||||
| ~~Phase 3~~ | ~~SAM Show Effects 20종~~ | ~~Three.js TextGeometry + Sprite~~ | 완료 |
|
||||
| **Phase 4** | 요소 속성 패널 고도화, 2D 평면도 모드 | Three.js Orthographic Camera | |
|
||||
| **Phase 5** | 모델 파일 관리, 버전 이력, 협력업체 조회 | Laravel API + DB | |
|
||||
|
||||
---
|
||||
|
||||
@@ -391,4 +549,4 @@ Three.js → React: bim.onSelect = setSelected (요소 선택 콜백)
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-12
|
||||
**최종 업데이트**: 2026-03-13
|
||||
|
||||
Reference in New Issue
Block a user