2012-12-02 132 views
1

我正在努力正確映射wpf中的紋理。首先,3D不是我的力量,但我有一些示例代碼和下面的輸出圖像。我正在做一個多邊形,執行三角測量,然後嘗試在輸出上映射矩形紋理。我得到的問題是,我無法將紋理映射到順暢的曲線。一個紋理貼圖使用了3dtools.dll庫,它效果很好,但生成的紋理貼圖在左邊產生了輸出。它不像我想要的那樣傾斜。右邊產生的圖像是我嘗試手動將紋理座標映射到圖像。我明白爲什麼它看起來像它,但我不確定如何糾正它?WPF中的紋理映射3d

private void simpleButtonClick(object sender, RoutedEventArgs e) 
     { 
      ClearViewport(); 
      SetCamera(); 

      PathGeometry FlatPath; 

      Geometry Geo = Geometry.Parse("M 0,0 L 0,10 C 4,4 6,6 10,10 V 0 C 6,-4 4,-6 0,0"); 
      var GeoText = FormattedText.BuildGeometry(new Point(0, 0)); 

      FlatPath = 
       Geo.GetFlattenedPathGeometry(.01, 
              ToleranceType. 
               Absolute); 
      var vertices = new List<Vertex>(); 
      foreach (PathFigure Figure in FlatPath.Figures) 
      { 
       List<Point> PointList = DumpFigureToList(Figure); 
       vertices.AddRange(PointList.Select(p=>new Vertex((float)p.X,(float)p.Y))); 
      } 

      // Write out the data set we're actually going to triangulate 
      var angulator = new Triangulator(); 

      List<Triad> triangles = angulator.Triangulation(vertices, true); 

      var Bounds = FlatPath.Bounds; 

      var mesh = new MeshGeometry3D(); 
      var cube = new Model3DGroup(); 
      var Count = 0; 
      foreach (var Tri in triangles) 
      { 
       Tri.MakeCounterClockwise(vertices); 
       if (FlatPath.FillContains(new Point(Tri.circumcircleX, Tri.circumcircleY))) 
       { 
        var p0 = new Point3D(vertices[Tri.a].x, vertices[Tri.a].y, 0); 
        var p1 = new Point3D(vertices[Tri.b].x, vertices[Tri.b].y, 0); 
        var p2 = new Point3D(vertices[Tri.c].x, vertices[Tri.c].y, 0); 


        mesh.Positions.Add(p0); 
        mesh.Positions.Add(p1); 
        mesh.Positions.Add(p2); 
        mesh.TriangleIndices.Add(Count); 
        Count++; 
        mesh.TriangleIndices.Add(Count); 
        Count++; 
        mesh.TriangleIndices.Add(Count); 
        Count++; 
        Vector3D normal = CalculateNormal(p0, p1, p2); 
        mesh.Normals.Add(normal); 
        mesh.Normals.Add(normal); 
        mesh.Normals.Add(normal); 



        mesh.TextureCoordinates.Add(new Point((Bounds.Left - vertices[Tri.a].x)/Bounds.Width, vertices[Tri.a].y > 0 ? 1 : 0)); 
        mesh.TextureCoordinates.Add(new Point((Bounds.Left - vertices[Tri.b].x)/Bounds.Width, vertices[Tri.b].y > 0 ? 1 : 0)); 
        mesh.TextureCoordinates.Add(new Point((Bounds.Left - vertices[Tri.c].x)/Bounds.Width, vertices[Tri.c].y > 0 ? 1 : 0)); 

        if (wireframeCheckBox.IsChecked == true) 
        { 
         var wireframe = new ScreenSpaceLines3D(); 
         wireframe.Points.Add(p0); 
         wireframe.Points.Add(p1); 
         wireframe.Points.Add(p2); 
         wireframe.Points.Add(p0); 
         wireframe.Color = Colors.LightBlue; 
         wireframe.Thickness = 2; 

         this.mainViewport.Children.Add(wireframe); 
        } 
       } 
      } 


      //mesh.TextureCoordinates = _3DTools.MeshUtils.GeneratePlanarTextureCoordinates(mesh, new Vector3D(0, 0, 1)); 

      var myBrush = new ImageBrush(); 
      myBrush.ImageSource = 
       new BitmapImage(new Uri(@"curvedown.png", UriKind.Absolute)); 
      Material material = new DiffuseMaterial(myBrush); 
      var model = new GeometryModel3D(mesh, material); 
      var group = new Model3DGroup(); 
      group.Children.Add(model); 

      PointLight light = new PointLight(Colors.White, new Point3D(10,10,10)); 
      group.Children.Add(light); 


      var Model = new ModelVisual3D(); 
      Model.Content = group; 
      this.mainViewport.Children.Add(Model); 

     } 

這裏是上面的輸出與所述線框。我在使用註釋掉的紋理座標代碼。在正確的手動代碼(未註釋)。 Image of output

回答

4

隨着您的三角測量,它將永遠不會像您期望的那樣正確曲線。要實現這種彎曲,您必須手動生成細條紋。像

 

    ++++++++ 
    |||||||| 
    |||||||| 
    ++++++++ 

- 其中每個+是頂點 - 但不是使其伸直,沿着不同的線從一個公共點來(假想圓),在沿半徑特定偏移映射它。

在僞代碼:

 

    for each i from 0 to nStripes 
     let angle = start + (end-start) * i/nStripes 
     let p1 = Point where 
     X = innerRadius * cos(angle) 
     Y = innerRadius * sin(angle) 
     let p2 = Point where 
     X = outerRadius * cos(angle) 
     Y = outerRadius * sin(angle) 
     add vertex at p1 
     add vertex at p2 

然後事後連接先前生成的邊緣成對,所以(0,1)+(2,3)將四,(2,3)+(4,5 )另一種,等等...

你將不得不決定對其中的條紋的數量是足夠好的。始終牢記,一個三角形內紋理映射總是被線性插值,從來沒有一個曲線完成的,所以你不能指望之類的東西曲線或梯形神奇地看的權利。