SamiKoen commited on
Commit
6b7e121
·
1 Parent(s): be74369

Trek logosu artik 3D plane mesh, Spine bone'a attach edili — avatar ile birlikte hareket eder. SVG runtime canvas->beyaza cevriliyor

Browse files
Files changed (1) hide show
  1. static/index.html +86 -14
static/index.html CHANGED
@@ -46,19 +46,6 @@
46
  border-color: rgba(52,211,153,0.7);
47
  box-shadow: 0 0 30px rgba(52,211,153,0.35);
48
  }
49
- .trek-logo {
50
- position: absolute;
51
- bottom: 17%;
52
- left: 50%;
53
- transform: translateX(-50%);
54
- width: clamp(70px, 22%, 110px);
55
- height: auto;
56
- /* SVG'yi siyahtan beyaza cevir + drop shadow */
57
- filter: brightness(0) invert(1) drop-shadow(0 1px 2px rgba(0,0,0,0.5));
58
- pointer-events: none;
59
- z-index: 5;
60
- user-select: none;
61
- }
62
  .loading {
63
  position: absolute;
64
  inset: 0;
@@ -135,7 +122,6 @@
135
  <div class="stage">
136
  <canvas id="avatarCanvas"></canvas>
137
  <div id="ring" class="ring"></div>
138
- <img class="trek-logo" src="/static/trek-logo.svg" alt="Trek" />
139
  <div id="loading" class="loading">
140
  <div class="spinner"></div>
141
  <div>Avatar yukleniyor...</div>
@@ -169,6 +155,7 @@ let scene, camera, renderer, clock;
169
  let avatar = null;
170
  let morphMeshes = []; // Morph target'i olan TUM mesh'ler
171
  let headBone = null;
 
172
 
173
  // ----- Audio state -----
174
  let ws = null;
@@ -293,11 +280,15 @@ async function loadAvatar() {
293
 
294
  console.log('[avatar] bone sayisi:', allBones.length, '— head bone:', headBone?.name || 'YOK');
295
  console.log('[avatar] morph mesh sayisi:', morphMeshes.length);
 
296
 
297
  if (morphMeshes.length === 0) {
298
  console.warn('[avatar] HIC morph target yok — bu avatar lip sync icin uygun degil');
299
  }
300
 
 
 
 
301
  // Avatar'i sahneye yerlestir (bel-yukari gorunum)
302
  avatar.position.set(0, 0, 0);
303
  scene.add(avatar);
@@ -305,6 +296,87 @@ async function loadAvatar() {
305
  return true;
306
  }
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  // ============================================================
309
  // Animasyon dongusu — lip sync, blink, idle
310
  // ============================================================
 
46
  border-color: rgba(52,211,153,0.7);
47
  box-shadow: 0 0 30px rgba(52,211,153,0.35);
48
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  .loading {
50
  position: absolute;
51
  inset: 0;
 
122
  <div class="stage">
123
  <canvas id="avatarCanvas"></canvas>
124
  <div id="ring" class="ring"></div>
 
125
  <div id="loading" class="loading">
126
  <div class="spinner"></div>
127
  <div>Avatar yukleniyor...</div>
 
155
  let avatar = null;
156
  let morphMeshes = []; // Morph target'i olan TUM mesh'ler
157
  let headBone = null;
158
+ let logoMesh = null; // Avatar gogsune attach edilen Trek logosu
159
 
160
  // ----- Audio state -----
161
  let ws = null;
 
280
 
281
  console.log('[avatar] bone sayisi:', allBones.length, '— head bone:', headBone?.name || 'YOK');
282
  console.log('[avatar] morph mesh sayisi:', morphMeshes.length);
283
+ console.log('[avatar] tum bone isimleri:', allBones);
284
 
285
  if (morphMeshes.length === 0) {
286
  console.warn('[avatar] HIC morph target yok — bu avatar lip sync icin uygun degil');
287
  }
288
 
289
+ // Trek logosunu avatar gogsune attach et (3D, avatar ile birlikte hareket eder)
290
+ await attachTrekLogo();
291
+
292
  // Avatar'i sahneye yerlestir (bel-yukari gorunum)
293
  avatar.position.set(0, 0, 0);
294
  scene.add(avatar);
 
296
  return true;
297
  }
298
 
299
+ // ============================================================
300
+ // Trek logosunu avatar gogsune ekle (3D, bone'a attach)
301
+ // ============================================================
302
+ async function loadLogoTexture() {
303
+ return new Promise((resolve) => {
304
+ const img = new Image();
305
+ img.crossOrigin = 'anonymous';
306
+ img.onload = () => {
307
+ const canvas = document.createElement('canvas');
308
+ const aspect = img.height / img.width;
309
+ canvas.width = 1024;
310
+ canvas.height = Math.round(1024 * aspect);
311
+ const ctx = canvas.getContext('2d');
312
+ // SVG'yi cizdir, sonra source-in ile beyaz fill — siyah logoyu beyaza cevirir
313
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
314
+ ctx.globalCompositeOperation = 'source-in';
315
+ ctx.fillStyle = '#ffffff';
316
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
317
+ const texture = new THREE.CanvasTexture(canvas);
318
+ texture.colorSpace = THREE.SRGBColorSpace;
319
+ texture.anisotropy = 16;
320
+ texture.needsUpdate = true;
321
+ resolve({ texture, aspect });
322
+ };
323
+ img.onerror = (e) => { console.error('[logo] yukleme hatasi:', e); resolve(null); };
324
+ img.src = '/static/trek-logo.svg';
325
+ });
326
+ }
327
+
328
+ async function attachTrekLogo() {
329
+ const result = await loadLogoTexture();
330
+ if (!result || !avatar) return;
331
+ const { texture, aspect } = result;
332
+
333
+ // Avatar'in gogus bone'unu bul (Spine2 > Spine1 > Spine > Chest > vb)
334
+ const candidates = ['Spine2', 'Spine1', 'Spine', 'Chest', 'spine2', 'spine1', 'spine'];
335
+ let chestBone = null;
336
+ for (const name of candidates) {
337
+ chestBone = avatar.getObjectByName(name);
338
+ if (chestBone) break;
339
+ }
340
+ // Mixamo prefix'i de dene
341
+ if (!chestBone) {
342
+ avatar.traverse((obj) => {
343
+ if (chestBone) return;
344
+ if (obj.isBone) {
345
+ const n = obj.name.toLowerCase();
346
+ if (n.includes('spine2') || n.includes('chest')) chestBone = obj;
347
+ }
348
+ });
349
+ }
350
+ console.log('[logo] gogus bone:', chestBone?.name || 'YOK');
351
+
352
+ if (!chestBone) {
353
+ console.warn('[logo] gogus bone bulunamadi, logo eklenmedi');
354
+ return;
355
+ }
356
+
357
+ const logoWidth = 0.13;
358
+ const logoGeometry = new THREE.PlaneGeometry(logoWidth, logoWidth * aspect);
359
+ const logoMaterial = new THREE.MeshBasicMaterial({
360
+ map: texture,
361
+ transparent: true,
362
+ side: THREE.DoubleSide,
363
+ depthTest: true,
364
+ depthWrite: false,
365
+ });
366
+ logoMesh = new THREE.Mesh(logoGeometry, logoMaterial);
367
+
368
+ // Bone local space'inde gogus on tarafina yerlestir
369
+ // (bone tipik olarak omurga boyunca yukari uzanir, +Z genelde on tarafa bakar)
370
+ logoMesh.position.set(0, 0.08, 0.085);
371
+ // Plane bone'a paralel olsun diye rotation
372
+ logoMesh.rotation.set(0, 0, 0);
373
+ // Tisirtin yuzeyinden cok hafif onde dursun (z-fight onleme)
374
+ logoMesh.renderOrder = 10;
375
+
376
+ chestBone.add(logoMesh);
377
+ console.log('[logo] yerlestirildi:', chestBone.name);
378
+ }
379
+
380
  // ============================================================
381
  // Animasyon dongusu — lip sync, blink, idle
382
  // ============================================================