Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hello,

My program shows a static scene containing several instances, at different places, of a 3d model, for example a tree. This model can be 'heavy', between 50000 and 100000 triangles, and the performance degrade quickly with the number of instances (performance is unacceptable with more than 10 instances).

My first code, without optimizations, looks like this :

public partial class Vue3D : Window
{
  public ModelVisual3D modelVisual = new ModelVisual3D();
  public Model3DGroup model3DGroup = new Model3DGroup();

  public Vue3D()
    {
      ...
      modelVisual.Content = model3DGroup;
      view1.Children.Add(modelVisual); // view1 = viewport3D
      ...
      BuildScene();
    }

  void BuildScene()
    {
      Model3DGroup model = GetModel("tree");
      foreach (Point3D pnt in <point collection>)
      {
        Model3DGroup modelClone = model.Clone();
        Transform3DGroup tg = new Transform3DGroup();
        tg.Children.Add(new TranslateTransform3D(pnt.X, pnt.Y, pnt.Z>));
        modelClone.Transform = tg;
        model3DGroup.Children.Add(modelClone);
      }
    }
}


For each instance i clone the complete model, and add the clone to the viewport after transformation.
Let's say the tree model contains 2 GeometryModel3D :
{mesh1 (20000 triangles), texture1} and {mesh2 (40000 triangles), texture2}.
If i show 10 trees, i'm adding 20 GeometryModel3D.

Since all these instances share the same 2 textures, i thought i could speed up things by creating only 2 GeometryModel3D : one with all the triangles associated with texture1, one with all the triangles associated with texture2. That's what i tried in this code :

void BuildScene()
     {
       List<Transform3DGroup>> listTg = new List<Transform3DGroup>();
       foreach (Point3D pnt in <point collection>)
       {
         Transform3DGroup tg = new Transform3DGroup();
         tg.Children.Add(new TranslateTransform3D(pnt.X, pnt.Y, pnt.Z>));
         listTg.Add(tg);
       }
       Model3DGroup model = GetModel("tree");
       foreach (GeometryModel3D gmodel in model.Children)
       {
         MeshGeometry3D mesh = gmodel.Geometry as MeshGeometry3D;
         GeometryModel3D newgmodel = new GeometryModel3D();
         newgmodel.Material = gmodel.Material;
         newgmodel.BackMaterial = gmodel.BackMaterial;
         MeshGeometry3D newmesh = new MeshGeometry3D();
         newgmodel.Geometry = newmesh;
         foreach (Transform3DGroup tg in listTg)
         {
           foreach (int indice in mesh.TriangleIndices)
             newmesh.TriangleIndices.Add(indice + newmesh.Positions.Count);
           foreach (Point3D p3 in mesh.Positions)
             newmesh.Positions.Add(tg.Transform(p3));
           if (mesh.TextureCoordinates != null)
           {
             foreach (System.Windows.Point p in mesh.TextureCoordinates)
               newmesh.TextureCoordinates.Add(p);
           }
         }
         newmesh.TriangleIndices.Freeze();
         newmesh.TextureCoordinates.Freeze();
         newmesh.Positions.Freeze();
         newgmodel.Material.Freeze();
         newgmodel.BackMaterial.Freeze();
         newgmodel.Freeze();
         model3DGroup.Children.Add(newgmodel);
       }
     }


And the performance is not better, in fact it's rather worse ... What am I missing here ? It seems that my assumption, i.e. minimizing the number GeometryModel3D would be beneficial, is false. I have read somewhere that in wpf 3d, the number of triangles has no big impact on performance, but that the number of textures was more critical. Here i have a big number of triangles but only 2 textures, only one ModelVisual3D, and all is frozen... Any suggestion ?
Posted

1 solution

3D makes my brain hurt. But there is a really good example of a 3D WPF real time animation here:
http://stuff.seans.com/2008/08/24/raindrop-animation-in-wpf/[^]
Perhaps you can get some tips there :) Especially look at his double buffer, I think thats the right way to go.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900