UNPKG

@vrspace/babylonjs

Version:

vrspace.org babylonjs client

189 lines (164 loc) 6.95 kB
import { VRSPACEUI, HumanoidAvatar } from './js/vrspace-min.js'; import { AvatarSelection } from './avatar-selection.js' var selectButtons = []; var avatars = []; export class AvatarLoader extends AvatarSelection { constructor() { super(); this.enableLogin = false; } createSelection() { this.manager = new BABYLON.GUI.GUI3DManager(scene); VRSPACEUI.debug = true; VRSPACEUI.listMatchingFiles( '../content/char/', (folders) => { var listed = 0; for ( var i = 0; i < folders.length; i++ ) { VRSPACEUI.listCharacters( folders[i].url(), (avatarDirs) => { avatars = avatars.concat(avatarDirs); if ( ++listed == folders.length ) { this.showWorld(); } }); } }); } showWorld() { console.log("Avatars available: "+avatars.length); var circumference = 2*avatars.length; // 2m for each avatar var radius = circumference/Math.PI/2; var angleIncrement = 2*Math.PI/avatars.length; var angle = 0; this.room.setDiameter(2.2*radius); for ( var i=0; i < avatars.length; i++ ) { var x = Math.sin(angle)*radius; var z = Math.cos(angle)*radius; var pos = new BABYLON.Vector3(x,0,z); this.loadAvatar( avatars[i], pos, angle, this.indicator, (avatar) => this.createAvatarUI(avatar,this.manager) ); angle += angleIncrement; } } loadAvatar( dir, pos, angle, indicator, callback ) { var avatar = new HumanoidAvatar(scene, dir); indicator.add(avatar); avatar.particles = this.startParticles(avatar.folder.name, pos); avatar.load( (avatar) => { this.character = avatar; if ( avatar.particles ) { avatar.particles.emitter.dispose(); avatar.particles.dispose(); delete( avatar.particles ); } indicator.remove(avatar); avatar.setPosition(pos); // CHECKME GLTF characters are facing the user when loaded avatar.setRotation( new BABYLON.Quaternion.RotationAxis(BABYLON.Axis.Y,angle)); if ( callback ) { callback( avatar ); } }, (evt) => { indicator.progress( evt, avatar ) } ); } createAvatarUI(avatar, manager) { var pos = avatar.parentMesh.position; var rot = avatar.parentMesh.rotationQuaternion; var text = new BABYLON.GUI.TextBlock(); text.text = "Avatar: "+avatar.folder.name; if ( avatar.info ) { text.text += '\n\nTitle: '+avatar.info.title+ '\n\nAuthor: '+avatar.info.author.replace('(','\n(')+ '\n\nLicense: '+avatar.info.license.replace('(','\n(') //+'\nSource:\n'+avatar.info.source; // too long ; } text.color = "white"; text.fontSize = 24; //text.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT; text.textVerticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP; var selectButton = new BABYLON.GUI.HolographicButton("select:"+avatar.folder.name); selectButton.imageUrl = this.contentBase+"/content/icons/zoom.png"; //selectButton.contentResolution = 1024; selectButton.contentScaleRatio = 4; selectButton.onPointerDownObservable.add( function() { console.log( "Selected "+avatar.folder.name ); selectButton.imageUrl = this.contentBase+"/content/icons/back.png"; if ( avatar.caption ) { avatar.caption.dispose(); avatar.caption = null; } avatar.castShadows(this.shadowGenerator); for ( var i = 0; i < selectButtons.length; i++ ) { if ( selectButtons[i] != selectButton ) { selectButtons[i].isVisible = false; } } }); selectButton.onPointerEnterObservable.add( function () { if ( ! avatar.caption ) { var group = new BABYLON.TransformNode(); group.position = new BABYLON.Vector3( pos.x*0.9,1,pos.z*0.9 ); //group.rotationQuaternion = new BABYLON.Quaternion.RotationAxis(BABYLON.Axis.Y,angle); group.rotationQuaternion = rot; var titlePlane = BABYLON.MeshBuilder.CreatePlane("Text"+avatar.folder.name, {height:1.5,width:6}, scene); titlePlane.parent = group; var titleTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh( titlePlane, 1024, 256, false // mouse events disabled ); titleTexture.addControl(text); avatar.caption = group; } }); selectButton.onPointerOutObservable.add( function () { if ( avatar.caption ) { avatar.caption.dispose(); avatar.caption = null; } }); manager.addControl(selectButton); // all of these must be set after control is added to manager // transform node does not exist earlier selectButton.position = new BABYLON.Vector3( pos.x*0.9,0.2,pos.z*0.9 ); //selectButton.scaling = new BABYLON.Vector3( 1.5,1.5,1.5 ); selectButton.scaling = new BABYLON.Vector3( .2, .2, .2 ); //selectButton.node.rotationQuaternion = new BABYLON.Quaternion.RotationAxis(BABYLON.Axis.Y,angle); selectButton.node.rotationQuaternion = rot; selectButtons.push(selectButton); } startParticles( dir, pos ) { var particleSystem; if (false && BABYLON.GPUParticleSystem.IsSupported) { // does not work in XR, renders only in one eye particleSystem = new BABYLON.GPUParticleSystem("particles:"+dir, { capacity:100 }, scene); particleSystem.activeParticleCount = 100; } else { particleSystem = new BABYLON.ParticleSystem("particles:"+dir, 100, scene); } particleSystem.worldOffset = pos; particleSystem.color1 = this.randomColor(); particleSystem.color2 = this.randomColor(); particleSystem.colorDead = new BABYLON.Color4(particleSystem.color2.r/10,particleSystem.color2.g/10,particleSystem.color2.b/10,0); particleSystem.emitRate = 10; particleSystem.particleEmitterType = new BABYLON.SphereParticleEmitter(0.5); particleSystem.particleTexture = new BABYLON.Texture(VRSPACEUI.contentBase+"/content/textures/flare.png", scene); particleSystem.gravity = new BABYLON.Vector3(0, 2, 0); particleSystem.minLifeTime = 0.5; particleSystem.maxLifeTime = 3; particleSystem.minSize = 0.1; particleSystem.maxSize = 0.2; particleSystem.minEmitPower = 0.1; particleSystem.maxEmitPower = 0.3; var fountain = BABYLON.Mesh.CreateBox("fountain", 0.1, scene); fountain.visibility = 0; particleSystem.emitter = fountain; particleSystem.start(); return particleSystem; } randomColor() { return new BABYLON.Color4(Math.random(), Math.random, Math.random(), Math.random()/5+0.8); } } export const WORLD = new AvatarLoader();