Skip to content

Commit 555d7e3

Browse files
committed
fix: change olympic medals on athletes
1 parent d0ee26c commit 555d7e3

8 files changed

Lines changed: 33 additions & 76 deletions

website/js/AthleteRenderer.js

Lines changed: 25 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,22 @@ export class AthleteRenderer {
55
static loader = new GLTFLoader();
66

77
static cache = {
8-
man: null,
9-
woman: null
8+
man_gold: null,
9+
man_silver: null,
10+
man_bronze: null,
11+
woman_gold: null,
12+
woman_silver: null,
13+
woman_bronze: null
1014
};
1115

12-
static loadModels(manUrl, womanUrl) {
16+
static loadModels(manGoldUrl, manSilverUrl, manBronzeUrl, womanGoldUrl, womanSilverUrl, womanBronzeUrl) {
1317
return Promise.all([
14-
this._load(manUrl).then(m => (this.cache.man = m)),
15-
this._load(womanUrl).then(m => (this.cache.woman = m))
18+
this._load(manGoldUrl).then(m => (this.cache.man_gold = m)),
19+
this._load(manSilverUrl).then(m => (this.cache.man_silver = m)),
20+
this._load(manBronzeUrl).then(m => (this.cache.man_bronze = m)),
21+
this._load(womanGoldUrl).then(m => (this.cache.woman_gold = m)),
22+
this._load(womanSilverUrl).then(m => (this.cache.woman_silver = m)),
23+
this._load(womanBronzeUrl).then(m => (this.cache.woman_bronze = m))
1624
]);
1725
}
1826

@@ -23,7 +31,9 @@ export class AthleteRenderer {
2331
}
2432

2533
static addHuman(scene, athlete, pos, gender = "man") {
26-
const base = this.cache[gender].clone(true);
34+
const cacheKey = `${gender}_${athlete.medal.toLowerCase()}`;
35+
36+
const base = this.cache[cacheKey].clone(true);
2737

2838
const group = new THREE.Group();
2939
group.position.set(pos.x, pos.podiumHeight, 0);
@@ -39,6 +49,12 @@ export class AthleteRenderer {
3949
base.scale.z *= weightScale;
4050
base.position.y = 0;
4151

52+
const medalMat = new THREE.MeshStandardMaterial({
53+
color: this._medalColor(athlete.medal),
54+
metalness: 0.8,
55+
roughness: 0.2
56+
});
57+
4258
base.traverse((obj) => {
4359
if (!obj.isMesh) return;
4460
const mat = obj.material;
@@ -47,83 +63,17 @@ export class AthleteRenderer {
4763
mat.side = THREE.DoubleSide;
4864
if (mat.map) mat.map.colorSpace = THREE.SRGBColorSpace;
4965
if (mat.emissiveMap) mat.emissiveMap.colorSpace = THREE.SRGBColorSpace;
50-
});
5166

52-
base.traverse((obj) => {
53-
if (!obj.isMesh) return;
54-
const name = obj.name.toLowerCase();
55-
if (name.includes("cloth") || name.includes("shirt") || name.includes("body")) {
56-
obj.material = new THREE.MeshStandardMaterial({
57-
color: 0xf2f2f2,
58-
roughness: 0.8
59-
});
67+
if (!obj.name.includes("_basic")) {
68+
obj.material = medalMat;
6069
}
6170
});
6271

6372
group.add(base);
64-
65-
// Real bounding box so all positions adapt to any model scale
66-
const tempBox = new THREE.Box3().setFromObject(group);
67-
const modelWorldHeight = tempBox.max.y - tempBox.min.y;
68-
69-
const chestWorldY = tempBox.min.y + modelWorldHeight * 0.72;
70-
const neckWorldY = tempBox.min.y + modelWorldHeight * 0.88;
71-
const frontWorldZ = tempBox.max.z + 0.02;
72-
73-
// Group-local Y (group sits at pos.podiumHeight)
74-
const chestLocalY = chestWorldY - pos.podiumHeight;
75-
const neckLocalY = neckWorldY - pos.podiumHeight;
76-
77-
const medalRadius = modelWorldHeight * 0.032;
78-
const strapRadius = medalRadius * 0.12;
79-
const neckHalfWidth = modelWorldHeight * 0.045; // where straps leave the neck
80-
const neckZ = frontWorldZ - medalRadius * 1.5; // straps start slightly behind
81-
82-
// Two diagonal ribbon straps forming a V around the neck
83-
const strapMat = new THREE.MeshStandardMaterial({ color: 0xcc1111, roughness: 0.65 });
84-
const medalCenter = new THREE.Vector3(0, chestLocalY, frontWorldZ);
85-
86-
[
87-
new THREE.Vector3(-neckHalfWidth, neckLocalY, neckZ),
88-
new THREE.Vector3( neckHalfWidth, neckLocalY, neckZ)
89-
].forEach(strapStart => {
90-
this._addSegment(group, strapStart, medalCenter, strapRadius, strapMat);
91-
});
92-
93-
// Medal disc (drawn after straps so it sits on top)
94-
const medalMat = new THREE.MeshStandardMaterial({
95-
color: this._medalColor(athlete.medal),
96-
metalness: 0.75,
97-
roughness: 0.25
98-
});
99-
const medalDisc = new THREE.Mesh(
100-
new THREE.CylinderGeometry(medalRadius, medalRadius, medalRadius * 0.25, 32),
101-
medalMat
102-
);
103-
medalDisc.position.set(0, chestLocalY, frontWorldZ);
104-
medalDisc.rotation.x = Math.PI / 2;
105-
group.add(medalDisc);
106-
10773
scene.add(group);
10874
return group;
10975
}
11076

111-
// Draws a cylinder aligned between two arbitrary 3D points
112-
static _addSegment(group, from, to, radius, material) {
113-
const dir = new THREE.Vector3().subVectors(to, from);
114-
const length = dir.length();
115-
const mid = new THREE.Vector3().lerpVectors(from, to, 0.5);
116-
117-
const mesh = new THREE.Mesh(
118-
new THREE.CylinderGeometry(radius, radius, length, 8),
119-
material
120-
);
121-
mesh.position.copy(mid);
122-
// CylinderGeometry is Y-up by default; rotate to align with dir
123-
mesh.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir.clone().normalize());
124-
group.add(mesh);
125-
}
126-
12777
static _medalColor(medal) {
12878
switch (medal) {
12979
case "Gold": return 0xf4c542;
@@ -132,4 +82,4 @@ export class AthleteRenderer {
13282
default: return 0xffffff;
13383
}
13484
}
135-
}
85+
}

website/js/body-types.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ import { AthleteRenderer } from "./AthleteRenderer.js";
4646
try {
4747
const [rows] = await Promise.all([
4848
d3.csv(DATA_PATH, d3.autoType),
49-
AthleteRenderer.loadModels("models/man_outfit.glb", "models/woman_outfit.glb")
49+
AthleteRenderer.loadModels(
50+
"models/man_outfit_gold.glb",
51+
"models/man_outfit_silver.glb",
52+
"models/man_outfit_bronze.glb",
53+
"models/woman_outfit_gold.glb",
54+
"models/woman_outfit_silver.glb",
55+
"models/woman_outfit_bronze.glb"
56+
)
5057
]);
5158

5259
state.rows = rows;
26.5 MB
Binary file not shown.

website/models/man_outfit_gold.glb

25.1 MB
Binary file not shown.
25.8 MB
Binary file not shown.
26.9 MB
Binary file not shown.
25.2 MB
Binary file not shown.
25.9 MB
Binary file not shown.

0 commit comments

Comments
 (0)