1,4 k tris0,09 × 0,03 × 0,09 m
Utiliser dans le code
Remixer dans l’éditeurdonut.js · 433 lignes
Module ES autonome — ne dépend que de three. Appelez la fonction factory et ajoutez le groupe à votre scène.
/**
* Donut — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,408 · Size (W × H × D): 0.09 × 0.03 × 0.09 m
*
* Usage:
* import { createDonut } from './donut.js';
*
* const model = createDonut();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
const pos = geometry.attributes.position;
const h = (a, b, c, s) => {
let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
x = Math.imul(x ^ (x >>> 16), 2246822507);
x = Math.imul(x ^ (x >>> 13), 3266489909);
return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
};
for (let i = 0; i < pos.count; i++) {
const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
}
pos.needsUpdate = true;
geometry.computeVertexNormals();
return geometry;
}
export function createDonut() {
const root = new THREE.Group();
root.name = 'Donut';
// Materials
const sprinkle1Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle1', color: 0xff5a5f, roughness: 0.4, flatShading: true });
const sprinkle2Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle2', color: 0xffd23f, roughness: 0.4, flatShading: true });
const sprinkle3Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle3', color: 0x3ec1d3, roughness: 0.4, flatShading: true });
const sprinkle4Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle4', color: 0x7ed957, roughness: 0.4, flatShading: true });
const sprinkle5Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle5', color: 0xffffff, roughness: 0.4, flatShading: true });
const sprinkle6Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle6', color: 0xa66cff, roughness: 0.4, flatShading: true });
const doughMat = new THREE.MeshStandardMaterial({ name: 'dough', color: 0xe0a35a, roughness: 0.75 });
const icingMat = new THREE.MeshStandardMaterial({ name: 'icing', color: 0xf58fb6, roughness: 0.3 });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.055, 0.014, 0.014);
// Parts
const donut = new THREE.Group();
donut.name = 'donut';
donut.scale.setScalar(0.09);
root.add(donut);
const dough = new THREE.Mesh(new THREE.TorusGeometry(0.31, 0.19, 10, 22), doughMat);
dough.name = 'dough';
dough.position.set(0, 0.1634, 0);
dough.rotation.set(deg(90), 0, 0);
dough.scale.set(1, 1, 0.86);
donut.add(dough);
const icing = new THREE.Mesh(jitter(new THREE.TorusGeometry(0.31, 0.2014, 10, 22), 0.008, 4), icingMat);
icing.name = 'icing';
icing.position.set(0, 0.2204, 0);
icing.rotation.set(deg(90), 0, 0);
icing.scale.set(1, 1, 0.62);
donut.add(icing);
const sprinkle1 = new THREE.Group();
sprinkle1.name = 'sprinkle1';
sprinkle1.position.set(-0.308, 0.344, -0.1395);
sprinkle1.rotation.set(deg(-2.0641), 0, deg(4.5449));
donut.add(sprinkle1);
const box5 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box5.rotation.set(0, deg(50.9911), 0);
sprinkle1.add(box5);
const sprinkle2 = new THREE.Group();
sprinkle2.name = 'sprinkle2';
sprinkle2.position.set(-0.2383, 0.345, -0.2171);
sprinkle2.rotation.set(deg(-1.4736), 0, deg(1.6166));
donut.add(sprinkle2);
const box7 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box7.rotation.set(0, deg(160.558), 0);
sprinkle2.add(box7);
const sprinkle3 = new THREE.Group();
sprinkle3.name = 'sprinkle3';
sprinkle3.position.set(0.267, 0.3351, 0.284);
sprinkle3.rotation.set(deg(11.0292), 0, deg(-10.1951));
donut.add(sprinkle3);
const box9 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box9.rotation.set(0, deg(79.7119), 0);
sprinkle3.add(box9);
const sprinkle4 = new THREE.Group();
sprinkle4.name = 'sprinkle4';
sprinkle4.position.set(0.0753, 0.3054, 0.4513);
sprinkle4.rotation.set(deg(33.3412), 0, deg(-5.2419));
donut.add(sprinkle4);
const box11 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box11.rotation.set(0, deg(61.2374), 0);
sprinkle4.add(box11);
const sprinkle5 = new THREE.Group();
sprinkle5.name = 'sprinkle5';
sprinkle5.position.set(-0.2973, 0.3343, 0.2564);
sprinkle5.rotation.set(deg(10.3149), 0, deg(11.7309));
donut.add(sprinkle5);
const box13 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box13.rotation.set(0, deg(17.4507), 0);
sprinkle5.add(box13);
const sprinkle6 = new THREE.Group();
sprinkle6.name = 'sprinkle6';
sprinkle6.position.set(0.3897, 0.3096, 0.227);
sprinkle6.rotation.set(deg(17.0123), 0, deg(-26.6709));
donut.add(sprinkle6);
const box15 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box15.rotation.set(0, deg(99.7794), 0);
sprinkle6.add(box15);
const sprinkle7 = new THREE.Group();
sprinkle7.name = 'sprinkle7';
sprinkle7.position.set(0.2208, 0.2674, 0.4448);
sprinkle7.rotation.set(deg(53.8002), 0, deg(-21.8253));
donut.add(sprinkle7);
const box17 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box17.rotation.set(0, deg(87.9619), 0);
sprinkle7.add(box17);
const sprinkle8 = new THREE.Group();
sprinkle8.name = 'sprinkle8';
sprinkle8.position.set(0.0338, 0.3442, -0.2816);
sprinkle8.rotation.set(deg(4.6446), 0, deg(0.5569));
donut.add(sprinkle8);
const box19 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box19.rotation.set(0, deg(83.8255), 0);
sprinkle8.add(box19);
const sprinkle9 = new THREE.Group();
sprinkle9.name = 'sprinkle9';
sprinkle9.position.set(0.1823, 0.3331, -0.1287);
sprinkle9.rotation.set(deg(9.6986), 0, deg(13.4235));
donut.add(sprinkle9);
const box21 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box21.rotation.set(0, deg(144.8156), 0);
sprinkle9.add(box21);
const sprinkle10 = new THREE.Group();
sprinkle10.name = 'sprinkle10';
sprinkle10.position.set(0.1869, 0.3357, 0.1388);
sprinkle10.rotation.set(deg(-8.7164), 0, deg(11.5345));
donut.add(sprinkle10);
const box23 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box23.rotation.set(0, deg(106.0369), 0);
sprinkle10.add(box23);
const sprinkle11 = new THREE.Group();
sprinkle11.name = 'sprinkle11';
sprinkle11.position.set(0.1607, 0.3333, -0.3621);
sprinkle11.rotation.set(deg(-15.0174), 0, deg(-6.5609));
donut.add(sprinkle11);
const box25 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box25.rotation.set(0, deg(68.7118), 0);
sprinkle11.add(box25);
const sprinkle12 = new THREE.Group();
sprinkle12.name = 'sprinkle12';
sprinkle12.position.set(-0.0902, 0.3373, -0.2218);
sprinkle12.rotation.set(deg(12.1323), 0, deg(-4.8866));
donut.add(sprinkle12);
const box27 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box27.rotation.set(0, deg(76.5529), 0);
sprinkle12.add(box27);
const sprinkle13 = new THREE.Group();
sprinkle13.name = 'sprinkle13';
sprinkle13.position.set(-0.0979, 0.2738, -0.0824);
sprinkle13.rotation.set(deg(40.15), 0, deg(-37.4483));
donut.add(sprinkle13);
const box29 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box29.rotation.set(0, deg(104.7462), 0);
sprinkle13.add(box29);
const sprinkle14 = new THREE.Group();
sprinkle14.name = 'sprinkle14';
sprinkle14.position.set(0.0085, 0.3306, 0.4047);
sprinkle14.rotation.set(deg(18.3058), 0, deg(-0.3786));
donut.add(sprinkle14);
const box31 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box31.rotation.set(0, deg(155.6567), 0);
sprinkle14.add(box31);
const sprinkle15 = new THREE.Group();
sprinkle15.name = 'sprinkle15';
sprinkle15.position.set(0.1484, 0.3093, 0.0798);
sprinkle15.rotation.set(deg(-16.1637), 0, deg(27.3628));
donut.add(sprinkle15);
const box33 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box33.rotation.set(0, deg(115.2804), 0);
sprinkle15.add(box33);
const sprinkle16 = new THREE.Group();
sprinkle16.name = 'sprinkle16';
sprinkle16.position.set(0.2259, 0.3449, -0.2339);
sprinkle16.rotation.set(deg(-1.9318), 0, deg(-1.8649));
donut.add(sprinkle16);
const box35 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box35.rotation.set(0, deg(10.7344), 0);
sprinkle16.add(box35);
const sprinkle17 = new THREE.Group();
sprinkle17.name = 'sprinkle17';
sprinkle17.position.set(0.1587, 0.324, -0.1177);
sprinkle17.rotation.set(deg(13.9503), 0, deg(18.0145));
donut.add(sprinkle17);
const box37 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box37.rotation.set(0, deg(70.5712), 0);
sprinkle17.add(box37);
const sprinkle18 = new THREE.Group();
sprinkle18.name = 'sprinkle18';
sprinkle18.position.set(0.0929, 0.3247, 0.4103);
sprinkle18.rotation.set(deg(21.6788), 0, deg(-4.7791));
donut.add(sprinkle18);
const box39 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box39.rotation.set(0, deg(38.6076), 0);
sprinkle18.add(box39);
const sprinkle19 = new THREE.Group();
sprinkle19.name = 'sprinkle19';
sprinkle19.position.set(-0.0823, 0.2977, 0.1276);
sprinkle19.rotation.set(deg(-33.451), 0, deg(-19.5784));
donut.add(sprinkle19);
const box41 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box41.rotation.set(0, deg(6.3323), 0);
sprinkle19.add(box41);
const sprinkle20 = new THREE.Group();
sprinkle20.name = 'sprinkle20';
sprinkle20.position.set(0.4737, 0.2879, -0.074);
sprinkle20.rotation.set(deg(-8.4776), 0, deg(-43.346));
donut.add(sprinkle20);
const box43 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box43.rotation.set(0, deg(37.911), 0);
sprinkle20.add(box43);
const sprinkle21 = new THREE.Group();
sprinkle21.name = 'sprinkle21';
sprinkle21.position.set(-0.1488, 0.3186, 0.111);
sprinkle21.rotation.set(deg(-16.2161), 0, deg(-20.5301));
donut.add(sprinkle21);
const box45 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box45.rotation.set(0, deg(49.143), 0);
sprinkle21.add(box45);
const sprinkle22 = new THREE.Group();
sprinkle22.name = 'sprinkle22';
sprinkle22.position.set(0.4404, 0.3114, 0.0819);
sprinkle22.rotation.set(deg(6.0846), 0, deg(-29.6753));
donut.add(sprinkle22);
const box47 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box47.rotation.set(0, deg(162.2151), 0);
sprinkle22.add(box47);
const sprinkle23 = new THREE.Group();
sprinkle23.name = 'sprinkle23';
sprinkle23.position.set(0.4241, 0.3201, 0.0779);
sprinkle23.rotation.set(deg(4.8256), 0, deg(-24.6114));
donut.add(sprinkle23);
const box49 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box49.rotation.set(0, deg(44.1494), 0);
sprinkle23.add(box49);
const sprinkle24 = new THREE.Group();
sprinkle24.name = 'sprinkle24';
sprinkle24.position.set(0.4879, 0.2779, -0.0303);
sprinkle24.rotation.set(deg(-4.2332), 0, deg(-49.967));
donut.add(sprinkle24);
const box51 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box51.rotation.set(0, deg(136.5695), 0);
sprinkle24.add(box51);
const sprinkle25 = new THREE.Group();
sprinkle25.name = 'sprinkle25';
sprinkle25.position.set(0.0861, 0.3244, 0.179);
sprinkle25.rotation.set(deg(-20.3547), 0, deg(9.501));
donut.add(sprinkle25);
const box53 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box53.rotation.set(0, deg(73.9506), 0);
sprinkle25.add(box53);
const sprinkle26 = new THREE.Group();
sprinkle26.name = 'sprinkle26';
sprinkle26.position.set(-0.1795, 0.3136, -0.4061);
sprinkle26.rotation.set(deg(-26.8218), 0, deg(11.2813));
donut.add(sprinkle26);
const box55 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box55.rotation.set(0, deg(84.5641), 0);
sprinkle26.add(box55);
const sprinkle27 = new THREE.Group();
sprinkle27.name = 'sprinkle27';
sprinkle27.position.set(0.0979, 0.3189, 0.4225);
sprinkle27.rotation.set(deg(25.1766), 0, deg(-5.6308));
donut.add(sprinkle27);
const box57 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box57.rotation.set(0, deg(68.2202), 0);
sprinkle27.add(box57);
const sprinkle28 = new THREE.Group();
sprinkle28.name = 'sprinkle28';
sprinkle28.position.set(0.1469, 0.3438, -0.2376);
sprinkle28.rotation.set(deg(4.6426), 0, deg(2.8659));
donut.add(sprinkle28);
const box59 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box59.rotation.set(0, deg(71.3566), 0);
sprinkle28.add(box59);
const sprinkle29 = new THREE.Group();
sprinkle29.name = 'sprinkle29';
sprinkle29.position.set(0.2644, 0.3439, -0.0914);
sprinkle29.rotation.set(deg(1.7606), 0, deg(5.0809));
donut.add(sprinkle29);
const box61 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box61.rotation.set(0, deg(163.6754), 0);
sprinkle29.add(box61);
const sprinkle30 = new THREE.Group();
sprinkle30.name = 'sprinkle30';
sprinkle30.position.set(-0.2257, 0.3422, -0.2736);
sprinkle30.rotation.set(deg(-6.2117), 0, deg(5.1002));
donut.add(sprinkle30);
const box63 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box63.rotation.set(0, deg(131.9645), 0);
sprinkle30.add(box63);
const sprinkle31 = new THREE.Group();
sprinkle31.name = 'sprinkle31';
sprinkle31.position.set(-0.2349, 0.3074, -0.3891);
sprinkle31.rotation.set(deg(-28.6815), 0, deg(16.1594));
donut.add(sprinkle31);
const box65 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box65.rotation.set(0, deg(125.4892), 0);
sprinkle31.add(box65);
const sprinkle32 = new THREE.Group();
sprinkle32.name = 'sprinkle32';
sprinkle32.position.set(0.1371, 0.3427, 0.2317);
sprinkle32.rotation.set(deg(-6.3024), 0, deg(3.7169));
donut.add(sprinkle32);
const box67 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box67.rotation.set(0, deg(168.4335), 0);
sprinkle32.add(box67);
const sprinkle33 = new THREE.Group();
sprinkle33.name = 'sprinkle33';
sprinkle33.position.set(-0.4827, 0.2668, -0.1185);
sprinkle33.rotation.set(deg(-20.2922), 0, deg(54.6969));
donut.add(sprinkle33);
const box69 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box69.rotation.set(0, deg(123.0071), 0);
sprinkle33.add(box69);
const sprinkle34 = new THREE.Group();
sprinkle34.name = 'sprinkle34';
sprinkle34.position.set(0.2178, 0.3314, -0.0044);
sprinkle34.rotation.set(deg(0.3673), 0, deg(17.6978));
donut.add(sprinkle34);
const box71 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box71.rotation.set(0, deg(5.0164), 0);
sprinkle34.add(box71);
const sprinkle35 = new THREE.Group();
sprinkle35.name = 'sprinkle35';
sprinkle35.position.set(-0.0624, 0.3359, 0.2249);
sprinkle35.rotation.set(deg(-13.803), 0, deg(-3.7843));
donut.add(sprinkle35);
const box73 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box73.rotation.set(0, deg(47.9673), 0);
sprinkle35.add(box73);
const sprinkle36 = new THREE.Group();
sprinkle36.name = 'sprinkle36';
sprinkle36.position.set(-0.1498, 0.2964, 0.0103);
sprinkle36.rotation.set(deg(-3.1854), 0, deg(-38.8348));
donut.add(sprinkle36);
const box75 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box75.rotation.set(0, deg(40.4357), 0);
sprinkle36.add(box75);
const sprinkle37 = new THREE.Group();
sprinkle37.name = 'sprinkle37';
sprinkle37.position.set(-0.2833, 0.344, 0.1856);
sprinkle37.rotation.set(deg(2.7971), 0, deg(4.2612));
donut.add(sprinkle37);
const box77 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box77.rotation.set(0, deg(83.9575), 0);
sprinkle37.add(box77);
const sprinkle38 = new THREE.Group();
sprinkle38.name = 'sprinkle38';
sprinkle38.position.set(-0.0916, 0.2788, 0.095);
sprinkle38.rotation.set(deg(-40.1594), 0, deg(-31.8774));
donut.add(sprinkle38);
const box79 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box79.rotation.set(0, deg(2.9683), 0);
sprinkle38.add(box79);
const sprinkle39 = new THREE.Group();
sprinkle39.name = 'sprinkle39';
sprinkle39.position.set(-0.0267, 0.3415, 0.3578);
sprinkle39.rotation.set(deg(8.7744), 0, deg(0.6512));
donut.add(sprinkle39);
const box81 = new THREE.Mesh(boxGeo, sprinkle3Mat);
box81.rotation.set(0, deg(133.4222), 0);
sprinkle39.add(box81);
const sprinkle40 = new THREE.Group();
sprinkle40.name = 'sprinkle40';
sprinkle40.position.set(-0.1283, 0.3066, 0.1025);
sprinkle40.rotation.set(deg(-22.0914), 0, deg(-25.206));
donut.add(sprinkle40);
const box83 = new THREE.Mesh(boxGeo, sprinkle4Mat);
box83.rotation.set(0, deg(104.7399), 0);
sprinkle40.add(box83);
const sprinkle41 = new THREE.Group();
sprinkle41.name = 'sprinkle41';
sprinkle41.position.set(-0.0865, 0.3, 0.1284);
sprinkle41.rotation.set(deg(-31.8699), 0, deg(-19.5772));
donut.add(sprinkle41);
const box85 = new THREE.Mesh(boxGeo, sprinkle5Mat);
box85.rotation.set(0, deg(84.4294), 0);
sprinkle41.add(box85);
const sprinkle42 = new THREE.Group();
sprinkle42.name = 'sprinkle42';
sprinkle42.position.set(0.2149, 0.3418, 0.2855);
sprinkle42.rotation.set(deg(6.826), 0, deg(-5.1114));
donut.add(sprinkle42);
const box87 = new THREE.Mesh(boxGeo, sprinkle6Mat);
box87.rotation.set(0, deg(10.4155), 0);
sprinkle42.add(box87);
const sprinkle43 = new THREE.Group();
sprinkle43.name = 'sprinkle43';
sprinkle43.position.set(0.1427, 0.3174, -0.4128);
sprinkle43.rotation.set(deg(-25.3935), 0, deg(-8.4294));
donut.add(sprinkle43);
const box89 = new THREE.Mesh(boxGeo, sprinkle1Mat);
box89.rotation.set(0, deg(117.7714), 0);
sprinkle43.add(box89);
const sprinkle44 = new THREE.Group();
sprinkle44.name = 'sprinkle44';
sprinkle44.position.set(0.1753, 0.3227, -0.0844);
sprinkle44.rotation.set(deg(10.6561), 0, deg(21.0114));
donut.add(sprinkle44);
const box91 = new THREE.Mesh(boxGeo, sprinkle2Mat);
box91.rotation.set(0, deg(73.3164), 0);
sprinkle44.add(box91);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createDonut;
Notes et commentaires
0 commentaire
Aucun commentaire pour l’instant. Dites comment vous avez utilisé ce modèle ou ce qui pourrait être amélioré.
Modèles similaires
Même catégorie ou étiquettes proches









