980 tris14.9 × 2.88 × 7.18 m
Use it in code
Remix in the editorglider.js · 196 lines
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
* Glider Sailplane — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 980 · Size (W × H × D): 14.91 × 2.88 × 7.18 m
*
* Usage:
* import { createGlider } from './glider.js';
*
* const model = createGlider();
* 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);
}
// 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 createGlider() {
const root = new THREE.Group();
root.name = 'Glider';
// Materials
const paintMat = new THREE.MeshStandardMaterial({ name: 'paint', color: 0xf3f2ee, roughness: 0.4, metalness: 0.05, flatShading: true });
const accentMat = new THREE.MeshStandardMaterial({ name: 'accent', color: 0xd8443a, roughness: 0.45, metalness: 0.05, flatShading: true });
const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0x25313e, roughness: 0.2, metalness: 0.35 });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2b2e33, roughness: 0.7, metalness: 0.2, flatShading: true });
const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0xa7adb5, roughness: 0.4, metalness: 0.6, flatShading: true });
// Shared geometries
const extrudeGeo = extrude([[0.08, 0], [-0.08, 0.42], [-0.2, 0.42], [-0.18, 0]], 0.03, [], [0.01, 0.01, 1]);
const boxGeo = new THREE.BoxGeometry(1.1, 0.012, 0.07);
const boxGeo2 = new THREE.BoxGeometry(2.625, 0.012, 0.025);
// Parts
const glider = new THREE.Group();
glider.name = 'glider';
glider.position.set(0, 0.0176, -0.1);
glider.rotation.set(deg(-3.5228), deg(0.5605), deg(-9.029));
root.add(glider);
const airframe = new THREE.Group();
airframe.name = 'airframe';
airframe.position.set(0, 0, 0.1);
glider.add(airframe);
const fuselage = new THREE.Mesh(lathe([[0, -4.3], [0.08, -4.25], [0.11, -3.4], [0.14, -2.2], [0.2, -1.3], [0.31, -0.55], [0.36, 0.3], [0.36, 1], [0.33, 1.7], [0.26, 2.25], [0.15, 2.58]], 12), paintMat);
fuselage.name = 'fuselage';
fuselage.position.set(0, 0.62, 0);
fuselage.rotation.set(deg(90), 0, 0);
fuselage.scale.set(1, 1, 1.15);
airframe.add(fuselage);
const noseCap = new THREE.Mesh(lathe([[0.15, 2.58], [0.07, 2.72], [0, 2.75]], 12), accentMat);
noseCap.name = 'noseCap';
noseCap.position.set(0, 0.62, 0);
noseCap.rotation.set(deg(90), 0, 0);
noseCap.scale.set(1, 1, 1.15);
airframe.add(noseCap);
const towHook = new THREE.Mesh(new THREE.BoxGeometry(0.03, 0.03, 0.12), darkMat);
towHook.name = 'towHook';
towHook.position.set(0, 0.46, 2.62);
airframe.add(towHook);
const canopy = new THREE.Mesh(new THREE.SphereGeometry(0.3, 12, 5, 0, Math.PI * 2, 0, Math.PI / 2), glassMat);
canopy.name = 'canopy';
canopy.position.set(0, 0.8, 1.3);
canopy.scale.set(1.06, 1.08, 3);
airframe.add(canopy);
const canopyFrame = new THREE.Mesh(new THREE.BoxGeometry(0.66, 0.05, 0.05), darkMat);
canopyFrame.name = 'canopyFrame';
canopyFrame.position.set(0, 0.98, 0.42);
airframe.add(canopyFrame);
const wingL = new THREE.Group();
wingL.name = 'wingL';
wingL.position.set(0, 0.92, 0);
wingL.rotation.set(0, 0, deg(2.5));
airframe.add(wingL);
const wingPanel = new THREE.Mesh(extrude([[0, 0.36], [3.375, 0.3], [7.2, 0.13], [7.5, 0.07], [7.5, -0.17], [7.2, -0.2], [3.375, -0.38], [0, -0.6]], 0.07, [], [0.02, 0.02, 1]), paintMat);
wingPanel.name = 'wingPanel';
wingPanel.rotation.set(deg(90), 0, 0);
wingL.add(wingPanel);
const wingTip = new THREE.Mesh(extrude([[6.6, 0.1567], [7.2, 0.13], [7.5, 0.07], [7.5, -0.17], [7.2, -0.2], [6.6, -0.2282]], 0.09, [], [0.02, 0.02, 1]), accentMat);
wingTip.name = 'wingTip';
wingTip.rotation.set(deg(90), 0, 0);
wingL.add(wingTip);
const winglet = new THREE.Mesh(extrudeGeo, accentMat);
winglet.name = 'winglet';
winglet.position.set(7.51, 0.03, 0);
winglet.rotation.set(0, deg(-90), 0);
wingL.add(winglet);
const airbrake = new THREE.Mesh(boxGeo, darkMat);
airbrake.name = 'airbrake';
airbrake.position.set(2.65, 0.062, -0.08);
wingL.add(airbrake);
const aileronLine = new THREE.Mesh(boxGeo2, darkMat);
aileronLine.name = 'aileronLine';
aileronLine.position.set(5.4, 0.062, -0.22);
wingL.add(aileronLine);
const wingR = new THREE.Group();
wingR.name = 'wingR';
wingR.position.set(0, 0.92, 0);
wingR.rotation.set(0, 0, deg(-2.5));
airframe.add(wingR);
const wingPanel2 = new THREE.Mesh(extrude([[0, 0.36], [-3.375, 0.3], [-7.2, 0.13], [-7.5, 0.07], [-7.5, -0.17], [-7.2, -0.2], [-3.375, -0.38], [0, -0.6]], 0.07, [], [0.02, 0.02, 1]), paintMat);
wingPanel2.name = 'wingPanel';
wingPanel2.rotation.set(deg(90), 0, 0);
wingR.add(wingPanel2);
const wingTip2 = new THREE.Mesh(extrude([[-6.6, 0.1567], [-7.2, 0.13], [-7.5, 0.07], [-7.5, -0.17], [-7.2, -0.2], [-6.6, -0.2282]], 0.09, [], [0.02, 0.02, 1]), accentMat);
wingTip2.name = 'wingTip';
wingTip2.rotation.set(deg(90), 0, 0);
wingR.add(wingTip2);
const winglet2 = new THREE.Mesh(extrudeGeo, accentMat);
winglet2.name = 'winglet';
winglet2.position.set(-7.51, 0.03, 0);
winglet2.rotation.set(0, deg(-90), 0);
wingR.add(winglet2);
const airbrake2 = new THREE.Mesh(boxGeo, darkMat);
airbrake2.name = 'airbrake';
airbrake2.position.set(-2.65, 0.062, -0.08);
wingR.add(airbrake2);
const aileronLine2 = new THREE.Mesh(boxGeo2, darkMat);
aileronLine2.name = 'aileronLine';
aileronLine2.position.set(-5.4, 0.062, -0.22);
wingR.add(aileronLine2);
const fin = new THREE.Mesh(extrude([[-3.2, 0.05], [-3.85, 1.2], [-4.12, 1.22], [-4.06, -0.05]], 0.06, [], [0.015, 0.015, 1]), paintMat);
fin.name = 'fin';
fin.position.set(0, 0.62, 0);
fin.rotation.set(0, deg(-90), 0);
airframe.add(fin);
const rudder = new THREE.Group();
rudder.name = 'rudder';
rudder.position.set(0, 0.62, -4.08);
airframe.add(rudder);
const rudderPanel = new THREE.Mesh(extrude([[0, 0.02], [0, 1.2], [-0.28, 1.2], [-0.36, -0.08]], 0.075, [], [0.01, 0.01, 1]), accentMat);
rudderPanel.name = 'rudderPanel';
rudderPanel.rotation.set(0, deg(-90), 0);
rudder.add(rudderPanel);
const stabilizer = new THREE.Mesh(extrude([[-1.45, -4.18], [-1.38, -3.92], [0, -3.7], [1.38, -3.92], [1.45, -4.18], [0, -4.3]], 0.04, [], [0.012, 0.012, 1]), paintMat);
stabilizer.name = 'stabilizer';
stabilizer.position.set(0, 1.84, 0);
stabilizer.rotation.set(deg(90), 0, 0);
airframe.add(stabilizer);
const pitot = new THREE.Mesh(new THREE.BoxGeometry(0.03, 0.03, 0.3), metalMat);
pitot.name = 'pitot';
pitot.position.set(0, 1.62, -3.6);
airframe.add(pitot);
const wheelWell = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.08, 0.5), darkMat);
wheelWell.name = 'wheelWell';
wheelWell.position.set(0, 0.27, -0.1);
airframe.add(wheelWell);
const mainWheel = new THREE.Group();
mainWheel.name = 'mainWheel';
mainWheel.position.set(0, 0.19, -0.1);
airframe.add(mainWheel);
const tire = new THREE.Mesh(new THREE.CylinderGeometry(0.19, 0.19, 0.11, 12), darkMat);
tire.name = 'tire';
tire.rotation.set(0, 0, deg(90));
mainWheel.add(tire);
const hub = new THREE.Mesh(new THREE.CylinderGeometry(0.08, 0.08, 0.12, 8), metalMat);
hub.name = 'hub';
hub.rotation.set(0, 0, deg(90));
mainWheel.add(hub);
const tailWheelStrut = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.2, 0.08), metalMat);
tailWheelStrut.name = 'tailWheelStrut';
tailWheelStrut.position.set(0, 0.42, -3.95);
airframe.add(tailWheelStrut);
const tailWheel = new THREE.Group();
tailWheel.name = 'tailWheel';
tailWheel.position.set(0, 0.32, -3.95);
airframe.add(tailWheel);
const tire2 = new THREE.Mesh(new THREE.CylinderGeometry(0.08, 0.08, 0.05, 8), darkMat);
tire2.name = 'tire';
tire2.rotation.set(0, 0, deg(90));
tailWheel.add(tire2);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createGlider;
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









