WPF 3d ImageBrush材质帮助

问题描述 投票:1回答:1

我试图在运行时将材料应用于我的GeometryModel3D:

        var model3D = ShardModelVisual.Content as GeometryModel3D;
        var materialGroup = model3D.Material as MaterialGroup;

        BitmapImage image;
        ResourceLoader.TryLoadImage("pack://application:,,,/AnzSurface;component/path file/img.png", out image, ".png");
        var iceBrush = new ImageBrush(image);
        var grp = new TransformGroup();
        grp.Children.Add(new ScaleTransform(0.25, 0.65, 0.5, 0.5));
        grp.Children.Add(new TranslateTransform(0.0, 0.0));
        iceBrush.Transform = grp;
        var iceMat = new DiffuseMaterial(iceBrush);
        materialGroup.Children.Add(iceMat);

这一切都很好,并且添加了材料。

我不理解的是我如何将用户单击屏幕上的图像映射到需要应用于TranslateTransform的偏移量。

即目前,x:-0.25沿X轴向后移动材质,但是我不知道如何从用户的鼠标单击中获取该类型的坐标...

当我这样做:

e.MouseDevice.GetPosition(ShardsViewPort3D);

这给了我鼠标单击的正常X / Y密码...

感谢您能提供的任何帮助!

wpf 3d
1个回答
3
投票

听起来,您想在几何图形上单击时将其滑动。方法如下:

如我的RayMeshGeometry3DHitTestResult中所述,使用点击测试将鼠标单击的X / Y坐标转换为earlier answer。这将为您提供被击中的MeshGeometry3D,被击中的三角形的顶点以及该三角形上的相对位置。

VertexIndex1中查找每个顶点索引(VertexIndex2VertexIndex2MeshGeometry3D.TextureCoordinates)以获取纹理坐标。这将为您提供三个(u,v)对作为Point对象。将(u,v)对中的每一个乘以命中测试结果(VertexWeight1VertexWeight2VertexWeight3)中的相应权重,并将这些对加在一起,即:

uMouse = u1 * VertexWeight1 + u2 * VertexWeight2 + u3 * VertexWeight3
vMouse = v1 * VertexWeight1 + v2 * VertexWeight2 + v3 * VertexWeight3

现在您有了一个点(uMouse,vMouse),它指示您的鼠标在材料上的单击位置。

[如果您希望纹理上的特定点精确移动到单击鼠标的位置,只需从所需材质中位置的(u,v)坐标中减去单击鼠标的位置(uMouse,vMouse)出现在鼠标下方,并将其设置为TranslateTransform。如果要处理拖动,请将计算的(uMouse,vMouse)存储在拖动开始的位置,并存储从拖动开始的转换,然后随着拖动的进行,将新的转换计算为:]

translate = (uMouse,vMouse) - (uMouseDragStart, vMouseDragStart) + origTranslate

在代码中,您将其写为Point加法。我在此说明中将其拼写为(u,v),因为我认为这样做更容易理解。实际上,要计算的代码(uMouse,vMouse)将更像这样:

var uv1 = hit.MeshHit.TextureCoordinates[hit.VertexIndex1];
var uv2 = hit.MeshHit.TextureCoordinates[hit.VertexIndex2];
var uv3 = hit.MeshHit.TextureCoordinates[hit.VertexIndex3];

var uvMouse = new Vector(
  uv1.X * hit.VertexWeight1 + uv2.X * hit.VertexWeight2 + uv3.X * hit.VertexWeight3)
  uv1.Y * hit.VertexWeight1 + uv2.Y * hit.VertexWeight2 + uv3.Y * hit.VertexWeight3);

以及在拖动过程中更新变换的代码将如下所示:

...
var translate = translateAtDragStart + uvMouse - uvMouseAtDragStart;
... = new TranslateTransform(translate.X, translate.Y);

您必须对此进行调整以适合实际情况。

请注意,您的HitTest回调可能会被调用多次,从最接近的网格开始,然后移回。甚至可以用2D命中来调用它,例如,如果2D对象位于Viewport3D的前面。因此,您需要检查每个命中点,看看它是否确实是您想要的,例如,在拖动过程中,即使不再是最重要的位置,您也要继续检查被拖动的网格上的位置。对要拖动的网格进行操作后,从回调中返回HitTestResultBehavior.Stop

© www.soinside.com 2019 - 2024. All rights reserved.