Spaces:
Running
Running
| import * as THREE from 'three'; | |
| const scene = new THREE.Scene(); | |
| scene.background = new THREE.Color( | |
| // 0xcccccc | |
| 'white' | |
| ); | |
| const clock = new THREE.Clock(); | |
| const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); | |
| camera.position.set(0, 30, 50); | |
| camera.lookAt(0, 3, 0); | |
| const controls = new (<any>THREE).OrbitControls(camera); | |
| const ambientLight = new THREE.AmbientLight(0xffffff, 1); | |
| scene.add(ambientLight); | |
| const renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| document.body.appendChild(renderer.domElement); | |
| const stats = new Stats(); | |
| document.body.appendChild(stats.dom); | |
| /// Anim mixer | |
| const mixers: THREE.AnimationMixer[] = []; | |
| class Assets { | |
| private static loadEggMtl(): Promise<THREE.Material[]> { | |
| return new Promise((resolve, reject) => { | |
| const loader: THREE.AnyLoader = new (<any>THREE).MTLLoader(); | |
| loader.load( | |
| `models/Egg_from_Poly_uovo/Egg from Poly uovo.mtl`, | |
| (materials) => { | |
| materials.preload(); | |
| resolve(materials); | |
| }, | |
| (xhr) => {}, | |
| reject | |
| ); | |
| }); | |
| } | |
| private static loadEggObj(materials: THREE.Material[]): Promise<THREE.Object3D> { | |
| return new Promise((resolve, reject) => { | |
| const loader: THREE.AnyLoader = new (<any>THREE).OBJLoader(); | |
| (<any>loader).setMaterials(materials); | |
| loader.load( | |
| `models/Egg_from_Poly_uovo/Egg from Poly uovo.obj`, | |
| (object: THREE.Object3D) => { | |
| resolve(object); | |
| }, | |
| (xhr) => { | |
| // c.log(`${ xhr.loaded / xhr.total * 100 }% loaded`); | |
| }, | |
| (error) => { | |
| c.error(error); | |
| reject(error); | |
| } | |
| ); | |
| }); | |
| } | |
| static async loadEgg(): Promise<THREE.Object3D> { | |
| const materialCreator = await this.loadEggMtl(); | |
| return this.loadEggObj(materialCreator); | |
| } | |
| static loadEggGltf(): Promise<THREE.Scene> { | |
| return new Promise((resolve, reject) => { | |
| const loader: THREE.AnyLoader = new (<any>THREE).GLTFLoader(); | |
| loader.load( | |
| `models/Egg_gltf/Egg from Poly uovo copy.gltf`, | |
| (gltf) => { | |
| c.log(gltf); | |
| resolve(gltf.scene); | |
| } | |
| ); | |
| }); | |
| } | |
| static loadDogDae(): Promise<{ | |
| animations: THREE.AnimationClip[]; | |
| scene: THREE.Group; | |
| }> { | |
| /// In Dae/Collada: did not manage to get | |
| /// either the anims or the texture. | |
| return new Promise((resolve, reject) => { | |
| const loader: THREE.AnyLoader = new (<any>THREE).ColladaLoader(); | |
| loader.load( | |
| `models/dog/pup_lohound.dae`, | |
| (collada) => { | |
| resolve(collada); | |
| } | |
| ); | |
| }); | |
| } | |
| static loadDogFbx(): Promise<THREE.Group> { | |
| return new Promise((resolve, reject) => { | |
| const loader: THREE.AnyLoader = new (<any>THREE).FBXLoader(); | |
| loader.load( | |
| `models/dog_fbx/puppy-snapchat.fbx`, | |
| (fbx) => { | |
| resolve(fbx); | |
| } | |
| ); | |
| }); | |
| } | |
| } | |
| class Utils { | |
| static boundingBox(o: THREE.Object3D): [THREE.Vector3, THREE.Vector3] { | |
| const bbox = new THREE.Box3().setFromObject(o); | |
| /// vv Just unpack it for easier console logging. | |
| return [bbox.min, bbox.max]; | |
| } | |
| } | |
| (async () => { | |
| /** | |
| * scene construction | |
| */ | |
| const gridHelper = new THREE.GridHelper(100, 100); | |
| scene.add(gridHelper); | |
| const axesHelper = new THREE.AxesHelper(50); | |
| scene.add(axesHelper); | |
| const cube = new THREE.Mesh( | |
| new THREE.BoxGeometry(1, 1, 1), | |
| new THREE.MeshBasicMaterial({ color: 0x00ff00 }) | |
| ); | |
| cube.position.x = 7; | |
| scene.add(cube); | |
| { | |
| const egg = await Assets.loadEgg(); | |
| c.log(egg); | |
| egg.scale.setScalar(.2); | |
| egg.rotateX(-Math.PI / 2); | |
| const box = new THREE.BoxHelper(egg); | |
| scene.add(box); | |
| scene.add(egg); | |
| ///// Manually set the material, for fun. | |
| // const eggFace = egg.getObjectByName("CallKit-IconMask") as THREE.Mesh; | |
| // c.log(eggFace.material); | |
| // (<THREE.MeshPhongMaterial>(eggFace.material)).color.set(0x000000); | |
| } | |
| { | |
| const egg = await Assets.loadEggGltf(); | |
| c.log(egg); | |
| egg.scale.setScalar(100); | |
| egg.position.x = -10; | |
| egg.remove(egg.getObjectByName('Camera')!); | |
| scene.add(egg); | |
| // c.log(Utils.boundingBox(egg)); | |
| const box = new THREE.BoxHelper(egg, new THREE.Color('red')); | |
| scene.add(box); | |
| } | |
| { | |
| ////// dog_fbx | |
| const dog = await Assets.loadDogFbx(); | |
| // c.log((<any>dog).animations); | |
| const mixer = new THREE.AnimationMixer(dog); | |
| const clip: THREE.AnimationClip = (<any>dog).animations.find(clip => clip.name === "lohound|lohoundAction"); | |
| /// ^^ this is the main parent animation! Do not play all children. | |
| c.log(clip); | |
| mixer.clipAction(clip).play(); | |
| mixers.push(mixer); | |
| const container = new THREE.Group(); | |
| container.add(dog); | |
| container.scale.setScalar(0.007); /// <- scale a container, not the dog itself or it'll fuck the anims. | |
| container.position.x = 12; | |
| scene.add(container); | |
| const box = new THREE.BoxHelper(container, new THREE.Color('green')); | |
| scene.add(box); | |
| } | |
| // const geometry = new THREE.CylinderBufferGeometry( 0, 10, 30, 4, 1 ); | |
| // const material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ); | |
| // for ( let i = 0; i < 500; i ++ ) { | |
| // const mesh = new THREE.Mesh( geometry, material ); | |
| // mesh.position.x = Math.random() * 1600 - 800; | |
| // mesh.position.y = 0; | |
| // mesh.position.z = Math.random() * 1600 - 800; | |
| // mesh.updateMatrix(); | |
| // mesh.matrixAutoUpdate = false; | |
| // scene.add( mesh ); | |
| // } | |
| })(); | |
| /** | |
| * MAIN() | |
| */ | |
| window.addEventListener('resize', onWindowResize, false); | |
| function onWindowResize() { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| function render() { | |
| const delta = clock.getDelta(); | |
| for (const mixer of mixers) { | |
| mixer.update(delta); | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| render(); | |
| stats.update(); | |
| } | |
| animate(); | |