Przeglądaj źródła

Adding animations select, glow, shadow config, changes to extended configuration

Raanan Weber 7 lat temu
rodzic
commit
90a18313a8

+ 10 - 1
Viewer/assets/templates/default/navbar.html

@@ -56,7 +56,8 @@
         font-size: 90%;
     }
 
-    div.button-container {
+    div.button-container,
+    div.animation-container {
         align-items: center;
         justify-content: flex-end;
     }
@@ -100,6 +101,14 @@
         <span class="model-subtitle"> {{#if subtitle}}{{subtitle}} {{/if}}</span>
     </div>
 </div>
+{{#if animations}}
+<div class="animation-container flex-container">
+    <select id="animation-selector" name="animations">
+        {{#each animations}}
+        <option value="{{this}}">{{this}}</option>> {{/each}}
+    </select>
+</div>
+{{/if}}
 <div class="button-container flex-container">
     <!-- holding the buttons -->
     {{#eachInMap buttons}}

+ 39 - 0
Viewer/dist/ufoExample.html

@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+
+    <head>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <meta http-equiv="X-UA-Compatible" content="ie=edge">
+        <title>BabylonJS Viewer - UFO</title>
+        <style>
+            babylon,
+            #viewport {
+                max-width: 1000px;
+                max-height: 800px;
+                width: 100%;
+                height: 800px;
+            }
+        </style>
+    </head>
+
+    <body>
+        <babylon id="babylon-viewer" extends="extended" templates.nav-bar.params.disable-on-fullscreen="true">
+            <scene glow="true">
+                <main-color r="0.5" g="0.2" b="0.2"></main-color>
+            </scene>
+            <model url="https://models.babylonjs.com/ufo.glb">
+                <animation auto-start="true"></animation>
+            </model>
+            <lights>
+                <light2 shadow-ortho-scale="0.5">
+                    <position x="0" y="6" z="6"></position>
+                </light2>
+            </lights>
+        </babylon>
+        <script src="viewer.js"></script>
+        <script>
+        </script>
+    </body>
+
+</html>

+ 2 - 1
Viewer/src/configuration/configuration.ts

@@ -1,5 +1,5 @@
 import { ITemplateConfiguration } from './../templateManager';
-import { EngineOptions } from 'babylonjs';
+import { EngineOptions, IGlowLayerOptions } from 'babylonjs';
 
 export interface ViewerConfiguration {
 
@@ -187,6 +187,7 @@ export interface ISceneConfiguration {
     environmentTexture?: string;
     colorGrading?: IColorGradingConfiguration;
     environmentRotationY?: number;
+    glow?: boolean | IGlowLayerOptions;
 }
 
 /**

+ 4 - 2
Viewer/src/configuration/types/default.ts

@@ -38,7 +38,8 @@ export let defaultConfiguration: ViewerConfiguration = {
             },
             events: {
                 pointerdown: { 'fullscreen-button': true/*, '#help-button': true*/ },
-                pointerover: true
+                pointerover: true,
+                change: { 'animation-selector': true }
             }
         },
         overlay: {
@@ -68,7 +69,8 @@ export let defaultConfiguration: ViewerConfiguration = {
                 zoomStopsAnimation: false
             },
             bouncing: 1
-        }
+        },
+        wheelPrecision: 200,
     },
     skybox: {
         /*cubeTexture: {

+ 21 - 21
Viewer/src/configuration/types/extended.ts

@@ -1,7 +1,7 @@
 import { ViewerConfiguration } from './../configuration';
 
 export let extendedConfiguration: ViewerConfiguration = {
-    version: "3.2.0-alpha4",
+    version: "3.2.0",
     extends: "default",
     camera: {
         radius: 1.8,
@@ -14,49 +14,49 @@ export let extendedConfiguration: ViewerConfiguration = {
     lights: {
         "light1": {
             type: 0,
-            shadowEnabled: true,
-            target: { x: -0.07100000337231904, y: -0.7150000339606777, z: -1.0 },
+            shadowEnabled: false,
+            target: { x: 0, y: 0, z: 0 },
             position: { x: -0.78, y: 1.298, z: 1.62 },
             diffuse: { r: 1.0, g: 1.0, b: 1.0 },
-            intensity: 6,
+            intensity: 2,
             intensityMode: 0,
             radius: 0.135,
             spotAngle: 59.9967,
             shadowBufferSize: 512,
-            shadowFieldOfView: 60.977,
-            shadowFrustumSize: 2.0,
+            shadowFieldOfView: 80.977,
+            shadowFrustumSize: 8.0,
             shadowMinZ: 1.0,
             shadowMaxZ: 10.0
         },
         "light2": {
-            type: 0,
+            type: 1,
             shadowEnabled: true,
-            target: { x: 1.0, y: 0.53, z: 0.18 },
+            target: { x: 0, y: -0.5, z: -1 },
             position: { x: 1.49, y: 1.39, z: -1.33 },
             diffuse: { r: 0.867, g: 0.816, b: 0.788 },
-            intensity: 4.887,
+            intensity: 2.887,
             intensityMode: 0,
-            radius: 0.0,
-            spotAngle: 34.285,
-            shadowBufferSize: 512,
-            shadowFieldOfView: 28,
-            shadowFrustumSize: 2.0,
-            shadowMinZ: 0.2,
-            shadowMaxZ: 10.0
+            shadowBufferSize: 1024,
+            shadowFrustumSize: 3.0,
+            shadowMinZ: 0.1,
+            shadowMaxZ: 12.0,
+            shadowConfig: {
+                blurKernel: 32
+            }
         },
         "light3": {
             type: 2,
-            shadowEnabled: true,
+            shadowEnabled: false,
             target: { x: 0, y: 1, z: 0 },
-            position: { x: -4, y: -2, z: 2.23 },
+            position: { x: -4, y: 2, z: 2.23 },
             diffuse: { r: 0.718, g: 0.772, b: 0.749 },
-            intensity: 7.052,
+            intensity: 3.052,
             intensityMode: 0,
             radius: 0.5,
             spotAngle: 42.85,
             shadowBufferSize: 512,
-            shadowFieldOfView: 45,
-            shadowFrustumSize: 2.0,
+            shadowFieldOfView: 80,
+            shadowFrustumSize: 8.0,
             shadowMinZ: 0.2,
             shadowMaxZ: 10.0
         }

+ 6 - 1
Viewer/src/model/viewerModel.ts

@@ -1,4 +1,4 @@
-import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, AnimationGroup, Animatable, AbstractMesh, Tools, Scene, SceneLoader, Observable, SceneLoaderProgressEvent, Tags, ParticleSystem, Skeleton, IDisposable, Nullable, Animation, Quaternion, Material, Vector3 } from "babylonjs";
+import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, AnimationGroup, Animatable, AbstractMesh, Tools, Scene, SceneLoader, Observable, SceneLoaderProgressEvent, Tags, ParticleSystem, Skeleton, IDisposable, Nullable, Animation, Quaternion, Material, Vector3, AnimationPropertiesOverride } from "babylonjs";
 import { GLTFFileLoader } from "babylonjs-loaders";
 import { IModelConfiguration } from "../configuration/configuration";
 import { IModelAnimation, GroupModelAnimation, AnimationPlayMode } from "./modelAnimation";
@@ -166,6 +166,11 @@ export class ViewerModel implements IDisposable {
 
 
     private _initAnimations() {
+        Animation.AllowMatricesInterpolation = true;
+        this._viewer.sceneManager.scene.animationPropertiesOverride = new AnimationPropertiesOverride();
+        this._viewer.sceneManager.scene.animationPropertiesOverride.enableBlending = true;
+        this._viewer.sceneManager.scene.animationPropertiesOverride.blendingSpeed = 0.02;
+        this._viewer.sceneManager.scene.animationPropertiesOverride.loopMode = 1;
         // check if this is not a gltf loader and init the animations
         if (this.skeletons.length) {
             this.skeletons.forEach((skeleton, idx) => {

+ 16 - 6
Viewer/src/templateManager.ts

@@ -1,6 +1,7 @@
 
 import { Observable, IFileRequest, Tools } from 'babylonjs';
 import { isUrl, camelToKebab, kebabToCamel } from './helper';
+import * as deepmerge from '../assets/deepmerge.min.js';
 
 /**
  * A single template configuration object
@@ -294,6 +295,7 @@ export class Template {
     public initPromise: Promise<Template>;
 
     private _fragment: DocumentFragment | Element;
+    private _addedFragment: DocumentFragment | Element;
     private _htmlTemplate: string;
     private _rawHtml: string;
 
@@ -341,11 +343,15 @@ export class Template {
      * 
      * @param params the new template parameters
      */
-    public updateParams(params: { [key: string]: string | number | boolean | object }) {
-        this._configuration.params = params;
+    public updateParams(params: { [key: string]: string | number | boolean | object }, append: boolean = true) {
+        if (append) {
+            this._configuration.params = deepmerge(this._configuration.params, params);
+        } else {
+            this._configuration.params = params;
+        }
         // update the template
         if (this.isLoaded) {
-            this.dispose();
+            // this.dispose();
         }
         let compiledTemplate = Handlebars.compile(this._htmlTemplate);
         let config = this._configuration.params || {};
@@ -401,8 +407,11 @@ export class Template {
      */
     public appendTo(parent: HTMLElement, forceRemove?: boolean) {
         if (this.parent) {
-            if (forceRemove && this._fragment) {
-                this.parent.removeChild(this._fragment);
+            if (forceRemove && this._addedFragment) {
+                /*let fragement = this.parent.querySelector(this.name)
+                if (fragement)
+                    this.parent.removeChild(fragement);*/
+                this.parent.innerHTML = '';
             } else {
                 return;
             }
@@ -413,7 +422,8 @@ export class Template {
             this.parent.id = this._configuration.id;
         }
         if (this._fragment) {
-            this._fragment = this.parent.appendChild(this._fragment);
+            this.parent.appendChild(this._fragment);
+            this._addedFragment = this._fragment;
         } else {
             this.parent.insertAdjacentHTML("beforeend", this._rawHtml);
         }

+ 8 - 0
Viewer/src/viewer/defaultViewer.ts

@@ -92,6 +92,10 @@ export class DefaultViewer extends AbstractViewer {
             this.templateManager.eventManager.registerCallback('navBar', triggerNavbar.bind(this, true), 'pointerover');
 
             this.templateManager.eventManager.registerCallback('navBar', this.toggleFullscreen, 'pointerdown', '#fullscreen-button');
+            this.templateManager.eventManager.registerCallback('navBar', (data) => {
+                if (data && data.event && data.event.target)
+                    this.sceneManager.models[0].playAnimation(data.event.target['value']);
+            }, 'change', '#animation-selector');
         }
     }
 
@@ -131,6 +135,10 @@ export class DefaultViewer extends AbstractViewer {
         let navbar = this.templateManager.getTemplate('navBar');
         if (!navbar) return;
 
+        if (model.getAnimationNames().length > 1) {
+            navbar.updateParams({ animations: model.getAnimationNames() });
+        }
+
         let modelConfiguration = model.configuration;
 
         let metadataContainer = navbar.parent.querySelector('#model-metadata');

+ 20 - 6
Viewer/src/viewer/sceneManager.ts

@@ -1,4 +1,4 @@
-import { Scene, ArcRotateCamera, Engine, Light, ShadowLight, Vector3, ShadowGenerator, Tags, CubeTexture, Quaternion, SceneOptimizer, EnvironmentHelper, SceneOptimizerOptions, Color3, IEnvironmentHelperOptions, AbstractMesh, FramingBehavior, Behavior, Observable, Color4 } from 'babylonjs';
+import { Scene, ArcRotateCamera, Engine, Light, ShadowLight, Vector3, ShadowGenerator, Tags, CubeTexture, Quaternion, SceneOptimizer, EnvironmentHelper, SceneOptimizerOptions, Color3, IEnvironmentHelperOptions, AbstractMesh, FramingBehavior, Behavior, Observable, Color4, IGlowLayerOptions } from 'babylonjs';
 import { AbstractViewer } from './viewer';
 import { ILightConfiguration, ISceneConfiguration, ISceneOptimizerConfiguration, ICameraConfiguration, ISkyboxConfiguration, ViewerConfiguration, IGroundConfiguration, IModelConfiguration } from '../configuration/configuration';
 import { ViewerModel } from '../model/viewerModel';
@@ -136,7 +136,7 @@ export class SceneManager {
     /**
      * initialize the scene. Calling this function again will dispose the old scene, if exists.
      */
-    public initScene(sceneConfiguration?: ISceneConfiguration, optimizerConfiguration?: boolean | ISceneOptimizerConfiguration): Promise<Scene> {
+    public initScene(sceneConfiguration: ISceneConfiguration = {}, optimizerConfiguration?: boolean | ISceneOptimizerConfiguration): Promise<Scene> {
 
         // if the scen exists, dispose it.
         if (this.scene) {
@@ -156,6 +156,16 @@ export class SceneManager {
 
         this._mainColor = new Color3();
 
+        if (sceneConfiguration.glow) {
+            let options: Partial<IGlowLayerOptions> = {
+                mainTextureFixedSize: 512
+            };
+            if (typeof sceneConfiguration.glow === 'object') {
+                options = sceneConfiguration.glow
+            }
+            var gl = new BABYLON.GlowLayer("glow", this.scene, options);
+        }
+
         if (sceneConfiguration) {
             this._configureScene(sceneConfiguration);
 
@@ -219,11 +229,11 @@ export class SceneManager {
                     this._mainColor.b = mc.b
                 }
 
-                this._mainColor.toLinearSpaceToRef(this._mainColor);
+                /*this._mainColor.toLinearSpaceToRef(this._mainColor);
                 let exposure = Math.pow(2.0, -((globalConfiguration.camera && globalConfiguration.camera.exposure) || 0.75)) * Math.PI;
                 this._mainColor.scaleToRef(1 / exposure, this._mainColor);
                 let environmentTint = (globalConfiguration.lab && globalConfiguration.lab.environmentMap && globalConfiguration.lab.environmentMap.tintLevel) || 0;
-                this._mainColor = BABYLON.Color3.Lerp(this._white, this._mainColor, environmentTint);
+                this._mainColor = Color3.Lerp(this._white, this._mainColor, environmentTint);*/
             }
         }
 
@@ -542,6 +552,8 @@ export class SceneManager {
             }
         }
 
+        this.environmentHelper.setMainColor(this._mainColor);
+
         if (this.environmentHelper.rootMesh && this._viewer.configuration.scene && this._viewer.configuration.scene.environmentRotationY !== undefined) {
             this.environmentHelper.rootMesh.rotation.y = this._viewer.configuration.scene.environmentRotationY;
         }
@@ -677,7 +689,7 @@ export class SceneManager {
                         shadowGenerator = new ShadowGenerator(512, light);
                         // TODO blur kernel definition
                     }
-                    extendClassWithConfig(shadowGenerator, lightConfig.shadowConfig || {});
+
                     // add the focues meshes to the shadow list
                     let shadownMap = shadowGenerator.getShadowMap();
                     if (!shadownMap) return;
@@ -696,6 +708,8 @@ export class SceneManager {
                     shadowGenerator.bias = this._shadowGeneratorBias;
                     shadowGenerator.blurKernel = blurKernel;
                     shadowGenerator.depthScale = 50 * (light.shadowMaxZ - light.shadowMinZ);
+                    //override defaults
+                    extendClassWithConfig(shadowGenerator, lightConfig.shadowConfig || {});
                 } else if (shadowGenerator) {
                     shadowGenerator.dispose();
                 }
@@ -727,7 +741,7 @@ export class SceneManager {
      * @return the kernel blur size
      */
     public getBlurKernel(light: BABYLON.IShadowLight, bufferSize: number): number {
-        var normalizedBlurKernel = 0.03; // TODO Should come from the config.
+        var normalizedBlurKernel = 0.05; // TODO Should come from the config.
         if (light.getTypeID() === BABYLON.Light.LIGHTTYPEID_DIRECTIONALLIGHT) {
             normalizedBlurKernel = normalizedBlurKernel / (<BABYLON.DirectionalLight>light).shadowFrustumSize;
         }