2009-11-16 22 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