代码拉取完成,页面将自动刷新
import * as THREE from 'three';
const {
performance,
document,
window,
HTMLCanvasElement,
requestAnimationFrame,
cancelAnimationFrame,
core,
Event,
Event0
} = THREE .DHTML
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { OrbitControls0 } from 'three/examples/jsm/controls/OrbitControls0.js';
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
import { LDrawLoader } from 'three/examples/jsm/loaders/LDrawLoader.js';
import { LDrawUtils } from 'three/examples/jsm/utils/LDrawUtils.js';
var requestId
Page({
onUnload() {
cancelAnimationFrame(requestId, this.canvas)
this.worker && this.worker.terminate()
if(this.canvas) this.canvas = null
setTimeout(() => {
if (this.renderer instanceof THREE.WebGLRenderer) {
this.renderer.dispose()
this.renderer.forceContextLoss()
this.renderer.context = null
this.renderer.domElement = null
this.renderer = null
}
}, 10)
},
webgl_touch(e){
const web_e = (window.platform=="devtools"?Event:Event0).fix(e)
this.canvas.dispatchEvent(web_e)
},
onLoad() {
document.createElementAsync("canvas", "webgl2",this).then(canvas => {
this.canvas = canvas
this.body_load(canvas).then()
})
},
async body_load(canvas3d) {
let container, progressBarDiv;
let camera, scene, renderer, controls, gui, guiData;
let model;
const ldrawPath = 'models/ldraw/officialLibrary/';
const modelFileList = {
'Car': 'models/car.ldr_Packed.mpd',
'Lunar Vehicle': 'models/1621-1-LunarMPVVehicle.mpd_Packed.mpd',
'Radar Truck': 'models/889-1-RadarTruck.mpd_Packed.mpd',
'Trailer': 'models/4838-1-MiniVehicles.mpd_Packed.mpd',
'Bulldozer': 'models/4915-1-MiniConstruction.mpd_Packed.mpd',
'Helicopter': 'models/4918-1-MiniFlyers.mpd_Packed.mpd',
'Plane': 'models/5935-1-IslandHopper.mpd_Packed.mpd',
'Lighthouse': 'models/30023-1-Lighthouse.ldr_Packed.mpd',
'X-Wing mini': 'models/30051-1-X-wingFighter-Mini.mpd_Packed.mpd',
'AT-ST mini': 'models/30054-1-AT-ST-Mini.mpd_Packed.mpd',
'AT-AT mini': 'models/4489-1-AT-AT-Mini.mpd_Packed.mpd',
'Shuttle': 'models/4494-1-Imperial Shuttle-Mini.mpd_Packed.mpd',
'TIE Interceptor': 'models/6965-1-TIEIntercep_4h4MXk5.mpd_Packed.mpd',
'Star fighter': 'models/6966-1-JediStarfighter-Mini.mpd_Packed.mpd',
'X-Wing': 'models/7140-1-X-wingFighter.mpd_Packed.mpd',
'AT-ST': 'models/10174-1-ImperialAT-ST-UCS.mpd_Packed.mpd'
};
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 150, 200, 250 );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
container.appendChild( renderer.domElement );
// scene
const pmremGenerator = new THREE.PMREMGenerator( renderer );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xdeebed );
scene.environment = pmremGenerator.fromScene( new RoomEnvironment( renderer ) ).texture;
controls = new (window.platform=="devtools"?OrbitControls:OrbitControls0)( camera, renderer.domElement );
controls.enableDamping = true;
//
guiData = {
modelFileName: modelFileList[ 'Car' ],
displayLines: true,
conditionalLines: true,
smoothNormals: true,
buildingStep: 0,
noBuildingSteps: 'No steps.',
flatColors: false,
mergeModel: false
};
window.addEventListener( 'resize', onWindowResize );
progressBarDiv = document.createElement( 'div' );
progressBarDiv.innerText = 'Loading...';
progressBarDiv.style.fontSize = '3em';
progressBarDiv.style.color = '#888';
progressBarDiv.style.display = 'block';
progressBarDiv.style.position = 'absolute';
progressBarDiv.style.top = '50%';
progressBarDiv.style.width = '100%';
progressBarDiv.style.textAlign = 'center';
// load materials and then the model
reloadObject( true );
}
function updateObjectsVisibility() {
model.traverse( c => {
if ( c.isLineSegments ) {
if ( c.isConditionalLine ) {
c.visible = guiData.conditionalLines;
} else {
c.visible = guiData.displayLines;
}
} else if ( c.isGroup ) {
// Hide objects with building step > gui setting
c.visible = c.userData.buildingStep <= guiData.buildingStep;
}
} );
}
function reloadObject( resetCamera ) {
if ( model ) {
scene.remove( model );
}
model = null;
updateProgressBar( 0 );
showProgressBar();
// only smooth when not rendering with flat colors to improve processing time
const lDrawLoader = new LDrawLoader();
lDrawLoader.smoothNormals = guiData.smoothNormals && ! guiData.flatColors;
lDrawLoader
.setPath( ldrawPath )
.load( guiData.modelFileName, function ( group2 ) {
if ( model ) {
scene.remove( model );
}
model = group2;
// demonstrate how to use convert to flat colors to better mimic the lego instructions look
if ( guiData.flatColors ) {
function convertMaterial( material ) {
const newMaterial = new THREE.MeshBasicMaterial();
newMaterial.color.copy( material.color );
newMaterial.polygonOffset = material.polygonOffset;
newMaterial.polygonOffsetUnits = material.polygonOffsetUnits;
newMaterial.polygonOffsetFactor = material.polygonOffsetFactor;
newMaterial.opacity = material.opacity;
newMaterial.transparent = material.transparent;
newMaterial.depthWrite = material.depthWrite;
newMaterial.toneMapping = false;
return newMaterial;
}
model.traverse( c => {
if ( c.isMesh ) {
if ( Array.isArray( c.material ) ) {
c.material = c.material.map( convertMaterial );
} else {
c.material = convertMaterial( c.material );
}
}
} );
}
// Merge model geometries by material
if ( guiData.mergeModel ) model = LDrawUtils.mergeObject( model );
// Convert from LDraw coordinates: rotate 180 degrees around OX
model.rotation.x = Math.PI;
scene.add( model );
guiData.buildingStep = model.userData.numBuildingSteps - 1;
updateObjectsVisibility();
// Adjust camera and light
const bbox = new THREE.Box3().setFromObject( model );
const size = bbox.getSize( new THREE.Vector3() );
const radius = Math.max( size.x, Math.max( size.y, size.z ) ) * 0.5;
if ( resetCamera ) {
controls.target0.copy( bbox.getCenter( new THREE.Vector3() ) );
controls.position0.set( - 2.3, 1, 2 ).multiplyScalar( radius ).add( controls.target0 );
controls.reset();
}
createGUI();
hideProgressBar();
}, onProgress, onError );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function createGUI() {
if ( gui ) {
gui.destroy();
}
gui = new GUI();
gui.add( guiData, 'modelFileName', modelFileList ).name( 'Model' ).onFinishChange( function () {
reloadObject( true );
} );
gui.add( guiData, 'flatColors' ).name( 'Flat Colors' ).onChange( function () {
reloadObject( false );
} );
gui.add( guiData, 'mergeModel' ).name( 'Merge model' ).onChange( function () {
reloadObject( false );
} );
if ( model.userData.numBuildingSteps > 1 ) {
gui.add( guiData, 'buildingStep', 0, model.userData.numBuildingSteps - 1 ).step( 1 ).name( 'Building step' ).onChange( updateObjectsVisibility );
} else {
gui.add( guiData, 'noBuildingSteps' ).name( 'Building step' ).onChange( updateObjectsVisibility );
}
gui.add( guiData, 'smoothNormals' ).name( 'Smooth Normals' ).onChange( function changeNormals() {
reloadObject( false );
} );
gui.add( guiData, 'displayLines' ).name( 'Display Lines' ).onChange( updateObjectsVisibility );
gui.add( guiData, 'conditionalLines' ).name( 'Conditional Lines' ).onChange( updateObjectsVisibility );
}
//
function animate() {
requestId = requestAnimationFrame( animate );
controls.update();
render();
}
function render() {
renderer.render( scene, camera );
}
function onProgress( xhr ) {
if ( xhr.lengthComputable ) {
updateProgressBar( xhr.loaded / xhr.total );
console.log( Math.round( xhr.loaded / xhr.total * 100, 2 ) + '% downloaded' );
}
}
function onError( error ) {
const message = 'Error loading model';
progressBarDiv.innerText = message;
console.log( message );
console.error( error );
}
function showProgressBar() {
document.body.appendChild( progressBarDiv );
}
function hideProgressBar() {
document.body.removeChild( progressBarDiv );
}
function updateProgressBar( fraction ) {
progressBarDiv.innerText = 'Loading... ' + Math.round( fraction * 100, 2 ) + '%';
}
}
})
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。