/Controls/HelixToolkit.Wpf/Visual3Ds/Manipulators/Manipulator.cs

https://bitbucket.org/kubrakms/thermalconductivity · C# · 416 lines · 199 code · 51 blank · 166 comment · 2 complexity · c63afe297e6789d193d3ab16cf9c0a84 MD5 · raw file

  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <copyright file="Manipulator.cs" company="Helix 3D Toolkit">
  3. // http://helixtoolkit.codeplex.com, license: Ms-PL
  4. // </copyright>
  5. // <summary>
  6. // An abstract base class for manipulators.
  7. // </summary>
  8. // --------------------------------------------------------------------------------------------------------------------
  9. namespace HelixToolkit.Wpf
  10. {
  11. using System.Windows;
  12. using System.Windows.Controls;
  13. using System.Windows.Data;
  14. using System.Windows.Input;
  15. using System.Windows.Media;
  16. using System.Windows.Media.Media3D;
  17. /// <summary>
  18. /// An abstract base class for manipulators.
  19. /// </summary>
  20. public abstract class Manipulator : UIElement3D
  21. {
  22. #region Constants and Fields
  23. /// <summary>
  24. /// The color property.
  25. /// </summary>
  26. public static readonly DependencyProperty ColorProperty = DependencyProperty.Register(
  27. "Color", typeof(Color), typeof(Manipulator), new UIPropertyMetadata(ColorChanged));
  28. /// <summary>
  29. /// The offset property.
  30. /// </summary>
  31. public static readonly DependencyProperty OffsetProperty = DependencyProperty.Register(
  32. "Offset",
  33. typeof(Vector3D),
  34. typeof(Manipulator),
  35. new FrameworkPropertyMetadata(
  36. new Vector3D(0, 0, 0), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PositionChanged));
  37. /// <summary>
  38. /// The pivot point property.
  39. /// </summary>
  40. public static readonly DependencyProperty PivotProperty = DependencyProperty.Register(
  41. "Pivot", typeof(Point3D), typeof(Manipulator), new PropertyMetadata(new Point3D()));
  42. /// <summary>
  43. /// The position property.
  44. /// </summary>
  45. public static readonly DependencyProperty PositionProperty = DependencyProperty.Register(
  46. "Position",
  47. typeof(Point3D),
  48. typeof(Manipulator),
  49. new FrameworkPropertyMetadata(
  50. new Point3D(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PositionChanged));
  51. /// <summary>
  52. /// The target transform property.
  53. /// </summary>
  54. public static readonly DependencyProperty TargetTransformProperty =
  55. DependencyProperty.Register(
  56. "TargetTransform",
  57. typeof(Transform3D),
  58. typeof(Manipulator),
  59. new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
  60. /// <summary>
  61. /// The value property.
  62. /// </summary>
  63. public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
  64. "Value",
  65. typeof(double),
  66. typeof(Manipulator),
  67. new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
  68. #endregion
  69. #region Constructors and Destructors
  70. /// <summary>
  71. /// Initializes a new instance of the <see cref="Manipulator" /> class.
  72. /// </summary>
  73. protected Manipulator()
  74. {
  75. this.Model = new GeometryModel3D();
  76. this.Visual3DModel = this.Model;
  77. this.OnGeometryChanged();
  78. }
  79. #endregion
  80. #region Public Properties
  81. /// <summary>
  82. /// Gets or sets the color of the manipulator.
  83. /// </summary>
  84. /// <value> The color. </value>
  85. public Color Color
  86. {
  87. get
  88. {
  89. return (Color)this.GetValue(ColorProperty);
  90. }
  91. set
  92. {
  93. this.SetValue(ColorProperty, value);
  94. }
  95. }
  96. /// <summary>
  97. /// Gets or sets the offset of the visual (this vector is added to the Position point).
  98. /// </summary>
  99. /// <value> The offset. </value>
  100. public Vector3D Offset
  101. {
  102. get
  103. {
  104. return (Vector3D)this.GetValue(OffsetProperty);
  105. }
  106. set
  107. {
  108. this.SetValue(OffsetProperty, value);
  109. }
  110. }
  111. /// <summary>
  112. /// Gets or sets the pivot point of the manipulator.
  113. /// </summary>
  114. /// <value> The position. </value>
  115. public Point3D Pivot
  116. {
  117. get
  118. {
  119. return (Point3D)this.GetValue(PivotProperty);
  120. }
  121. set
  122. {
  123. this.SetValue(PivotProperty, value);
  124. }
  125. }
  126. /// <summary>
  127. /// Gets or sets the position of the manipulator.
  128. /// </summary>
  129. /// <value> The position. </value>
  130. public Point3D Position
  131. {
  132. get
  133. {
  134. return (Point3D)this.GetValue(PositionProperty);
  135. }
  136. set
  137. {
  138. this.SetValue(PositionProperty, value);
  139. }
  140. }
  141. /// <summary>
  142. /// Gets or sets TargetTransform.
  143. /// </summary>
  144. public Transform3D TargetTransform
  145. {
  146. get
  147. {
  148. return (Transform3D)this.GetValue(TargetTransformProperty);
  149. }
  150. set
  151. {
  152. this.SetValue(TargetTransformProperty, value);
  153. }
  154. }
  155. /// <summary>
  156. /// Gets or sets the manipulator value.
  157. /// </summary>
  158. /// <value> The value. </value>
  159. public double Value
  160. {
  161. get
  162. {
  163. return (double)this.GetValue(ValueProperty);
  164. }
  165. set
  166. {
  167. this.SetValue(ValueProperty, value);
  168. }
  169. }
  170. #endregion
  171. #region Properties
  172. /// <summary>
  173. /// Gets or sets the camera.
  174. /// </summary>
  175. protected ProjectionCamera Camera { get; set; }
  176. /// <summary>
  177. /// Gets or sets the hit plane normal.
  178. /// </summary>
  179. protected Vector3D HitPlaneNormal { get; set; }
  180. /// <summary>
  181. /// Gets or sets the model.
  182. /// </summary>
  183. protected GeometryModel3D Model { get; set; }
  184. /// <summary>
  185. /// Gets or sets the parent viewport.
  186. /// </summary>
  187. protected Viewport3D ParentViewport { get; set; }
  188. #endregion
  189. #region Public Methods
  190. /// <summary>
  191. /// Binds this manipulator to a given Visual3D.
  192. /// </summary>
  193. /// <param name="source">
  194. /// Source Visual3D which receives the manipulator transforms.
  195. /// </param>
  196. public virtual void Bind(ModelVisual3D source)
  197. {
  198. BindingOperations.SetBinding(this, TargetTransformProperty, new Binding("Transform") { Source = source });
  199. BindingOperations.SetBinding(this, TransformProperty, new Binding("Transform") { Source = source });
  200. }
  201. /// <summary>
  202. /// Releases the binding of this manipulator.
  203. /// </summary>
  204. public virtual void UnBind()
  205. {
  206. BindingOperations.ClearBinding(this, TargetTransformProperty);
  207. BindingOperations.ClearBinding(this, TransformProperty);
  208. }
  209. #endregion
  210. #region Methods
  211. /// <summary>
  212. /// Called when Geometry is changed.
  213. /// </summary>
  214. /// <param name="d">
  215. /// The sender.
  216. /// </param>
  217. /// <param name="e">
  218. /// The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.
  219. /// </param>
  220. protected static void GeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  221. {
  222. ((Manipulator)d).OnGeometryChanged();
  223. }
  224. /// <summary>
  225. /// Projects the point on the hit plane.
  226. /// </summary>
  227. /// <param name="p">
  228. /// The p.
  229. /// </param>
  230. /// <param name="hitPlaneOrigin">
  231. /// The hit Plane Origin.
  232. /// </param>
  233. /// <param name="hitPlaneNormal">
  234. /// The hit plane normal (world coordinate system).
  235. /// </param>
  236. /// <returns>
  237. /// The point in world coordinates.
  238. /// </returns>
  239. protected virtual Point3D? GetHitPlanePoint(Point p, Point3D hitPlaneOrigin, Vector3D hitPlaneNormal)
  240. {
  241. return Viewport3DHelper.UnProject(this.ParentViewport, p, hitPlaneOrigin, hitPlaneNormal);
  242. }
  243. /// <summary>
  244. /// The on geometry changed.
  245. /// </summary>
  246. protected abstract void OnGeometryChanged();
  247. /// <summary>
  248. /// The on mouse down.
  249. /// </summary>
  250. /// <param name="e">
  251. /// The event arguments.
  252. /// </param>
  253. protected override void OnMouseDown(MouseButtonEventArgs e)
  254. {
  255. base.OnMouseDown(e);
  256. this.ParentViewport = Visual3DHelper.GetViewport3D(this);
  257. this.Camera = this.ParentViewport.Camera as ProjectionCamera;
  258. var projectionCamera = this.Camera;
  259. if (projectionCamera != null)
  260. {
  261. this.HitPlaneNormal = projectionCamera.LookDirection;
  262. }
  263. this.CaptureMouse();
  264. }
  265. /// <summary>
  266. /// The on mouse up.
  267. /// </summary>
  268. /// <param name="e">
  269. /// The event arguments.
  270. /// </param>
  271. protected override void OnMouseUp(MouseButtonEventArgs e)
  272. {
  273. base.OnMouseUp(e);
  274. this.ReleaseMouseCapture();
  275. }
  276. /// <summary>
  277. /// Transforms from world to local coordinates.
  278. /// </summary>
  279. /// <param name="worldPoint">
  280. /// The point (world coords).
  281. /// </param>
  282. /// <returns>
  283. /// Transformed vector (local coords).
  284. /// </returns>
  285. protected Point3D ToLocal(Point3D worldPoint)
  286. {
  287. var mat = Visual3DHelper.GetTransform(this);
  288. mat.Invert();
  289. var t = new MatrixTransform3D(mat);
  290. return t.Transform(worldPoint);
  291. }
  292. /// <summary>
  293. /// Transforms from local to world coordinates.
  294. /// </summary>
  295. /// <param name="point">
  296. /// The point (local coords).
  297. /// </param>
  298. /// <returns>
  299. /// Transformed point (world coords).
  300. /// </returns>
  301. protected Point3D ToWorld(Point3D point)
  302. {
  303. var mat = Visual3DHelper.GetTransform(this);
  304. var t = new MatrixTransform3D(mat);
  305. return t.Transform(point);
  306. }
  307. /// <summary>
  308. /// Transforms from local to world coordinates.
  309. /// </summary>
  310. /// <param name="vector">
  311. /// The vector (local coords).
  312. /// </param>
  313. /// <returns>
  314. /// Transformed vector (world coords).
  315. /// </returns>
  316. protected Vector3D ToWorld(Vector3D vector)
  317. {
  318. var mat = Visual3DHelper.GetTransform(this);
  319. var t = new MatrixTransform3D(mat);
  320. return t.Transform(vector);
  321. }
  322. /// <summary>
  323. /// The color changed.
  324. /// </summary>
  325. /// <param name="d">
  326. /// The sender.
  327. /// </param>
  328. /// <param name="e">
  329. /// The event arguments.
  330. /// </param>
  331. private static void ColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  332. {
  333. ((Manipulator)d).OnColorChanged();
  334. }
  335. /// <summary>
  336. /// Called when position has been changed.
  337. /// </summary>
  338. /// <param name="d">
  339. /// The sender.
  340. /// </param>
  341. /// <param name="e">
  342. /// The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.
  343. /// </param>
  344. private static void PositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  345. {
  346. ((Manipulator)d).OnPositionChanged();
  347. }
  348. /// <summary>
  349. /// The on color changed.
  350. /// </summary>
  351. private void OnColorChanged()
  352. {
  353. this.Model.Material = MaterialHelper.CreateMaterial(this.Color);
  354. this.Model.BackMaterial = this.Model.Material;
  355. }
  356. /// <summary>
  357. /// Called when position is changed.
  358. /// </summary>
  359. private void OnPositionChanged()
  360. {
  361. this.Transform = new TranslateTransform3D(this.Position.X + this.Offset.X, this.Position.Y + this.Offset.Y, this.Position.Z + this.Offset.Z);
  362. }
  363. #endregion
  364. }
  365. }