2009-11-16 20 views
1

我试着在运行时将材料应用到我的GeometryModel3D像这样:WPF 3D图像刷物质上的帮助

 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的偏移量。

I.e.目前,X:-0.25向后移动沿X轴的材质,但我不知道如何让这种类型的从用户点击鼠标的坐标...

当我这样做:

e.MouseDevice.GetPosition(ShardsViewPort3D);

,让我正常的X /鼠标点击Y的corrds ...

感谢您的帮助,您可以给!

+0

有可能是一个更好的方法来做到这一点,但显而易见的方法是实施http://en.wikipedia.org/wiki/Ray_casting – 2009-11-16 03:07:07

+0

嗯,不太清楚你的意思是什么关于我的问题..你能否请进一步解释这将如何帮助我的情况? – Mark 2009-11-16 03:55:55

回答

3

听起来好像你想在你的几何图形上滑动材质,当你点击它时。方法如下:

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

查找MeshGeometry3D.TextureCoordinates中的每个顶点索引(VertexIndex1,VertexIndex2,VertexIndex2)以获取纹理坐标。这会给你三个(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 

在代码中,你会把它写成点添加。我在这个解释中将它解释为(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

+0

非常感谢!这是一个很好的答案,我真的很感谢细节 – Mark 2009-11-16 04:52:17

+0

我确实找到了另一种方式,但生病给你点这一点 – Mark 2009-11-17 03:13:17