helix-toolkit / helix-toolkit

Helix Toolkit is a collection of 3D components for .NET.
http://helix-toolkit.org/
MIT License
1.85k stars 661 forks source link

BatchedMeshGeometryModel3D not displayed #1021

Open KrabatTilt opened 5 years ago

KrabatTilt commented 5 years ago

I am using helix-toolkit version 2.5.1.

I am trying to load and display a lot of small rectangular tiles with different texture loaded from file. Currently I put every tile separately into a ModelGroup which works fine. But it seems to generate a performance issue as UI becomes laggy when removing/adding items from/to the model group while viewport is moved by the user. So I tried to implement loading all tiles together in one BatchedMeshGeometryModel3D and adding just this model to the ModelGroup. But unfortunately, this does not work. The BatchedModel is added but not displayed.

Below is my code of the Viewport and model creation logic.

Viewport:

<hx:Viewport3DX x:Name="Viewport3Dx" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2"
                        UseDefaultGestures="False" ShowViewCube="False"
                        CameraRotationMode="Turntable" CameraMode="Inspect" IsRotationEnabled="False"
                        Camera="{Binding Camera}" TouchDown="Viewport3Dx_OnTouchDown" IsTouchRotateEnabled="False"
                        ZoomAroundMouseDownPoint="True" MSAA="Disable" FXAALevel="Low" EnableD2DRendering="False"
                        BackgroundColor="{Binding BackgroundColor}" IsViewCubeMoverEnabled="False"
                        ZoomDistanceLimitNear="20" LeftRightPanSensitivity="400" FocusVisualStyle="{x:Null}"
                        IsInertiaEnabled="true" ZoomSensitivity="5" CameraInertiaFactor="0.7" >
            <hx:Viewport3DX.InputBindings>
                <MouseBinding Gesture="MiddleClick" Command="hx:ViewportCommands.Zoom" />
                <MouseBinding Gesture="LeftClick" Command="hx:ViewportCommands.Pan" />
            </hx:Viewport3DX.InputBindings>
            <hx:DirectionalLight3D Color="White" Direction="0,0,-10" />
            <hx:GroupModel3D x:Name="ModelGroup" IsHitTestVisible="True"/>
        </hx:Viewport3DX>

ModelCreation:

                    var batchedMaterials =new List<HelixToolkit.Wpf.SharpDX.Material>();
                    var batchedMeshes = new List<BatchedMeshGeometryConfig>();
                    var model = new BatchedMeshGeometryModel3D();

                    foreach (string file in files)
                    {
                        MemoryStream ms = await  GetTextureAsync(file);

                        var material = new PhongMaterial
                        {
                            SpecularColor = Color.Black,
                            DiffuseMap = ms,
                            DiffuseMapSampler = new SamplerStateDescription
                            {
                                AddressU = TextureAddressMode.Clamp,
                                AddressV = TextureAddressMode.Clamp,
                                AddressW = TextureAddressMode.Clamp,
                                Filter = Filter.Anisotropic
                            }
                        };

                        var meshBuilder = new MeshBuilder();
                        meshBuilder.AddBox(new Rect3D(tileRect.X, tileRect.Y, 0, tileRect.Width, tileRect.Height, 0.0), BoxFaces.PositiveZ);
                        MeshGeometry3D geometry = meshBuilder.ToMeshGeometry3D();

                        batchedMaterials.Add(material);
                        batchedMeshes.Add(new BatchedMeshGeometryConfig(geometry, Matrix.Identity, batchedMaterials.Count-1));
                    }

                    model.BatchedGeometries = batchedMeshes;
                    model.BatchedMaterials = batchedMaterials;
                    model.CullMode = CullMode.Back;
                    //model.Material = PhongMaterials.White;

                    Viewport3DxModelGroup.Children.Add(model);
holance commented 5 years ago

You need to assign the BatchedMeshGeometryModel3D a material as master material.

And also needs to provide your own function to merge all texture together as a single texture map and assign into the master material map.

Also the texture coordinates for each mesh need to be corrected based on how you merge your textures as well.

HelixToolkit provided an image packer tool (needs further implementation to support file streams) to pack multiple textures together. But you still need to correct the texture coordinates in each mesh.

You may use SpriteSheetPacker as well.