| 39 |
private Point3D _cameraLookPoint; |
private Point3D _cameraLookPoint; |
| 40 |
private RotateTransform3D _rotationTransform = new RotateTransform3D(); |
private RotateTransform3D _rotationTransform = new RotateTransform3D(); |
| 41 |
ModelVisual3D clickedVisual; |
ModelVisual3D clickedVisual; |
| 42 |
|
|
| 43 |
|
Transform3DGroup clickedtransformGroup; |
| 44 |
private TranslateTransform3D _clickedTranslate = new TranslateTransform3D(); |
private TranslateTransform3D _clickedTranslate = new TranslateTransform3D(); |
| 45 |
|
private TranslateTransform3D _clickedTranslateOriginal = new TranslateTransform3D(); |
| 46 |
|
private RotateTransform3D _clickedRotate = new RotateTransform3D(); |
| 47 |
|
private AxisAngleRotation3D _clickedAxisAngleRotate = new AxisAngleRotation3D(); |
| 48 |
|
|
| 49 |
bool isTracking = false; |
bool isTracking = false; |
| 50 |
|
|
| 51 |
public CameraControl(PerspectiveCamera camera) |
public CameraControl(PerspectiveCamera camera) |
| 52 |
{ |
{ |
| 53 |
_camera = camera; |
_camera = camera; |
| 54 |
|
|
| 55 |
_rotationTransform.Rotation = _rotation; |
_rotationTransform.Rotation = _rotation; |
|
_transform = new Transform3DGroup(); |
|
| 56 |
|
|
| 57 |
|
_transform = new Transform3DGroup(); |
| 58 |
//_transform.Children.Add(_translate); |
//_transform.Children.Add(_translate); |
| 59 |
_transform.Children.Add(_rotationTransform); |
_transform.Children.Add(_rotationTransform); |
| 60 |
// _transform.Children.Add(_scale); |
// _transform.Children.Add(_scale); |
| 61 |
|
|
| 62 |
|
//for pan and rotate the object |
| 63 |
|
|
| 64 |
|
//clickedtransformGroup = new Transform3DGroup(); |
| 65 |
|
//clickedtransformGroup.Children.Add(_clickedRotate); |
| 66 |
|
//clickedtransformGroup.Children.Add(_clickedTranslate); |
| 67 |
} |
} |
| 68 |
|
|
| 69 |
/// <summary> |
/// <summary> |
| 107 |
double scale = e.Delta / 1200.00; |
double scale = e.Delta / 1200.00; |
| 108 |
double distance = Point3D.Subtract(_cameraLookPoint, _camera.Position).Length; |
double distance = Point3D.Subtract(_cameraLookPoint, _camera.Position).Length; |
| 109 |
|
|
| 110 |
if (distance > 1024 || distance <= 0.5) |
if (distance > 1024 || distance <= 1) |
| 111 |
{ |
{ |
| 112 |
if (touch == false) |
if (touch == false) |
| 113 |
{ |
{ |
| 121 |
|
|
| 122 |
if (touch == true) |
if (touch == true) |
| 123 |
scale = -scale; |
scale = -scale; |
| 124 |
_camera.Position = new Point3D(_camera.Position.X - scale * _cameraLookDirection.X, _camera.Position.Y - scale * _cameraLookDirection.Y, _camera.Position.Z - scale * _cameraLookDirection.Z); |
_camera.Position = new Point3D(_camera.Position.X + scale * _cameraLookDirection.X, |
| 125 |
|
_camera.Position.Y + scale * _cameraLookDirection.Y, |
| 126 |
|
_camera.Position.Z + scale * _cameraLookDirection.Z); |
| 127 |
_camera.LookDirection = Point3D.Subtract(_cameraLookPoint, _camera.Position); |
_camera.LookDirection = Point3D.Subtract(_cameraLookPoint, _camera.Position); |
| 128 |
} |
} |
| 129 |
|
|
| 141 |
if (visul3d == null) |
if (visul3d == null) |
| 142 |
return; |
return; |
| 143 |
|
|
| 144 |
_clickedTranslate = visul3d.Transform as TranslateTransform3D; |
Transform3DGroup group = visul3d.Transform as Transform3DGroup; |
| 145 |
if (_clickedTranslate == null) |
if (group != null) |
| 146 |
return; |
{ |
| 147 |
|
if (group.Children[0] != null) |
| 148 |
|
{ |
| 149 |
|
_clickedRotate = group.Children[0] as RotateTransform3D; |
| 150 |
|
_clickedRotate.Rotation = _clickedAxisAngleRotate; |
| 151 |
|
} |
| 152 |
|
if (group.Children[1] !=null) |
| 153 |
|
_clickedTranslate = group.Children[1] as TranslateTransform3D; |
| 154 |
|
} |
| 155 |
|
//if (_clickedTranslate == null) |
| 156 |
|
// return; |
| 157 |
|
|
| 158 |
|
//for pan the object |
| 159 |
clickedVisual = visul3d; |
clickedVisual = visul3d; |
| 160 |
clickedVisual.Transform = _clickedTranslate; |
//clickedVisual.Transform = _clickedRotate;// clickedtransformGroup;// _clickedTranslate; |
| 161 |
|
_clickedTranslateOriginal = _clickedTranslate.Clone(); |
| 162 |
|
|
| 163 |
|
|
| 164 |
|
//for ALT + MOUSE + ROTATE |
| 165 |
Petzold.Media3D.LineRange line; |
Petzold.Media3D.LineRange line; |
| 166 |
Petzold.Media3D.ViewportInfo.Point2DtoPoint3D(_eventSource as Viewport3D, pclick, out line); |
Petzold.Media3D.ViewportInfo.Point2DtoPoint3D(_eventSource as Viewport3D, pclick, out line); |
| 167 |
_cameraLookPoint = line.PointFromY(visul3d.Content.Bounds.Y); |
_cameraLookPoint = line.PointFromY(visul3d.Content.Bounds.Y); |
| 170 |
_rotationTransform.CenterY = _cameraLookPoint.Y; |
_rotationTransform.CenterY = _cameraLookPoint.Y; |
| 171 |
_rotationTransform.CenterZ = _cameraLookPoint.Z; |
_rotationTransform.CenterZ = _cameraLookPoint.Z; |
| 172 |
|
|
| 173 |
|
//for rotate the object mouse clicked |
| 174 |
|
_clickedRotate.CenterX = _cameraLookPoint.X; |
| 175 |
|
_clickedRotate.CenterY = _cameraLookPoint.Y; |
| 176 |
|
_clickedRotate.CenterZ = _cameraLookPoint.Z; |
| 177 |
|
|
| 178 |
|
|
| 179 |
_cameraLookDirection = Point3D.Subtract(_cameraLookPoint, _camera.Position); |
_cameraLookDirection = Point3D.Subtract(_cameraLookPoint, _camera.Position); |
| 180 |
_camera.LookDirection = _cameraLookDirection; |
_camera.LookDirection = _cameraLookDirection; |
| 181 |
|
|
| 182 |
|
//TRACK BALL |
| 183 |
|
_previousPosition3D = ProjectToTrackball( |
| 184 |
|
EventSource.ActualWidth, |
| 185 |
|
EventSource.ActualHeight, |
| 186 |
|
_previousPosition2D); |
| 187 |
|
|
| 188 |
isTracking = true; |
isTracking = true; |
| 189 |
_eventSource.CaptureMouse(); |
_eventSource.CaptureMouse(); |
| 190 |
_eventSource.Focus(); |
_eventSource.Focus(); |
| 196 |
Mouse.Capture(EventSource, CaptureMode.None); |
Mouse.Capture(EventSource, CaptureMode.None); |
| 197 |
isTracking = false; |
isTracking = false; |
| 198 |
|
|
| 199 |
|
//_clickedRotate = null; |
| 200 |
|
//_clickedAxisAngleRotate = null; |
| 201 |
|
//_clickedTranslate = null; |
| 202 |
|
//_clickedTranslateOriginal = null; |
| 203 |
|
|
| 204 |
_eventSource.ReleaseMouseCapture(); |
_eventSource.ReleaseMouseCapture(); |
| 205 |
_eventSource.Cursor = Cursors.Arrow; |
_eventSource.Cursor = Cursors.Arrow; |
| 206 |
string mmm = mm; |
string mmm = mm; |
| 226 |
{ |
{ |
| 227 |
CameraPanUP(currentPosition); |
CameraPanUP(currentPosition); |
| 228 |
} |
} |
| 229 |
|
else if (e.RightButton == MouseButtonState.Pressed && Keyboard.IsKeyDown(Key.A)) |
| 230 |
|
{ |
| 231 |
|
CameraPanLeft(currentPosition); |
| 232 |
|
} |
| 233 |
|
else if (e.LeftButton == MouseButtonState.Pressed && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) |
| 234 |
|
&& (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))) |
| 235 |
|
{ |
| 236 |
|
if (isTracking) |
| 237 |
|
RotateObject(currentPosition); |
| 238 |
|
} |
| 239 |
|
|
| 240 |
else if (e.LeftButton == MouseButtonState.Pressed && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) |
else if (e.LeftButton == MouseButtonState.Pressed && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) |
| 241 |
{ |
{ |
| 242 |
|
if(isTracking) |
| 243 |
PanObject(currentPosition); |
PanObject(currentPosition); |
| 244 |
} |
} |
| 245 |
|
|
| 246 |
_previousPosition2D = currentPosition; |
_previousPosition2D = currentPosition; |
| 247 |
} |
} |
| 248 |
|
|
| 249 |
|
private void RotateObject(Point currentPosition) |
| 250 |
|
{ |
| 251 |
|
|
| 252 |
|
//double axisAngle = currentPosition.X - _previousPosition2D.X; |
| 253 |
|
//double angletimes = axisAngle; |
| 254 |
|
|
| 255 |
|
//if (angletimes > 360 || angletimes < -360) |
| 256 |
|
// angletimes = 0; |
| 257 |
|
|
| 258 |
|
//if (angletimes + _clickedAxisAngleRotate.Angle >= 360) |
| 259 |
|
// _clickedAxisAngleRotate.Angle = 0; |
| 260 |
|
|
| 261 |
|
Vector3D currentPosition3D = ProjectToTrackball(clickedVisual.Content.Bounds.SizeX, clickedVisual.Content.Bounds.SizeZ, |
| 262 |
|
/*EventSource.ActualWidth, EventSource.ActualHeight, */currentPosition); |
| 263 |
|
|
| 264 |
|
Vector3D axis = Vector3D.CrossProduct(_previousPosition3D, currentPosition3D); |
| 265 |
|
double angle = Vector3D.AngleBetween(_previousPosition3D, currentPosition3D); |
| 266 |
|
Quaternion delta = new Quaternion(axis, -angle); |
| 267 |
|
|
| 268 |
|
// Get the current orientantion from the RotateTransform3D |
| 269 |
|
AxisAngleRotation3D r = _rotation; |
| 270 |
|
Quaternion q = new Quaternion(_rotation.Axis, _rotation.Angle); |
| 271 |
|
|
| 272 |
|
// Compose the delta with the previous orientation |
| 273 |
|
q *= delta; |
| 274 |
|
|
| 275 |
|
|
| 276 |
|
_clickedRotate.CenterX = _cameraLookPoint.X; |
| 277 |
|
_clickedRotate.CenterY = _cameraLookPoint.Y; |
| 278 |
|
_clickedRotate.CenterZ = _cameraLookPoint.Z; |
| 279 |
|
|
| 280 |
|
// Write the new orientation back to the Rotation3D |
| 281 |
|
_clickedAxisAngleRotate.Axis = q.Axis; |
| 282 |
|
_clickedAxisAngleRotate.Angle += q.Angle; |
| 283 |
|
|
| 284 |
|
|
| 285 |
|
_previousPosition3D = currentPosition3D; |
| 286 |
|
|
| 287 |
|
//_clickedAxisAngleRotate.Axis = new Vector3D(0, 0, 1); |
| 288 |
|
//_clickedAxisAngleRotate.Angle += axisAngle; |
| 289 |
|
} |
| 290 |
|
|
| 291 |
|
private Vector3D ProjectToTrackball(double width, double height, Point point) |
| 292 |
|
{ |
| 293 |
|
double x = point.X / (width / 2); // Scale so bounds map to [0,0] - [2,2] |
| 294 |
|
double y = point.Y / (height / 2); |
| 295 |
|
|
| 296 |
|
x = x - 1; // Translate 0,0 to the center |
| 297 |
|
y = 1 - y; // Flip so +Y is up instead of down |
| 298 |
|
|
| 299 |
|
double z2 = 1 - x * x - y * y; // z^2 = 1 - x^2 - y^2 |
| 300 |
|
double z = z2 > 0 ? Math.Sqrt(z2) : 0; |
| 301 |
|
|
| 302 |
|
return new Vector3D(x, y, z); |
| 303 |
|
} |
| 304 |
|
|
| 305 |
|
#endregion Event Handling |
| 306 |
|
|
| 307 |
|
private void CameraPanLeft(Point currentPosition) |
| 308 |
|
{ |
| 309 |
|
LineRange range; |
| 310 |
|
ViewportInfo.Point2DtoPoint3D(_eventSource as Viewport3D, currentPosition, out range); |
| 311 |
|
Point3D pointNew = range.PointFromY(clickedVisual.Content.Bounds.Y); |
| 312 |
|
|
| 313 |
|
//_camera.Position. |
| 314 |
|
} |
| 315 |
|
|
| 316 |
private void PanObject(Point currentPosition) |
private void PanObject(Point currentPosition) |
| 317 |
{ |
{ |
| 318 |
double scale = currentPosition.Y - _previousPosition2D.Y; |
double scaley = currentPosition.Y - _previousPosition2D.Y; |
| 319 |
scale = scale / 5; |
scaley = scaley / 100.00; |
| 320 |
|
|
| 321 |
|
|
| 322 |
|
double scalex = currentPosition.X - _previousPosition2D.X; |
| 323 |
|
scalex = scalex / 100.00; |
| 324 |
|
|
| 325 |
|
//double scalez = Math.Sqrt(scalex * scalex + scaley * scaley); |
| 326 |
|
|
| 327 |
LineRange range; |
LineRange range; |
| 328 |
ViewportInfo.Point2DtoPoint3D(_eventSource as Viewport3D, currentPosition, out range); |
ViewportInfo.Point2DtoPoint3D(_eventSource as Viewport3D, currentPosition, out range); |
| 329 |
Point3D pointNew = range.PointFromZ(clickedVisual.Content.Bounds.X); |
Point3D pointNew = range.PointFromY(clickedVisual.Content.Bounds.Y); |
|
//Vector3D v = pointNew- new Point3D(clickedVisual.Content.Bounds.X,clickedVisual.Content.Bounds.Y,clickedVisual.Content.Bounds.Z); |
|
| 330 |
|
|
| 331 |
Vector3D vectMouse = pointNew - _cameraLookPoint; |
Vector3D vectMouse = pointNew - _cameraLookPoint; |
| 332 |
_clickedTranslate.OffsetX = _clickedTranslate.OffsetX + vectMouse.X; |
_clickedTranslate.OffsetX = _clickedTranslateOriginal.OffsetX + vectMouse.X; |
| 333 |
_clickedTranslate.OffsetY = _clickedTranslate.OffsetY + vectMouse.Y; |
_clickedTranslate.OffsetY = _clickedTranslateOriginal.OffsetY + vectMouse.Y; |
| 334 |
_clickedTranslate.OffsetZ = _clickedTranslate.OffsetZ + vectMouse.Z; |
_clickedTranslate.OffsetZ = _clickedTranslateOriginal.OffsetZ + vectMouse.Z;// vectMouse.Z; |
| 335 |
|
|
|
//_camera.LookDirection = new Vector3D(_camera.LookDirection.X, _camera.LookDirection.Y, _camera.LookDirection.Z + scale); |
|
| 336 |
|
|
| 337 |
} |
} |
| 338 |
|
|
|
#endregion Event Handling |
|
| 339 |
|
|
| 340 |
private void LookUpDown(Point currentPosition) |
private void LookUpDown(Point currentPosition) |
| 341 |
{ |
{ |