标签 wasm 下的文章

导航

如果你要在Blazor WebAssembly应用中使用Babylonjs,请参考:https://www.hnbc.info/index.php/archives/40/

准备阶段

本文案中用到的Hnbc.Lib.Blazor.BabylonJS.Server项目,是基于Babylonjs官方javascript生成的供blazor使用的引用库。可通过https://github.com/canhorn/EventHorizon.Blazor.TypeScript.Interop.Generator 该工程进行生成。
也可使用我已经生成好的项目直接使用:
下载一:https://pan.baidu.com/s/19GgK3b09cIPAG4t-8sBw-g 提取码: fvxg
下载二:https://download.csdn.net/download/yuexingchen2/19666177

Blazor Server应用配置

生成基于Blazor的BabylonJs引用库

参考:https://github.com/canhorn/EventHorizon.Blazor.TypeScript.Interop.Generator
可直接clone该项目,然后生成,或者下载我已经处理好的:

创建Blazor项目

创建新项目,选择Blazor Server应用

添加Hnbc.Lib.Blazor.BabylonJS.Server项目

将项目文Hnbc.Lib.Blazor.BabylonJS.Server拷贝到解决方案目录下,在解决方案上右键,添加现有项目,选择Hnbc.Lib.Blazor.BabylonJS.Server

添加项目引用

Blazor Server应用项目上添加项目引用,将Hnbc.Lib.Blazor.BabylonJS.Server引用到当前项目。

修改App.razor

App.razor文件末尾,添加如下代码:


@code {
    [Inject]
    public IJSRuntime JSRuntime { get; set; }

    protected override void OnInitialized()
    {
        EventHorizon.Blazor.Server.Interop.EventHorizonBlazorInterop.JSRuntime = JSRuntime;
    }
}

添加Js引用

Pages/_Host.cshtml文件中,添加Babylon的js引用和server-interop-bridge.js引用

        <!-- blazor基础框架js -->
        <script src="_framework/blazor.server.js"></script>
        <script src="_content/EventHorizon.Blazor.Server.Interop/server-interop-bridge.js"></script>

    <!-- Babylon.js -->
    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    <script src="https://cdn.babylonjs.com/ammo.js"></script>
    <script src="https://cdn.babylonjs.com/cannon.js"></script>
    <script src="https://cdn.babylonjs.com/Oimo.js"></script>
    <script src="https://cdn.babylonjs.com/libktx.js"></script>
    <script src="https://cdn.babylonjs.com/earcut.min.js"></script>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
    <script src="https://cdn.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
    <script src="https://cdn.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.js"></script>
    <script src="https://cdn.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
    <script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>

创建Babylon组件

为了测试是否可以正常使用,在项目下新建Controls文件夹,在此文件夹下新建-Razor组件。命名为TestComp。内容为:

<div>
    <canvas id="test-window" style="width:100%"></canvas>
</div>

添加TestComp的类文件,在Controls下添加名为TestComp.razor.cs的类文件,内容为:

using BABYLON;
using Hnbc.Lib.Blazor.BabylonJS.Server.Model;
using EventHorizon.Blazor.Server.Interop.Callbacks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Blazor.Test.Server.Controls
{
    public partial class TestComp : IDisposable
    {
        private IDictionary<string, AnimationGroup> _animationMap = new Dictionary<string, AnimationGroup>();
        private AnimationGroup _runningAnimation = null;
        private Engine _engine;
        public Mesh Obj; 

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await CreateScene();
            }
        }

        public void Dispose()
        {
            _engine?.dispose();
        }

        public async ValueTask CreateScene()
        {
            var canvas = await Canvas.GetElementById("test-window");
            var engine = await Engine.NewEngine(canvas,true);
            var scene = await Scene.NewScene(engine);
            var cameraTarget = await Vector3.NewVector3(0, 0, 5);

            var camera = await ArcRotateCamera.NewArcRotateCamera(
                "ArcRotateCamera",
                (decimal)(System.Math.PI / 2),
                (decimal)(System.Math.PI / 2),
                2,
                cameraTarget,
                scene
            );
            var hemisphericLightDirection = await Vector3.NewVector3(1, 1, 0);
            var light1 = await HemisphericLight.NewHemisphericLight("light1", hemisphericLightDirection, scene);
            var pointLightDirection = await Vector3.NewVector3(0, 1, -1);

            var light2 = await PointLight.NewPointLight("Omni", pointLightDirection,scene);

            await Mesh.CreateSphere("sphere1",50,2, scene);

            await scene.set_activeCamera(camera);
            await camera.attachControl(false);

            await engine.runRenderLoop(new ActionCallback(
                            () => Task.Run(() => scene.render(true, false))
                        ));

            _engine = engine;
        }

        public async ValueTask RunAnimation(string name)
        {
            if (_runningAnimation != null)
            {
                await _runningAnimation.stop();
                _runningAnimation = null;
            }

            if (_animationMap.ContainsKey(name))
            {
                await _animationMap[name].play(true);
                _runningAnimation = _animationMap[name];
            }
        }
    }
}

测试

修改Pages/Index.razor文件,添加TestComp组件显示。

@page "/"

<h1>Babylon测试!</h1>

<Blazor.Test.Server.Controls.TestComp/>

启动,如果界面显示了模型,则说明可以正常使用了。

修改网站设置

如果上面的测试例子中,使用了glb模型,为了能在网站加载此模型,需要在StartUp.cs文件的Configure中添加如下代码,如果网站部署在IIS下,也可在IIS中手动配置MIME。


var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".fx"] = "application/fx";
provider.Mappings[".gltf"] = "model/vnd.gltf+json";
provider.Mappings[".glb"] = "application/octet-stream";

导航

如果你要在Blazor Server应用中使用Babylonjs,请参考:https://www.hnbc.info/index.php/archives/41/

准备阶段

本文案中用到的Hnbc.Lib.Blazor.BabylonJS.Wasm项目,是基于Babylonjs官方javascript生成的供blazor使用的引用库。可通过https://github.com/canhorn/EventHorizon.Blazor.TypeScript.Interop.Generator 该工程进行生成
也可使用我已经生成好的项目:
下载一:https://pan.baidu.com/s/19GgK3b09cIPAG4t-8sBw-g 提取码: fvxg
下载二:https://download.csdn.net/download/yuexingchen2/19666120

Blazor WebAssembly应用配置

创建Blazor项目

创建新项目,选择Blazor WebAssembly应用

添加Hnbc.Lib.Blazor.BabylonJS.Wasm项目

将项目文Hnbc.Lib.Blazor.BabylonJS.Wasm拷贝到解决方案目录下,在解决方案上右键,添加现有项目,选择Hnbc.Lib.Blazor.BabylonJS.Wasm

添加项目引用

Blazor WebAssembly应用上添加项目引用,将Hnbc.Lib.Blazor.BabylonJS.Wasm引用到当前项目。

修改App.razor

App.razor文件末尾,添加如下代码:


@code { 
    [Inject]
    public IJSRuntime JSRuntime { get; set; }

    protected override void OnInitialized()
    {
        EventHorizon.Blazor.Interop.EventHorizonBlazorInterop.JSRuntime = JSRuntime;
    }
}

添加Js引用

wwwroot/index.html文件中,添加Babylon的js引用和interop-bridge.js引用

添加interop-bridge.js引用,通常和blazor.webassembly.js在一起。

        <!-- blazor基础框架js -->
    <script src="_framework/blazor.webassembly.js"></script>
    <script src="_content/EventHorizon.Blazor.Interop/interop-bridge.js"></script>

添加BabylonJs引用,通常放在head中。

    <!-- Babylon.js -->
    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    <script src="https://cdn.babylonjs.com/ammo.js"></script>
    <script src="https://cdn.babylonjs.com/cannon.js"></script>
    <script src="https://cdn.babylonjs.com/Oimo.js"></script>
    <script src="https://cdn.babylonjs.com/libktx.js"></script>
    <script src="https://cdn.babylonjs.com/earcut.min.js"></script>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
    <script src="https://cdn.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
    <script src="https://cdn.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.js"></script>
    <script src="https://cdn.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
    <script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>

创建Babylon组件

为了测试是否可以正常使用,在项目下新建Controls文件夹,在此文件夹下新建-Razor组件。命名为TestComp。内容为:

<div>
    <canvas id="test-window" style="width:100%"></canvas>
</div>

添加TestComp的类文件,在Controls下添加名为TestComp.razor.cs的类文件,内容为:

using BabylonJS;
using Hnbc.Lib.Blazor.BabylonJS.Wasm.Model;
using EventHorizon.Blazor.Interop.Callbacks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Blazor.Test.Client.Controls
{
    public partial class TestComp : IDisposable
    {
        private IDictionary<string, AnimationGroup> _animationMap = new Dictionary<string, AnimationGroup>();
        private AnimationGroup _runningAnimation = null;
        private Engine _engine;
        public Mesh Obj;

        protected override void OnAfterRender(bool firstRender)
        {
            if (firstRender)
            {
                CreateScene();
            }
        }

        public void Dispose()
        {
            _engine?.dispose();
        }

        public void CreateScene()
        {
            var canvas = Canvas.GetElementById("test-window");
            var engine = new Engine(canvas, true);
            var scene = new Scene(engine);
            var cameraTarget = new BabylonJS.Vector3(0, 0, 5);

            var camera =new ArcRotateCamera(
                "ArcRotateCamera",
                (decimal)(System.Math.PI / 2),
                (decimal)(System.Math.PI / 2),
                2,
                cameraTarget,
                scene
            );
            var hemisphericLightDirection = new BabylonJS.Vector3(1, 1, 0);
            var light1 = new HemisphericLight("light1", hemisphericLightDirection, scene);
            var pointLightDirection = new BabylonJS.Vector3(0, 1, -1);

            var light2 = new PointLight("Omni", pointLightDirection, scene);
             
            Mesh.CreateSphere("sphere1", 50, 2, scene);

            scene.activeCamera= camera;
            camera.attachControl(false);

            engine.runRenderLoop(new ActionCallback(
                            () => Task.Run(() => scene.render(true, false))
                        ));

            _engine = engine;
        }

        public void RunAnimation(string name)
        {
            if (_runningAnimation != null)
            {
                _runningAnimation.stop();
                _runningAnimation = null;
            }

            if (_animationMap.ContainsKey(name))
            {
                _animationMap[name].play(true);
                _runningAnimation = _animationMap[name];
            }
        }
    }
}

测试

修改Pages/Index.razor文件,添加TestComp组件显示。

@page "/"

<h1>Hello, Babylon!</h1>

<Blazor.Test.Client.Controls.TestComp/>

启动,如果界面显示了模型,则说明可以正常使用了。