1312 三角面9.40 × 15.1 × 9.40 m
在代码中使用
在编辑器中改编hot-air-balloon.js · 238 行
自包含的 ES 模块,仅依赖 three。调用工厂函数,然后把返回的 group 添加到场景中。
/**
* Hot Air Balloon — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,312 · Size (W × H × D): 9.40 × 15.10 × 9.40 m
*
* Usage:
* import { createHotAirBalloon } from './hot-air-balloon.js';
*
* const model = createHotAirBalloon();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}
// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}
export function createHotAirBalloon() {
const root = new THREE.Group();
root.name = 'HotAirBalloon';
// Materials
const fabricAMat = new THREE.MeshStandardMaterial({ name: 'fabricA', color: 0xe2483c, roughness: 0.75, flatShading: true, side: THREE.DoubleSide });
const fabricBMat = new THREE.MeshStandardMaterial({ name: 'fabricB', color: 0xf6d25a, roughness: 0.75, flatShading: true, side: THREE.DoubleSide });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x3a2d26, roughness: 0.85, flatShading: true, side: THREE.DoubleSide });
const wickerMat = new THREE.MeshStandardMaterial({ name: 'wicker', color: 0xb98a4e, roughness: 0.95, flatShading: true });
const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x9aa1aa, roughness: 0.4, metalness: 0.6, flatShading: true });
const flameMat = new THREE.MeshStandardMaterial({ name: 'flame', color: 0xffb23d, roughness: 0.6, emissive: 0xff8a1a, emissiveIntensity: 1.6, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(1.47, 0.05, 1.47);
const cylinderGeo = new THREE.CylinderGeometry(0.03, 0.03, 1.3, 5);
// Parts
const envelope = new THREE.Group();
envelope.name = 'envelope';
envelope.position.set(0, 10.0574, 0);
root.add(envelope);
const gore1 = new THREE.Group();
gore1.name = 'gore1';
envelope.add(gore1);
const sphere3 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, 0, Math.PI / 6, 0, Math.PI / 2), fabricAMat);
sphere3.scale.set(4.7, 4.9, 4.7);
gore1.add(sphere3);
const sphere4 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, 0, Math.PI / 6, Math.PI / 2, 1.2566), fabricAMat);
sphere4.scale.set(4.7, 7, 4.7);
gore1.add(sphere4);
const gore2 = new THREE.Group();
gore2.name = 'gore2';
envelope.add(gore2);
const sphere6 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI / 6, Math.PI / 6, 0, Math.PI / 2), fabricBMat);
sphere6.scale.set(4.7, 4.9, 4.7);
gore2.add(sphere6);
const sphere7 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI / 6, Math.PI / 6, Math.PI / 2, 1.2566), fabricBMat);
sphere7.scale.set(4.7, 7, 4.7);
gore2.add(sphere7);
const gore3 = new THREE.Group();
gore3.name = 'gore3';
envelope.add(gore3);
const sphere9 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI / 3, Math.PI / 6, 0, Math.PI / 2), fabricAMat);
sphere9.scale.set(4.7, 4.9, 4.7);
gore3.add(sphere9);
const sphere10 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI / 3, Math.PI / 6, Math.PI / 2, 1.2566), fabricAMat);
sphere10.scale.set(4.7, 7, 4.7);
gore3.add(sphere10);
const gore4 = new THREE.Group();
gore4.name = 'gore4';
envelope.add(gore4);
const sphere12 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI / 2, Math.PI / 6, 0, Math.PI / 2), fabricBMat);
sphere12.scale.set(4.7, 4.9, 4.7);
gore4.add(sphere12);
const sphere13 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI / 2, Math.PI / 6, Math.PI / 2, 1.2566), fabricBMat);
sphere13.scale.set(4.7, 7, 4.7);
gore4.add(sphere13);
const gore5 = new THREE.Group();
gore5.name = 'gore5';
envelope.add(gore5);
const sphere15 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 0.6667, Math.PI / 6, 0, Math.PI / 2), fabricAMat);
sphere15.scale.set(4.7, 4.9, 4.7);
gore5.add(sphere15);
const sphere16 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 0.6667, Math.PI / 6, Math.PI / 2, 1.2566), fabricAMat);
sphere16.scale.set(4.7, 7, 4.7);
gore5.add(sphere16);
const gore6 = new THREE.Group();
gore6.name = 'gore6';
envelope.add(gore6);
const sphere18 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 0.8333, Math.PI / 6, 0, Math.PI / 2), fabricBMat);
sphere18.scale.set(4.7, 4.9, 4.7);
gore6.add(sphere18);
const sphere19 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 0.8333, Math.PI / 6, Math.PI / 2, 1.2566), fabricBMat);
sphere19.scale.set(4.7, 7, 4.7);
gore6.add(sphere19);
const gore7 = new THREE.Group();
gore7.name = 'gore7';
envelope.add(gore7);
const sphere21 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI, Math.PI / 6, 0, Math.PI / 2), fabricAMat);
sphere21.scale.set(4.7, 4.9, 4.7);
gore7.add(sphere21);
const sphere22 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI, Math.PI / 6, Math.PI / 2, 1.2566), fabricAMat);
sphere22.scale.set(4.7, 7, 4.7);
gore7.add(sphere22);
const gore8 = new THREE.Group();
gore8.name = 'gore8';
envelope.add(gore8);
const sphere24 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.1667, Math.PI / 6, 0, Math.PI / 2), fabricBMat);
sphere24.scale.set(4.7, 4.9, 4.7);
gore8.add(sphere24);
const sphere25 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.1667, Math.PI / 6, Math.PI / 2, 1.2566), fabricBMat);
sphere25.scale.set(4.7, 7, 4.7);
gore8.add(sphere25);
const gore9 = new THREE.Group();
gore9.name = 'gore9';
envelope.add(gore9);
const sphere27 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.3333, Math.PI / 6, 0, Math.PI / 2), fabricAMat);
sphere27.scale.set(4.7, 4.9, 4.7);
gore9.add(sphere27);
const sphere28 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.3333, Math.PI / 6, Math.PI / 2, 1.2566), fabricAMat);
sphere28.scale.set(4.7, 7, 4.7);
gore9.add(sphere28);
const gore10 = new THREE.Group();
gore10.name = 'gore10';
envelope.add(gore10);
const sphere30 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.5, Math.PI / 6, 0, Math.PI / 2), fabricBMat);
sphere30.scale.set(4.7, 4.9, 4.7);
gore10.add(sphere30);
const sphere31 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.5, Math.PI / 6, Math.PI / 2, 1.2566), fabricBMat);
sphere31.scale.set(4.7, 7, 4.7);
gore10.add(sphere31);
const gore11 = new THREE.Group();
gore11.name = 'gore11';
envelope.add(gore11);
const sphere33 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.6667, Math.PI / 6, 0, Math.PI / 2), fabricAMat);
sphere33.scale.set(4.7, 4.9, 4.7);
gore11.add(sphere33);
const sphere34 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.6667, Math.PI / 6, Math.PI / 2, 1.2566), fabricAMat);
sphere34.scale.set(4.7, 7, 4.7);
gore11.add(sphere34);
const gore12 = new THREE.Group();
gore12.name = 'gore12';
envelope.add(gore12);
const sphere36 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.8333, Math.PI / 6, 0, Math.PI / 2), fabricBMat);
sphere36.scale.set(4.7, 4.9, 4.7);
gore12.add(sphere36);
const sphere37 = new THREE.Mesh(new THREE.SphereGeometry(1, 2, 6, Math.PI * 1.8333, Math.PI / 6, Math.PI / 2, 1.2566), fabricBMat);
sphere37.scale.set(4.7, 7, 4.7);
gore12.add(sphere37);
const crown = new THREE.Mesh(new THREE.SphereGeometry(1.15, 10, 2, 0, Math.PI * 2, 0, Math.PI / 2), darkMat);
crown.name = 'crown';
crown.position.set(0, 4.7, 0);
crown.scale.set(1, 0.3, 1);
envelope.add(crown);
const skirt = new THREE.Mesh(lathe([[1.191, 2.5], [1.3943, 3.1], [1.4724, 3.45]], 16), darkMat);
skirt.name = 'skirt';
root.add(skirt);
const loadRing = new THREE.Mesh(new THREE.TorusGeometry(1.191, 0.06, 4, 16), metalMat);
loadRing.name = 'loadRing';
loadRing.position.set(0, 2.5, 0);
loadRing.rotation.set(deg(90), 0, 0);
root.add(loadRing);
const basket = new THREE.Group();
basket.name = 'basket';
root.add(basket);
const wickerBox = new THREE.Mesh(new THREE.BoxGeometry(1.45, 1.15, 1.45), wickerMat);
wickerBox.name = 'wickerBox';
wickerBox.position.set(0, 0.575, 0);
basket.add(wickerBox);
const rim = new THREE.Mesh(new THREE.BoxGeometry(1.53, 0.14, 1.53), darkMat);
rim.name = 'rim';
rim.position.set(0, 1.1, 0);
basket.add(rim);
const base = new THREE.Mesh(new THREE.BoxGeometry(1.49, 0.08, 1.49), darkMat);
base.name = 'base';
base.position.set(0, 0.04, 0);
basket.add(base);
const box45 = new THREE.Mesh(boxGeo, darkMat);
box45.position.set(0, 0.32, 0);
basket.add(box45);
const box46 = new THREE.Mesh(boxGeo, darkMat);
box46.position.set(0, 0.62, 0);
basket.add(box46);
const cylinder47 = new THREE.Mesh(cylinderGeo, metalMat);
cylinder47.position.set(0.55, 1.8, 0.55);
basket.add(cylinder47);
const cylinder48 = new THREE.Mesh(cylinderGeo, metalMat);
cylinder48.position.set(0.55, 1.8, -0.55);
basket.add(cylinder48);
const cylinder49 = new THREE.Mesh(cylinderGeo, metalMat);
cylinder49.position.set(-0.55, 1.8, 0.55);
basket.add(cylinder49);
const cylinder50 = new THREE.Mesh(cylinderGeo, metalMat);
cylinder50.position.set(-0.55, 1.8, -0.55);
basket.add(cylinder50);
const burnerFrame = new THREE.Mesh(new THREE.BoxGeometry(1.16, 0.05, 1.16), metalMat);
burnerFrame.name = 'burnerFrame';
burnerFrame.position.set(0, 2.45, 0);
basket.add(burnerFrame);
const burner = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.16, 0.36, 8), metalMat);
burner.name = 'burner';
burner.position.set(0, 2.27, 0);
basket.add(burner);
const flame = new THREE.Mesh(new THREE.ConeGeometry(0.16, 0.7, 7), flameMat);
flame.name = 'flame';
flame.position.set(0, 2.8, 0);
basket.add(flame);
const rope1 = new THREE.Mesh(tube([[0.72, 1.15, 0.72], [0.7811, 1.825, 0.7811], [0.8421, 2.5, 0.8421]], 0.025, 2, 4), darkMat);
rope1.name = 'rope1';
root.add(rope1);
const rope2 = new THREE.Mesh(tube([[0.72, 1.15, -0.72], [0.7811, 1.825, -0.7811], [0.8421, 2.5, -0.8421]], 0.025, 2, 4), darkMat);
rope2.name = 'rope2';
root.add(rope2);
const rope3 = new THREE.Mesh(tube([[-0.72, 1.15, -0.72], [-0.7811, 1.825, -0.7811], [-0.8421, 2.5, -0.8421]], 0.025, 2, 4), darkMat);
rope3.name = 'rope3';
root.add(rope3);
const rope4 = new THREE.Mesh(tube([[-0.72, 1.15, 0.72], [-0.7811, 1.825, 0.7811], [-0.8421, 2.5, 0.8421]], 0.025, 2, 4), darkMat);
rope4.name = 'rope4';
root.add(rope4);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createHotAirBalloon;
评分与评论
0 条评论
暂无评论。分享一下你是如何使用这个模型的,或者有哪些可以改进的地方。
相关模型
同一分类或相似标签









