712 tris0.99 × 0.14 × 1.28 m
Use it in code
Remix in the editorlily-pad.js · 340 lines
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
* Lily Pads — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 712 · Size (W × H × D): 0.99 × 0.14 × 1.28 m
*
* Usage:
* import { createLilyPad } from './lily-pad.js';
*
* const model = createLilyPad();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
const options = bevel
? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
: { depth, bevelEnabled: false };
return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}
export function createLilyPad() {
const root = new THREE.Group();
root.name = 'LilyPad';
// Materials
const padMat = new THREE.MeshStandardMaterial({ name: 'pad', color: 0x4f9a3c, roughness: 0.55, flatShading: true });
const padLightMat = new THREE.MeshStandardMaterial({ name: 'padLight', color: 0x54a64e, roughness: 0.55, flatShading: true });
const veinMat = new THREE.MeshStandardMaterial({ name: 'vein', color: 0x75b673, roughness: 0.6, flatShading: true });
const petalMat = new THREE.MeshStandardMaterial({ name: 'petal', color: 0xf5a8c6, roughness: 0.6, flatShading: true });
const petalInnerMat = new THREE.MeshStandardMaterial({ name: 'petalInner', color: 0xfbd8e5, roughness: 0.6, flatShading: true });
const heartMat = new THREE.MeshStandardMaterial({ name: 'heart', color: 0xf4c23c, roughness: 0.6, flatShading: true });
const budMat = new THREE.MeshStandardMaterial({ name: 'bud', color: 0xdd97b2, roughness: 0.6, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.246, 0.003, 0.008);
const boxGeo2 = new THREE.BoxGeometry(0.1403, 0.003, 0.008);
const boxGeo3 = new THREE.BoxGeometry(0.1478, 0.003, 0.008);
const boxGeo4 = new THREE.BoxGeometry(0.1628, 0.003, 0.008);
const octahedronGeo = new THREE.OctahedronGeometry(1, 0);
// Parts
const lily1 = new THREE.Group();
lily1.name = 'lily1';
lily1.position.set(-0.2572, 0, 0.0653);
lily1.rotation.set(0, deg(128.8474), 0);
root.add(lily1);
const pad = new THREE.Group();
pad.name = 'pad';
lily1.add(pad);
const pad2 = new THREE.Mesh(extrude([[0, 0], [0.2869, -0.0877], [0.2152, -0.209], [0.096, -0.2842], [-0.0443, -0.2967], [-0.1749, -0.2437], [-0.2669, -0.137], [-0.3, 0], [-0.2669, 0.137], [-0.1749, 0.2437], [-0.0443, 0.2967], [0.096, 0.2842], [0.2152, 0.209], [0.2869, 0.0877]], 0.015), padMat);
pad2.name = 'pad';
pad2.position.set(0, 0.0075, 0);
pad2.rotation.set(deg(-90), 0, 0);
pad.add(pad2);
const vein1 = new THREE.Mesh(boxGeo, veinMat);
vein1.name = 'vein1';
vein1.position.set(0.1079, 0.0165, -0.059);
vein1.rotation.set(0, deg(28.6479), 0);
lily1.add(vein1);
const vein2 = new THREE.Mesh(boxGeo, veinMat);
vein2.name = 'vein2';
vein2.position.set(0.0233, 0.0165, -0.1208);
vein2.rotation.set(0, deg(79.0986), 0);
lily1.add(vein2);
const vein3 = new THREE.Mesh(boxGeo, veinMat);
vein3.name = 'vein3';
vein3.position.set(-0.0783, 0.0165, -0.0948);
vein3.rotation.set(0, deg(129.5493), 0);
lily1.add(vein3);
const vein4 = new THREE.Mesh(boxGeo, veinMat);
vein4.name = 'vein4';
vein4.position.set(-0.123, 0.0165, 0);
vein4.rotation.set(0, deg(180), 0);
lily1.add(vein4);
const vein5 = new THREE.Mesh(boxGeo, veinMat);
vein5.name = 'vein5';
vein5.position.set(-0.0783, 0.0165, 0.0948);
vein5.rotation.set(0, deg(230.4507), 0);
lily1.add(vein5);
const vein6 = new THREE.Mesh(boxGeo, veinMat);
vein6.name = 'vein6';
vein6.position.set(0.0233, 0.0165, 0.1208);
vein6.rotation.set(0, deg(280.9014), 0);
lily1.add(vein6);
const vein7 = new THREE.Mesh(boxGeo, veinMat);
vein7.name = 'vein7';
vein7.position.set(0.1079, 0.0165, 0.059);
vein7.rotation.set(0, deg(331.3521), 0);
lily1.add(vein7);
const lily2 = new THREE.Group();
lily2.name = 'lily2';
lily2.position.set(0.2682, 0, -0.0965);
lily2.rotation.set(0, deg(272.4929), 0);
root.add(lily2);
const pad3 = new THREE.Group();
pad3.name = 'pad';
lily2.add(pad3);
const pad4 = new THREE.Mesh(extrude([[0, 0], [0.1636, -0.05], [0.1227, -0.1192], [0.0547, -0.1621], [-0.0253, -0.1692], [-0.0997, -0.139], [-0.1522, -0.0781], [-0.1711, 0], [-0.1522, 0.0781], [-0.0997, 0.139], [-0.0253, 0.1692], [0.0547, 0.1621], [0.1227, 0.1192], [0.1636, 0.05]], 0.012), padLightMat);
pad4.name = 'pad';
pad4.position.set(0, 0.006, 0);
pad4.rotation.set(deg(-90), 0, 0);
pad3.add(pad4);
const vein12 = new THREE.Mesh(boxGeo2, veinMat);
vein12.name = 'vein1';
vein12.position.set(0.0615, 0.0135, -0.0336);
vein12.rotation.set(0, deg(28.6479), 0);
lily2.add(vein12);
const vein22 = new THREE.Mesh(boxGeo2, veinMat);
vein22.name = 'vein2';
vein22.position.set(0.0133, 0.0135, -0.0689);
vein22.rotation.set(0, deg(79.0986), 0);
lily2.add(vein22);
const vein32 = new THREE.Mesh(boxGeo2, veinMat);
vein32.name = 'vein3';
vein32.position.set(-0.0447, 0.0135, -0.0541);
vein32.rotation.set(0, deg(129.5493), 0);
lily2.add(vein32);
const vein42 = new THREE.Mesh(boxGeo2, veinMat);
vein42.name = 'vein4';
vein42.position.set(-0.0701, 0.0135, 0);
vein42.rotation.set(0, deg(180), 0);
lily2.add(vein42);
const vein52 = new THREE.Mesh(boxGeo2, veinMat);
vein52.name = 'vein5';
vein52.position.set(-0.0447, 0.0135, 0.0541);
vein52.rotation.set(0, deg(230.4507), 0);
lily2.add(vein52);
const vein62 = new THREE.Mesh(boxGeo2, veinMat);
vein62.name = 'vein6';
vein62.position.set(0.0133, 0.0135, 0.0689);
vein62.rotation.set(0, deg(280.9014), 0);
lily2.add(vein62);
const vein72 = new THREE.Mesh(boxGeo2, veinMat);
vein72.name = 'vein7';
vein72.position.set(0.0615, 0.0135, 0.0336);
vein72.rotation.set(0, deg(331.3521), 0);
lily2.add(vein72);
const lily3 = new THREE.Group();
lily3.name = 'lily3';
lily3.position.set(-0.0991, 0, -0.4347);
lily3.rotation.set(0, deg(302.2002), 0);
root.add(lily3);
const pad5 = new THREE.Group();
pad5.name = 'pad';
lily3.add(pad5);
const pad6 = new THREE.Mesh(extrude([[0, 0], [0.1724, -0.0527], [0.1293, -0.1256], [0.0577, -0.1708], [-0.0266, -0.1783], [-0.1051, -0.1464], [-0.1603, -0.0823], [-0.1802, 0], [-0.1603, 0.0823], [-0.1051, 0.1464], [-0.0266, 0.1783], [0.0577, 0.1708], [0.1293, 0.1256], [0.1724, 0.0527]], 0.012), padMat);
pad6.name = 'pad';
pad6.position.set(0, 0.006, 0);
pad6.rotation.set(deg(-90), 0, 0);
pad5.add(pad6);
const vein13 = new THREE.Mesh(boxGeo3, veinMat);
vein13.name = 'vein1';
vein13.position.set(0.0648, 0.0135, -0.0354);
vein13.rotation.set(0, deg(28.6479), 0);
lily3.add(vein13);
const vein23 = new THREE.Mesh(boxGeo3, veinMat);
vein23.name = 'vein2';
vein23.position.set(0.014, 0.0135, -0.0726);
vein23.rotation.set(0, deg(79.0986), 0);
lily3.add(vein23);
const vein33 = new THREE.Mesh(boxGeo3, veinMat);
vein33.name = 'vein3';
vein33.position.set(-0.0471, 0.0135, -0.057);
vein33.rotation.set(0, deg(129.5493), 0);
lily3.add(vein33);
const vein43 = new THREE.Mesh(boxGeo3, veinMat);
vein43.name = 'vein4';
vein43.position.set(-0.0739, 0.0135, 0);
vein43.rotation.set(0, deg(180), 0);
lily3.add(vein43);
const vein53 = new THREE.Mesh(boxGeo3, veinMat);
vein53.name = 'vein5';
vein53.position.set(-0.0471, 0.0135, 0.057);
vein53.rotation.set(0, deg(230.4507), 0);
lily3.add(vein53);
const vein63 = new THREE.Mesh(boxGeo3, veinMat);
vein63.name = 'vein6';
vein63.position.set(0.014, 0.0135, 0.0726);
vein63.rotation.set(0, deg(280.9014), 0);
lily3.add(vein63);
const vein73 = new THREE.Mesh(boxGeo3, veinMat);
vein73.name = 'vein7';
vein73.position.set(0.0648, 0.0135, 0.0354);
vein73.rotation.set(0, deg(331.3521), 0);
lily3.add(vein73);
const lily4 = new THREE.Group();
lily4.name = 'lily4';
lily4.position.set(0.0882, 0, 0.4659);
lily4.rotation.set(0, deg(217.3457), 0);
root.add(lily4);
const pad7 = new THREE.Group();
pad7.name = 'pad';
lily4.add(pad7);
const pad8 = new THREE.Mesh(extrude([[0, 0], [0.1899, -0.058], [0.1424, -0.1383], [0.0635, -0.1881], [-0.0293, -0.1963], [-0.1158, -0.1613], [-0.1766, -0.0906], [-0.1985, 0], [-0.1766, 0.0906], [-0.1158, 0.1613], [-0.0293, 0.1963], [0.0635, 0.1881], [0.1424, 0.1383], [0.1899, 0.058]], 0.012), padLightMat);
pad8.name = 'pad';
pad8.position.set(0, 0.006, 0);
pad8.rotation.set(deg(-90), 0, 0);
pad7.add(pad8);
const vein14 = new THREE.Mesh(boxGeo4, veinMat);
vein14.name = 'vein1';
vein14.position.set(0.0714, 0.0135, -0.039);
vein14.rotation.set(0, deg(28.6479), 0);
lily4.add(vein14);
const vein24 = new THREE.Mesh(boxGeo4, veinMat);
vein24.name = 'vein2';
vein24.position.set(0.0154, 0.0135, -0.0799);
vein24.rotation.set(0, deg(79.0986), 0);
lily4.add(vein24);
const vein34 = new THREE.Mesh(boxGeo4, veinMat);
vein34.name = 'vein3';
vein34.position.set(-0.0518, 0.0135, -0.0628);
vein34.rotation.set(0, deg(129.5493), 0);
lily4.add(vein34);
const vein44 = new THREE.Mesh(boxGeo4, veinMat);
vein44.name = 'vein4';
vein44.position.set(-0.0814, 0.0135, 0);
vein44.rotation.set(0, deg(180), 0);
lily4.add(vein44);
const vein54 = new THREE.Mesh(boxGeo4, veinMat);
vein54.name = 'vein5';
vein54.position.set(-0.0518, 0.0135, 0.0628);
vein54.rotation.set(0, deg(230.4507), 0);
lily4.add(vein54);
const vein64 = new THREE.Mesh(boxGeo4, veinMat);
vein64.name = 'vein6';
vein64.position.set(0.0154, 0.0135, 0.0799);
vein64.rotation.set(0, deg(280.9014), 0);
lily4.add(vein64);
const vein74 = new THREE.Mesh(boxGeo4, veinMat);
vein74.name = 'vein7';
vein74.position.set(0.0714, 0.0135, 0.039);
vein74.rotation.set(0, deg(331.3521), 0);
lily4.add(vein74);
const waterLily = new THREE.Group();
waterLily.name = 'waterLily';
waterLily.position.set(-0.3172, 0.015, 0.0953);
waterLily.rotation.set(0, deg(8.7699), 0);
root.add(waterLily);
const octahedron42 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron42.position.set(0.0785, 0.0435, 0);
octahedron42.rotation.set(0, 0, deg(-72));
octahedron42.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron42);
const octahedron43 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron43.position.set(0.0555, 0.0435, 0.0555);
octahedron43.rotation.set(deg(45.7767), deg(-20.2118), deg(-45.7767));
octahedron43.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron43);
const octahedron44 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron44.position.set(0, 0.0435, 0.0785);
octahedron44.rotation.set(deg(72), 0, 0);
octahedron44.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron44);
const octahedron45 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron45.position.set(-0.0555, 0.0435, 0.0555);
octahedron45.rotation.set(deg(45.7767), deg(20.2118), deg(45.7767));
octahedron45.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron45);
const octahedron46 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron46.position.set(-0.0785, 0.0435, 0);
octahedron46.rotation.set(0, 0, deg(72));
octahedron46.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron46);
const octahedron47 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron47.position.set(-0.0555, 0.0435, -0.0555);
octahedron47.rotation.set(deg(-45.7767), deg(-20.2118), deg(45.7767));
octahedron47.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron47);
const octahedron48 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron48.position.set(0, 0.0435, -0.0785);
octahedron48.rotation.set(deg(-72), 0, 0);
octahedron48.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron48);
const octahedron49 = new THREE.Mesh(octahedronGeo, petalMat);
octahedron49.position.set(0.0555, 0.0435, -0.0555);
octahedron49.rotation.set(deg(-45.7767), deg(20.2118), deg(-45.7767));
octahedron49.scale.set(0.0363, 0.0825, 0.0132);
waterLily.add(octahedron49);
const octahedron50 = new THREE.Mesh(octahedronGeo, petalInnerMat);
octahedron50.position.set(0.0369, 0.0774, 0.0213);
octahedron50.rotation.set(deg(19.6731), deg(-6.3857), deg(-35.669));
octahedron50.scale.set(0.0281, 0.0638, 0.0102);
waterLily.add(octahedron50);
const octahedron51 = new THREE.Mesh(octahedronGeo, petalInnerMat);
octahedron51.position.set(0, 0.0774, 0.0427);
octahedron51.rotation.set(deg(42), 0, 0);
octahedron51.scale.set(0.0281, 0.0638, 0.0102);
waterLily.add(octahedron51);
const octahedron52 = new THREE.Mesh(octahedronGeo, petalInnerMat);
octahedron52.position.set(-0.0369, 0.0774, 0.0213);
octahedron52.rotation.set(deg(19.6731), deg(6.3857), deg(35.669));
octahedron52.scale.set(0.0281, 0.0638, 0.0102);
waterLily.add(octahedron52);
const octahedron53 = new THREE.Mesh(octahedronGeo, petalInnerMat);
octahedron53.position.set(-0.0369, 0.0774, -0.0213);
octahedron53.rotation.set(deg(-19.6731), deg(-6.3857), deg(35.669));
octahedron53.scale.set(0.0281, 0.0638, 0.0102);
waterLily.add(octahedron53);
const octahedron54 = new THREE.Mesh(octahedronGeo, petalInnerMat);
octahedron54.position.set(0, 0.0774, -0.0427);
octahedron54.rotation.set(deg(-42), 0, 0);
octahedron54.scale.set(0.0281, 0.0638, 0.0102);
waterLily.add(octahedron54);
const octahedron55 = new THREE.Mesh(octahedronGeo, petalInnerMat);
octahedron55.position.set(0.0369, 0.0774, -0.0213);
octahedron55.rotation.set(deg(-19.6731), deg(6.3857), deg(-35.669));
octahedron55.scale.set(0.0281, 0.0638, 0.0102);
waterLily.add(octahedron55);
const cylinder56 = new THREE.Mesh(new THREE.CylinderGeometry(0.033, 0.039, 0.045, 6), heartMat);
cylinder56.position.set(0, 0.0405, 0);
waterLily.add(cylinder56);
const bud = new THREE.Group();
bud.name = 'bud';
bud.position.set(0.1179, 0.012, 0.4659);
root.add(bud);
const octahedron58 = new THREE.Mesh(octahedronGeo, budMat);
octahedron58.position.set(0, 0.05, 0);
octahedron58.scale.set(0.035, 0.06, 0.035);
bud.add(octahedron58);
const cylinder59 = new THREE.Mesh(new THREE.CylinderGeometry(0.022, 0.026, 0.02, 6), padMat);
cylinder59.position.set(0, 0.01, 0);
bud.add(cylinder59);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createLilyPad;
Ratings & comments
0 comments
No comments yet. Share how you used this model or what could be better.
Related models
Same category or similar tags









