Il semble que vous souhaitiez faire glisser le matériau autour de votre géométrie lorsque vous cliquez dessus. Voici comment:
Utilisez le test d'impact pour traduire vos coordonnées X/Y à partir du clic de la souris dans un RayMeshGeometry3DHitTestResult
comme décrit dans earlier answer. Cela vous donnera le MeshGeometry3D
qui a été touché, les sommets du triangle qui a été touché, et la position relative sur ce triangle.
rechercher chaque index de sommet (VertexIndex1
, VertexIndex2
, VertexIndex2
) dans le MeshGeometry3D.TextureCoordinates
pour obtenir les coordonnées de texture. Cela vous donnera trois paires (u, v) en tant qu'objets ponctuels. Multiplier chaque le (u, v) paires par le poids correspondant du résultat de test de recherche (VertexWeight1
, VertexWeight2
, VertexWeight3
) et ajoutez les paires ensemble, à savoir:
uMouse = u1 * VertexWeight1 + u2 * VertexWeight2 + u3 * VertexWeight3
vMouse = v1 * VertexWeight1 + v2 * VertexWeight2 + v3 * VertexWeight3
Maintenant, vous avez un point (uMouse, VMOUSE) cela indique où sur votre matériel votre souris a été cliquée. Si vous voulez qu'un point particulier de votre texture se déplace exactement à l'endroit où la souris a été cliquée, il suffit de soustraire le (uMouse, vMouse) où la souris a été cliquée de la coordonnée (u, v) de l'emplacement dans le matériau vous voulez apparaître sous la souris, et définissez ceci comme TranslateTransform. Si vous voulez gérer glisser, stocker le calculée (uMouse, VMOUSE) où la traînée a commencé et la transformation à partir du début de la traînée, puis comme traînantes progrès calculer la nouvelle transform comme:
translate = (uMouse,vMouse) - (uMouseDragStart, vMouseDragStart) + origTranslate
Dans le code, vous aurez écrivez ceci comme ajouts de points. Je l'ai orthographié comme (u, v) dans cette explication parce que je pensais que c'était plus facile à comprendre si je le faisais. En réalité le code à calculer (uMouse, VMOUSE) regardera plus comme ceci:
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);
et le code pour mettre à jour la transformation au cours d'une traînée ressemblera à quelque chose comme ceci:
...
var translate = translateAtDragStart + uvMouse - uvMouseAtDragStart;
... = new TranslateTransform(translate.X, translate.Y);
Vous aurez doit adapter cela à la situation exacte.
Notez que votre rappel HitTest peut être appelé plusieurs fois, en commençant par le maillage le plus proche et en reculant. Il peut même être appelé avec des hits 2D, par exemple si un objet 2D est en face de votre Viewport3D. Donc, vous voudrez vérifier chaque hit pour voir si c'est vraiment ce que vous voulez, par exemple, pendant le glisser, vous voulez continuer à vérifier la position sur le mesh en train d'être déplacé même si ce n'est plus le cas. Renvoyez HitTestResultBehavior.Stop
de votre rappel une fois que vous avez agi sur le maillage en train d'être déplacé.
Il ya probablement une meilleure façon de le faire, mais l'approche évidente est de mettre en œuvre http://en.wikipedia.org/wiki/Ray_casting –
Hmm, pas trop sûr de ce que vous entendez par là par rapport à ma question .. Pouvez-vous m'expliquer comment cela pourrait aider ma situation? – Mark