Ride: full sportscar trim so it reads as a convertible, not a tractor
Hood, trunk, bumpers, side skirts, torus-arch fenders, grille, headlamps, taillight bar, mirrors, rear spoiler, exhausts. Fixed layout in palette paint (painted panels join the viz reflection feed); dark trim stays matte. Verified front/side/rear: lamps on, viz pattern on the hood, arches over wheels.
This commit is contained in:
@@ -523,6 +523,107 @@ export const ride = {
|
|||||||
instance.car.add(cabin);
|
instance.car.add(cabin);
|
||||||
instance.bodyMeshes.push(cabin);
|
instance.bodyMeshes.push(cabin);
|
||||||
|
|
||||||
|
// Sportscar trim: hood, trunk, bumpers, skirts, fenders, grille,
|
||||||
|
// lamps, mirrors, spoiler, exhausts. Fixed layout, palette paint
|
||||||
|
// — the chassis above varies per track, this is what makes every
|
||||||
|
// reading of it a convertible rather than a tractor. Painted
|
||||||
|
// panels join the viz reflection feed (more surface mirroring the
|
||||||
|
// video); dark trim stays matte. All constants: identical on
|
||||||
|
// every track, every run.
|
||||||
|
{
|
||||||
|
const paint = cc(0);
|
||||||
|
const paintMat = () => vizEnvMaterial(new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(paint[0] * 0.85, paint[1] * 0.85, paint[2] * 0.85),
|
||||||
|
emissive: new T.Color(paint[0] * 0.1, paint[1] * 0.1, paint[2] * 0.1),
|
||||||
|
roughness: 0.32, metalness: 0.45,
|
||||||
|
transparent: opacity < 0.999, opacity,
|
||||||
|
}), instance, 0.45);
|
||||||
|
const trimMat = new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(0.04, 0.04, 0.05), roughness: 0.6, metalness: 0.5,
|
||||||
|
transparent: opacity < 0.999, opacity,
|
||||||
|
});
|
||||||
|
const add = (mesh) => {
|
||||||
|
instance.car.add(mesh);
|
||||||
|
instance.bodyMeshes.push(mesh);
|
||||||
|
return mesh;
|
||||||
|
};
|
||||||
|
// Hood: long low panel ahead of the cabin, nose tilted down,
|
||||||
|
// thick enough to meet the cabin's lower edge with no gap.
|
||||||
|
const hood = add(new T.Mesh(new T.BoxGeometry(1.5, 0.24, 1.15), paintMat()));
|
||||||
|
hood.position.set(0, 0.18, -1.6);
|
||||||
|
hood.rotation.x = -0.07;
|
||||||
|
// Trunk deck behind the cabin, meeting its lower edge.
|
||||||
|
const trunk = add(new T.Mesh(new T.BoxGeometry(1.5, 0.2, 0.8), paintMat()));
|
||||||
|
trunk.position.set(0, 0.2, 1.15);
|
||||||
|
// Bumpers, low and wide, fore and aft.
|
||||||
|
const bumperF = add(new T.Mesh(new T.BoxGeometry(1.8, 0.22, 0.3), trimMat));
|
||||||
|
bumperF.position.set(0, -0.35, -2.05);
|
||||||
|
const bumperR = add(new T.Mesh(new T.BoxGeometry(1.8, 0.22, 0.3), trimMat));
|
||||||
|
bumperR.position.set(0, -0.35, 1.62);
|
||||||
|
// Side skirts between the wheels.
|
||||||
|
for (const side of [-1, 1]) {
|
||||||
|
const skirt = add(new T.Mesh(new T.BoxGeometry(0.12, 0.14, 2.0), trimMat));
|
||||||
|
skirt.position.set(side * 0.93, -0.5, -0.15);
|
||||||
|
}
|
||||||
|
// Fenders: half-torus arches over each wheel. Torus arc 0..π
|
||||||
|
// spans the upper half in XY; yawed 90° it arches across the
|
||||||
|
// wheel in the rolling plane.
|
||||||
|
const fenderGeo = new T.TorusGeometry(0.5, 0.1, 8, 12, Math.PI);
|
||||||
|
for (const [wx, wz] of [[-0.95, 1.05], [0.95, 1.05], [-0.95, -1.35], [0.95, -1.35]]) {
|
||||||
|
const fender = add(new T.Mesh(fenderGeo, paintMat()));
|
||||||
|
fender.rotation.y = Math.PI / 2;
|
||||||
|
fender.position.set(wx, -0.62, wz);
|
||||||
|
}
|
||||||
|
// Grille + headlamps proud of the nose so no face z-fights.
|
||||||
|
const grille = add(new T.Mesh(new T.BoxGeometry(0.9, 0.16, 0.06), trimMat));
|
||||||
|
grille.position.set(0, -0.12, -2.21);
|
||||||
|
const lampMat = new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(0.1, 0.1, 0.12),
|
||||||
|
emissive: new T.Color(0.75, 0.82, 1.0),
|
||||||
|
emissiveIntensity: 2.0,
|
||||||
|
roughness: 0.3,
|
||||||
|
});
|
||||||
|
for (const side of [-1, 1]) {
|
||||||
|
const lamp = add(new T.Mesh(new T.CircleGeometry(0.09, 16), lampMat));
|
||||||
|
lamp.position.set(side * 0.55, -0.05, -2.22);
|
||||||
|
lamp.rotation.y = Math.PI;
|
||||||
|
}
|
||||||
|
// Taillight bar set into the bumper's rear face.
|
||||||
|
const tail = add(new T.Mesh(
|
||||||
|
new T.BoxGeometry(1.2, 0.09, 0.05),
|
||||||
|
new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(0.08, 0.01, 0.01),
|
||||||
|
emissive: new T.Color(1.0, 0.08, 0.08),
|
||||||
|
emissiveIntensity: 1.5,
|
||||||
|
roughness: 0.4,
|
||||||
|
})));
|
||||||
|
tail.position.set(0, -0.28, 1.78);
|
||||||
|
// Mirrors on stalks at the cabin front corners.
|
||||||
|
for (const side of [-1, 1]) {
|
||||||
|
const stalk = add(new T.Mesh(new T.BoxGeometry(0.04, 0.12, 0.04), trimMat));
|
||||||
|
stalk.position.set(side * 0.9, 0.72, -0.95);
|
||||||
|
const mirror = add(new T.Mesh(new T.BoxGeometry(0.14, 0.09, 0.07), paintMat()));
|
||||||
|
mirror.position.set(side * 0.94, 0.8, -0.95);
|
||||||
|
}
|
||||||
|
// Rear spoiler: blade on two mounts over the trunk.
|
||||||
|
for (const side of [-1, 1]) {
|
||||||
|
const mount = add(new T.Mesh(new T.BoxGeometry(0.08, 0.3, 0.12), trimMat));
|
||||||
|
mount.position.set(side * 0.5, 0.28, 1.35);
|
||||||
|
}
|
||||||
|
const spoiler = add(new T.Mesh(new T.BoxGeometry(1.5, 0.06, 0.35), paintMat()));
|
||||||
|
spoiler.position.set(0, 0.46, 1.35);
|
||||||
|
// Exhausts under the rear bumper.
|
||||||
|
const pipeGeo = new T.CylinderGeometry(0.06, 0.06, 0.25, 12);
|
||||||
|
pipeGeo.rotateX(Math.PI / 2);
|
||||||
|
const pipeMat = new T.MeshStandardMaterial({
|
||||||
|
color: new T.Color(0.08, 0.08, 0.09), roughness: 0.35, metalness: 0.8,
|
||||||
|
});
|
||||||
|
for (const side of [-1, 1]) {
|
||||||
|
const pipe = add(new T.Mesh(pipeGeo, pipeMat));
|
||||||
|
pipe.position.set(side * 0.35, -0.45, 1.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wheels: four dark torus + hub, spin with speed (see below).
|
// Wheels: four dark torus + hub, spin with speed (see below).
|
||||||
const wheelGeo = new T.TorusGeometry(0.34, 0.13, 8, 18);
|
const wheelGeo = new T.TorusGeometry(0.34, 0.13, 8, 18);
|
||||||
const hubGeo = new T.CylinderGeometry(0.2, 0.2, 0.1, 10);
|
const hubGeo = new T.CylinderGeometry(0.2, 0.2, 0.1, 10);
|
||||||
|
|||||||
Reference in New Issue
Block a user