加载各种模型
<canvas id="mainCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "./js/build/three.module.js",
"three/addons/": "./js/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight } from "./init.js";
import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
import { MTLLoader } from "three/addons/loaders/MTLLoader.js";
import { ColladaLoader } from "three/addons/loaders/ColladaLoader.js";
import { STLLoader } from "three/addons/loaders/STLLoader.js";
import { VTKLoader } from "three/addons/loaders/VTKLoader.js";
import { PDBLoader } from "three/addons/loaders/PDBLoader.js";
import { PLYLoader } from "three/addons/loaders/PLYLoader.js";
import { VRMLLoader } from "three/addons/loaders/VRMLLoader.js";
import { TDSLoader } from "three/addons/loaders/TDSLoader.js";
import { ThreeMFLoader } from "three/addons/loaders/3MFLoader.js";
import { AMFLoader } from "three/addons/loaders/AMFLoader.js";
import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
import { GCodeLoader } from "three/addons/loaders/GCodeLoader.js";
import { SVGLoader } from "three/addons/loaders/SVGLoader.js";
function init() {
const gui = new GUI();
const renderer = initRenderer("mainCanvas");
let scene = new THREE.Scene();
const camera = initPerspectiveCamera();
scene.add(camera);
let ambientLight = initAmbientLight();
scene.add(ambientLight);
let spotLight = initSpotLight();
scene.add(spotLight);
let knot = createMesh(new THREE.TorusKnotGeometry(10, 1, 64, 8, 2, 3));
scene.add(knot);
const controls = setupControls();
let step = 0;
let loadedMesh;
render();
function render() {
knot.rotation.y = step += 0.01;
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function setupControls() {
const controls = new (function () {
this.radius = knot.geometry.parameters.radius;
this.tube = 0.3;
this.radialSegments = knot.geometry.parameters.radialSegments;
this.tubularSegments = knot.geometry.parameters.tubularSegments;
this.p = knot.geometry.parameters.p;
this.q = knot.geometry.parameters.q;
this.redraw = function () {
scene.remove(knot);
knot = createMesh(
new THREE.TorusKnotGeometry(controls.radius, controls.tube, Math.round(controls.radialSegments), Math.round(controls.tubularSegments), Math.round(controls.p), Math.round(controls.q))
);
scene.add(knot);
};
this.saveMesh = function () {
const result = knot.toJSON();
sessionStorage.setItem("mesh", JSON.stringify(result));
console.log(sessionStorage.getItem("mesh"));
};
this.loadMesh = function () {
scene.remove(loadedMesh);
const json = sessionStorage.getItem("mesh");
if (json) {
const loadedGeometry = JSON.parse(json);
const loader = new THREE.ObjectLoader();
loadedMesh = loader.parse(loadedGeometry);
loadedMesh.position.x -= 40;
scene.add(loadedMesh);
}
};
this.exportScene = function () {
sessionStorage.setItem("scene", JSON.stringify(scene.toJSON()));
console.log(sessionStorage.getItem("scene"));
};
this.clearScene = function () {
scene = new THREE.Scene();
ambientLight = initAmbientLight();
scene.add(ambientLight);
spotLight = initSpotLight();
scene.add(spotLight);
};
this.importScene = function () {
const json = sessionStorage.getItem("scene");
if (json) {
const loadedSceneAsJson = JSON.parse(json);
const loader = new THREE.ObjectLoader();
scene = loader.parse(loadedSceneAsJson);
}
};
this.loadFromJson = function () {
const loader = new THREE.ObjectLoader();
loader.load("./models/lightmap/lightmap.json", function (obj) {
computeSize(obj);
console.log("obj scale", obj.scale);
computeSize(scene);
obj.scale.set(5, 5, 5);
scene.add(obj);
});
};
this.loadFromObj = function () {
// OBJ加载器 用于加载 .obj 资源的加载器。
// OBJ 文件格式是一种简单的数据格式, 这种格式以人类可读的形式来表示3D几何体,即每个顶点的位置、每个纹理坐标顶点的UV位置、顶点法线、 将使每个多边形定义为顶点列表的面以及纹理顶点。
const loader = new OBJLoader();
loader.load("./models/tree.obj", function (obj) {
computeSize(obj);
console.log("obj scale", obj.scale);
computeSize(scene);
obj.scale.set(20, 20, 20);
scene.add(obj);
});
};
this.loadFromObjMtl = function () {
const mtlLoader = new MTLLoader();
mtlLoader.load("./models/walt/WaltHead.mtl", function (materials) {
materials.preload();
const loader = new OBJLoader();
loader.load("./models/walt/WaltHead.obj", function (obj) {
computeSize(obj);
console.log("obj scale", obj.scale);
computeSize(scene);
obj.scale.set(0.2, 0.2, 0.2);
scene.add(obj);
});
});
};
this.loadFromCollada = function () {
const loader = new ColladaLoader();
loader.load("./models/pump/pump.dae", function (res) {
const sceneGroup = res.scene;
sceneGroup.children.forEach(function (child) {
if (child instanceof THREE.Mesh) {
child.receiveShadow = true;
child.castShadow = true;
} else {
sceneGroup.remove(child);
}
});
sceneGroup.rotation.z = 0.5 * Math.PI;
sceneGroup.scale.set(8, 8, 8);
scene = sceneGroup;
});
};
this.loadFromStl = function () {
const loader = new STLLoader();
loader.load("./models/stl/ascii/slotted_disk.stl", function (geometry) {
const mat = new THREE.MeshStandardMaterial({
color: 0xffffff,
metalness: 1,
roughness: 0.5,
});
const mesh = new THREE.Mesh(geometry, mat);
mesh.rotation.x = -0.5 * Math.PI;
mesh.scale.set(20, 20, 20);
computeSize(mesh);
computeSize(scene);
scene.add(mesh);
});
};
this.loadFromVtk = function () {
const loader = new VTKLoader();
loader.load("./models/vtk/liver.vtk", function (geometry) {
const mat = new THREE.MeshNormalMaterial();
geometry.center();
geometry.computeVertexNormals();
const mesh = new THREE.Mesh(geometry, mat);
mesh.scale.set(0.3, 0.3, 0.3);
computeSize(mesh);
computeSize(scene);
scene.add(mesh);
});
};
this.loadFromPdb = function () {
const loader = new PDBLoader();
loader.load("./models/diamond.pdb", function (geometries) {
const group = new THREE.Object3D();
const geometryAtoms = geometries.geometryAtoms;
for (let i = 0; i < geometryAtoms.attributes.position.count; i++) {
const startPosition = new THREE.Vector3();
startPosition.x = geometryAtoms.attributes.position.getX(i);
startPosition.y = geometryAtoms.attributes.position.getY(i);
startPosition.z = geometryAtoms.attributes.position.getZ(i);
const color = new THREE.Color();
color.r = geometryAtoms.attributes.color.getX(i);
color.g = geometryAtoms.attributes.color.getY(i);
color.b = geometryAtoms.attributes.color.getZ(i);
const material = new THREE.MeshPhongMaterial({
color: color,
});
const sphere = new THREE.SphereGeometry(0.2);
const mesh = new THREE.Mesh(sphere, material);
mesh.position.copy(startPosition);
group.add(mesh);
}
const geometryBonds = geometries.geometryBonds;
for (let j = 0; j < geometryBonds.attributes.position.count; j += 2) {
const startPosition = new THREE.Vector3();
startPosition.x = geometryBonds.attributes.position.getX(j);
startPosition.y = geometryBonds.attributes.position.getY(j);
startPosition.z = geometryBonds.attributes.position.getZ(j);
const endPosition = new THREE.Vector3();
endPosition.x = geometryBonds.attributes.position.getX(j + 1);
endPosition.y = geometryBonds.attributes.position.getY(j + 1);
endPosition.z = geometryBonds.attributes.position.getZ(j + 1);
const path = new THREE.CatmullRomCurve3([startPosition, endPosition]);
const tube = new THREE.TubeGeometry(path, 1, 0.04);
const material = new THREE.MeshPhongMaterial({
color: 0xcccccc,
});
const mesh = new THREE.Mesh(tube, material);
group.add(mesh);
}
computeSize(scene);
computeSize(group);
group.scale.set(2, 2, 2);
scene.add(group);
});
};
this.loadFromPly = function () {
const loader = new PLYLoader();
loader.load("./models/ply/ascii/dolphins.ply", function (geometry) {
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 1,
opacity: 0.6,
transparent: true,
blending: THREE.AdditiveBlending,
depthWrite: false,
map: generateSprite(),
});
const group = new THREE.Points(geometry, material);
group.scale.set(0.05, 0.05, 0.05);
computeSize(scene);
computeSize(group);
scene.add(group);
});
};
this.loadFromVrml = function () {
const loader = new VRMLLoader();
loader.load("./models/house.wrl", function (model) {
computeSize(model);
computeSize(scene);
console.log("model scale", model.scale, model);
console.log("scene", scene);
model.scale.set(0.05, 0.05, 0.05);
// model.scale.set(25, 25, 25);
// scene.add(model);
scene = model;
// renderer.render(model, camera);
});
};
this.loadFromTds = function () {
const loader = new TDSLoader();
loader.load("./models/3ds/portalgun/portalgun.3ds", function (group) {
computeSize(group);
group.scale.set(20, 20, 20);
scene.add(group);
});
};
this.loadFrom3mf = function () {
const loader = new ThreeMFLoader();
loader.load("./models/truck.3mf", function (group) {
computeSize(group);
scene.add(group);
});
};
this.loadFromAmf = function () {
const loader = new AMFLoader();
loader.load("./models/rook.amf", function (group) {
computeSize(group);
group.scale.set(5, 5, 5);
scene.add(group);
});
};
this.loadFromDrc = function () {
// DRACOLoader 一个用于加载经过Draco压缩的图形库。
// Draco是一个开源的库,主要用于压缩和解压缩三维模型及点云。 以客户端上解压缩为代价,显著减少压缩的图形。
// 独立的Draco文件后缀为.drc,其中包含顶点坐标,法线,颜色和其他的属性,不包含材质,纹理,动画和节点结构。
const loader = new DRACOLoader();
loader.setDecoderPath("./js/jsm/libs/draco/");
loader.setDecoderConfig({ type: "js" });
loader.preload();
loader.load("./models/bunny.drc", function (geometry) {
geometry.computeVertexNormals();
geometry.computeBoundingSphere();
geometry.computeBoundingBox();
const mesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial());
computeSize(mesh);
mesh.scale.set(100, 100, 100);
scene.add(mesh);
});
};
this.loadFromGcode = function () {
const loader = new GCodeLoader();
loader.load("./models/benchy.gcode", function (obj) {
computeSize(obj);
obj.scale.set(0.1, 0.1, 0.1);
scene.add(obj);
});
};
this.loadFromSvg = function () {
// SVGLoader 用于加载.svg资源的加载器
// 可伸缩向量图形是XML形式的矢量图形格式,用来描述二维矢量图形并支持交互和动画。
const loader = new SVGLoader();
loader.load("./models/tiger.svg", function (data) {
const paths = data.paths;
const group = new THREE.Group();
group.scale.multiplyScalar(0.1);
group.scale.y *= -1;
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
const material = new THREE.MeshBasicMaterial({
color: path.color,
side: THREE.DoubleSide,
depthWrite: false,
});
const shapes = path.toShapes(true);
for (let j = 0; j < shapes.length; j++) {
const shape = shapes[j];
const geometry = new THREE.ShapeGeometry(shape);
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
}
}
computeSize(group);
scene.add(group);
});
};
})();
const ioGui = gui.addFolder("Save & Load");
ioGui.add(controls, "exportScene");
ioGui.add(controls, "clearScene");
ioGui.add(controls, "importScene");
ioGui.add(controls, "saveMesh").onChange(controls.saveMesh);
ioGui.add(controls, "loadMesh").onChange(controls.loadMesh);
ioGui.add(controls, "loadFromJson").onChange(controls.loadFromJson);
ioGui.add(controls, "loadFromObj").onChange(controls.loadFromObj);
ioGui.add(controls, "loadFromObjMtl").onChange(controls.loadFromObjMtl);
ioGui.add(controls, "loadFromCollada").onChange(controls.loadFromCollada);
ioGui.add(controls, "loadFromStl").onChange(controls.loadFromStl);
ioGui.add(controls, "loadFromVtk").onChange(controls.loadFromVtk);
ioGui.add(controls, "loadFromPdb").onChange(controls.loadFromPdb);
ioGui.add(controls, "loadFromPly").onChange(controls.loadFromPly);
ioGui.add(controls, "loadFromVrml").onChange(controls.loadFromVrml);
ioGui.add(controls, "loadFromTds").onChange(controls.loadFromTds);
ioGui.add(controls, "loadFrom3mf").onChange(controls.loadFrom3mf);
ioGui.add(controls, "loadFromAmf").onChange(controls.loadFromAmf);
ioGui.add(controls, "loadFromDrc").onChange(controls.loadFromDrc);
ioGui.add(controls, "loadFromGcode").onChange(controls.loadFromGcode);
ioGui.add(controls, "loadFromSvg").onChange(controls.loadFromSvg);
const meshGui = gui.addFolder("mesh");
meshGui.add(controls, "radius", 0, 40).onChange(controls.redraw);
meshGui.add(controls, "tube", 0, 40).onChange(controls.redraw);
meshGui.add(controls, "radialSegments", 1, 400).step(1).onChange(controls.redraw);
meshGui.add(controls, "tubularSegments", 1, 20).step(1).onChange(controls.redraw);
meshGui.add(controls, "p", 1, 10).step(1).onChange(controls.redraw);
meshGui.add(controls, "q", 1, 15).step(1).onChange(controls.redraw);
return controls;
}
}
init();
function createMesh(geom) {
const meshMaterial = new THREE.MeshBasicMaterial({
vertexColors: false,
wireframe: true,
wireframeLinewidth: 2,
color: 0xaaaaaa,
});
meshMaterial.side = THREE.DoubleSide;
const mesh = new THREE.Mesh(geom, meshMaterial);
mesh.position.set(20, 0, 0);
return mesh;
}
function computeSize(obj) {
const cbox = new THREE.Box3().setFromObject(obj);
const size = cbox.getSize(new THREE.Vector3());
if (obj instanceof THREE.Scene) {
console.log("scene size", size);
} else {
console.log("obj size", size);
}
}
function generateSprite() {
const canvas = document.createElement("canvas");
canvas.width = 16;
canvas.height = 16;
const context = canvas.getContext("2d");
const gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, "rgba(255,255,255,1)");
gradient.addColorStop(0.2, "rgba(0,255,255,1)");
gradient.addColorStop(0.4, "rgba(0,0,64,1)");
gradient.addColorStop(1, "rgba(0,0,0,1)");
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
const texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return texture;
}
</script>
标签:function,const,three,controls,js,add,new,scene,加载 From: https://www.cnblogs.com/caroline2016/p/18208927