private Quaternion GetRotationForDelta() { DoubleVector screenPlane = new DoubleVector(1, 0, 0, 0, 1, 0); DoubleVector cameraPlane = new DoubleVector(_camera1.LookDirection.GetRotatedVector(_camera1.UpDirection, -90), _camera1.UpDirection); return screenPlane.GetRotation(cameraPlane); }
public void ViewChanged(DoubleVector lookDirection) { if (_marker2D != null) { _viewport.Children.Remove(_marker2D); } if (_marker2D == null) { _marker2D = new ScreenSpaceLines3D(); _marker2D.Color = UtilityWPF.ColorFromHex("60A0A0A0"); _marker2D.Thickness = 4d; } _marker2D.Clear(); RotateTransform3D transform = new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new DoubleVector(0, 0, 1, 0, -1, 0), lookDirection))); #region Marker 2D double orthDist = (_sizeMult * _field.Size * 1.1d) / 2d; double cornerDist = (_sizeMult * _field.Size * .2d) / 2d; // TopLeft Point3D corner = transform.Transform(new Point3D(-orthDist, -orthDist, -orthDist)); Vector3D direction = transform.Transform(new Vector3D(cornerDist, 0, 0)); _marker2D.AddLine(corner, corner + direction); direction = transform.Transform(new Vector3D(0, cornerDist, 0)); _marker2D.AddLine(corner, corner + direction); //TopRight corner = transform.Transform(new Point3D(orthDist, -orthDist, -orthDist)); direction = transform.Transform(new Vector3D(-cornerDist, 0, 0)); _marker2D.AddLine(corner, corner + direction); direction = transform.Transform(new Vector3D(0, cornerDist, 0)); _marker2D.AddLine(corner, corner + direction); //BottomRight corner = transform.Transform(new Point3D(orthDist, orthDist, -orthDist)); direction = transform.Transform(new Vector3D(-cornerDist, 0, 0)); _marker2D.AddLine(corner, corner + direction); direction = transform.Transform(new Vector3D(0, -cornerDist, 0)); _marker2D.AddLine(corner, corner + direction); //BottomLeft corner = transform.Transform(new Point3D(-orthDist, orthDist, -orthDist)); direction = transform.Transform(new Vector3D(cornerDist, 0, 0)); _marker2D.AddLine(corner, corner + direction); direction = transform.Transform(new Vector3D(0, -cornerDist, 0)); _marker2D.AddLine(corner, corner + direction); _viewport.Children.Add(_marker2D); #endregion // Camera _camera.Position = transform.Transform(new Point3D(0, 0, (_sizeMult * _field.Size * -4d) / 2d)); _camera.LookDirection = lookDirection.Standard; _camera.UpDirection = lookDirection.Orth; // Remember it _lookDirection = lookDirection; }
private void AddRope(Point3D bodyAttachPoint, Point3D anchorPoint, double? radianLimit) { const double SEGMENTLENGTH = .25d; if (_body == null) { throw new InvalidOperationException("The body must be created before this method is called"); } // Figure out how many rope segments to make Vector3D dir = anchorPoint - bodyAttachPoint; int numSegments = Convert.ToInt32(dir.Length / SEGMENTLENGTH); if (numSegments == 0) { numSegments = 1; } double segmentLength = dir.Length / numSegments; DoubleVector dirDbl = new DoubleVector(dir, Math3D.GetArbitraryOrhonganal(dir)); #region Anchor #region WPF Model // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Anchor))); materials.Children.Add(_colors.AnchorSpecular); // Geometry Mesh MeshGeometry3D mesh = UtilityWPF.GetSphere_LatLon(5, .1d); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = mesh; // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate //rotation = _defaultDirectionFacing.GetAngleAroundAxis(dirDbl); //transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation))); transform.Children.Add(new TranslateTransform3D(anchorPoint.ToVector())); // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; #endregion // Body CollisionHull hull = CollisionHull.CreateNull(_world); Body body = new Body(hull, model.Transform.Value, 0, new Visual3D[] { model }); hull.Dispose(); _anchorBodies.Add(body); // Add to the viewport _viewport.Children.Add(model); #endregion #region Rope for (int cntr = 0; cntr < numSegments; cntr++) { #region WPF Model // Material materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Rope))); materials.Children.Add(_colors.RopeSpecular); // Geometry Mesh mesh = UtilityWPF.GetCylinder_AlongX(7, .03d, segmentLength); CollisionHull ropeHull = CollisionHull.CreateCylinder(_world, 0, .03d, segmentLength, null); // Geometry Model geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = mesh; // Transform transform = new Transform3DGroup(); // rotate needs to be added before translate //Quaternion rotation = _defaultDirectionFacing.GetAngleAroundAxis(dirDbl); Vector3D axisStandard; double radiansStandard; Math3D.GetRotation(out axisStandard, out radiansStandard, _defaultDirectionFacing.Standard, dirDbl.Standard); Quaternion rotationStandard = new Quaternion(axisStandard, Math1D.RadiansToDegrees(radiansStandard)); //Vector3D axisOrth; //double radiansOrth; //Math3D.GetRotation(out axisOrth, out radiansOrth, _defaultDirectionFacing.Orth, dirDbl.Orth); //Quaternion rotationOrth = new Quaternion(axisOrth, Math3D.RadiansToDegrees(radiansOrth)); //Quaternion rotation = rotationStandard.ToUnit() * rotationOrth.ToUnit(); //Quaternion rotation = rotationOrth; Quaternion rotation = rotationStandard; // adding the orth in just messes it up transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation))); Vector3D segmentPosition = new Vector3D((segmentLength / 2d) + (segmentLength * cntr), 0, 0); segmentPosition = rotation.GetRotatedVector(segmentPosition); segmentPosition += bodyAttachPoint.ToVector(); transform.Children.Add(new TranslateTransform3D(segmentPosition)); // Model Visual model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; #endregion // Body body = new Body(ropeHull, model.Transform.Value, .1, new Visual3D[] { model }); ropeHull.Dispose(); #region Joint if (cntr == 0) { _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, bodyAttachPoint, _body, body)); } else { Vector3D connectPosition2 = new Vector3D(segmentLength * cntr, 0, 0); connectPosition2 = rotation.GetRotatedVector(connectPosition2); connectPosition2 += bodyAttachPoint.ToVector(); _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, connectPosition2.ToPoint(), _ropeBodies[_ropeBodies.Count - 1], body)); } if (cntr == numSegments - 1) { Vector3D connectPosition1 = new Vector3D(segmentLength * numSegments, 0, 0); connectPosition1 = rotation.GetRotatedVector(connectPosition1); connectPosition1 += bodyAttachPoint.ToVector(); _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, connectPosition1.ToPoint(), body, _anchorBodies[_anchorBodies.Count - 1])); } #endregion _ropeBodies.Add(body); // Add to the viewport _viewport.Children.Add(model); } if (radianLimit != null) { for (int cntr = 0; cntr < _ropeJoints.Count - 1; cntr++) // the connection between the anchor point and rope will never have a limit { ((JointBallAndSocket)_ropeJoints[cntr]).SetConeLimits(dir, radianLimit.Value, null); } } #endregion }
private void AddBrick(CollisionShapeType shape, Color color, Vector3D size, double mass, Point3D position, DoubleVector directionFacing) { // Get the wpf model CollisionHull hull; Transform3DGroup transform; Quaternion rotation; DiffuseMaterial bodyMaterial; ModelVisual3D model = GetWPFModel(out hull, out transform, out rotation, out bodyMaterial, shape, color, Colors.White, 100d, size, position, directionFacing, true); // Add to the viewport _viewport.Children.Add(model); // Make a physics body that represents this shape Body body = new Body(hull, transform.Value, 1d, new Visual3D[] { model }); hull.Dispose(); body.MaterialGroupID = _material_Brick; body.ApplyForceAndTorque += new EventHandler<BodyApplyForceAndTorqueArgs>(Body_ApplyForceAndTorque); _bricks.Add(body); _bodyMaterials.Add(body, new BodyMaterial(bodyMaterial, color, size.Length)); }
public static DoubleVector GetRotatedVector(this Quaternion quaternion, DoubleVector doubleVector) { Matrix3D matrix = new Matrix3D(); matrix.Rotate(quaternion); MatrixTransform3D transform = new MatrixTransform3D(matrix); return new DoubleVector(transform.Transform(doubleVector.Standard), transform.Transform(doubleVector.Orth)); }
/// <summary> /// This overload will rotate arrays of different types. Just pass null if you don't have any of that type /// </summary> public static void GetRotatedVector(this Quaternion quaternion, Vector3D[] vectors, Point3D[] points, DoubleVector[] doubleVectors) { Matrix3D matrix = new Matrix3D(); matrix.Rotate(quaternion); MatrixTransform3D transform = new MatrixTransform3D(matrix); if (vectors != null) { transform.Transform(vectors); } if (points != null) { transform.Transform(points); } if (doubleVectors != null) { for (int cntr = 0; cntr < doubleVectors.Length; cntr++) { doubleVectors[cntr] = new DoubleVector(transform.Transform(doubleVectors[cntr].Standard), transform.Transform(doubleVectors[cntr].Orth)); } } }
private void btnDrillHead_Click(object sender, RoutedEventArgs e) { try { Point3D position = Math3D.GetRandomVector_Circular(3).ToPoint(); position.Z = _lastTowerHeight + 5; Vector3D velocity = new Vector3D(0, 0, -3); Vector3D angularVelocity = new Vector3D(UtilityCore.GetScaledValue_Capped(0d, 400d, trkBulletSpeed.Minimum, trkBulletSpeed.Maximum, trkBulletSpeed.Value), 0, 0); // AddCannonBall rotates this so it will be about the z axis DoubleVector directionFacing = new DoubleVector(0, 0, -1, 1, 0, 0); Vector3D size = new Vector3D(3d, 5d, 0d); // x is radius, y is height AddCannonBall(CollisionShapeType.Cone, Colors.Indigo, size, 200d, position, velocity, angularVelocity, directionFacing); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
public Quaternion GetRotation(DoubleVector destination) { return Math3D.GetRotation(this, destination); }
private void btnBaseball_Click(object sender, RoutedEventArgs e) { try { Point3D position = GetCannonPosition(); Vector3D velocity = GetCannonVelocity(); Vector3D angularVelocity = new Vector3D(); DoubleVector directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity)); Vector3D size = new Vector3D(2d, 2d, 2d); AddCannonBall(CollisionShapeType.Sphere, Colors.GhostWhite, size, 5d, position, velocity, angularVelocity, directionFacing); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnWrecker_Click(object sender, RoutedEventArgs e) { try { Color color = Color.FromArgb(255, 50, 15, 15); Point3D position = GetCannonPosition(); Vector3D velocity = GetCannonVelocity(); Vector3D angularVelocity = new Vector3D(); DoubleVector directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity)); Vector3D size = new Vector3D(4d, 4d, 4d); AddCannonBall(CollisionShapeType.Sphere, color, size, 60d, position, velocity, angularVelocity, directionFacing); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnSlug_Click(object sender, RoutedEventArgs e) { try { Point3D position = GetCannonPosition(); Vector3D velocity = GetCannonVelocity(); Vector3D angularVelocity = new Vector3D(); DoubleVector directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity)); Vector3D size = new Vector3D(.5d, .8d, 0d); // x is radius, y is height AddCannonBall(CollisionShapeType.Cylinder, Colors.DimGray, size, 6d, position, velocity, angularVelocity, directionFacing); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void FireRaySprtShootBall() { Vector3D velocity = _rayDirection.ToUnit() * trkBulletSpeed.Value; DoubleVector directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity)); switch (cboLeftBallType.Text) { case "Nerf": #region Nerf AddCannonBall( CollisionShapeType.Cylinder, Colors.Coral, new Vector3D(.75d, 5d, 0d), // x is radius, y is height .1d, _rayPoint, velocity, new Vector3D(), directionFacing); #endregion break; case "Pellet": #region Pellet AddCannonBall( CollisionShapeType.Sphere, Colors.SteelBlue, new Vector3D(.5d, .5d, .5d), 2d, _rayPoint, velocity, new Vector3D(), directionFacing); #endregion break; case "Slug": #region Slug AddCannonBall( CollisionShapeType.Cylinder, Colors.DimGray, new Vector3D(.5d, .8d, 0d), // x is radius, y is height 6d, _rayPoint, velocity, new Vector3D(), directionFacing); #endregion break; case "Baseball": #region Baseball AddCannonBall( CollisionShapeType.Sphere, Colors.GhostWhite, new Vector3D(2d, 2d, 2d), 5d, _rayPoint, velocity, new Vector3D(), directionFacing); #endregion break; case "Cannon": #region Cannon AddCannonBall( CollisionShapeType.Sphere, Color.FromArgb(255, 45, 45, 32), new Vector3D(2d, 2d, 2d), 15d, _rayPoint, velocity, new Vector3D(), directionFacing); #endregion break; case "Wrecker": #region Wrecker AddCannonBall( CollisionShapeType.Sphere, Color.FromArgb(255, 50, 15, 15), new Vector3D(4d, 4d, 4d), 60d, _rayPoint, velocity, new Vector3D(), directionFacing); #endregion break; case "Shotgun": #region Shotgun // Build a transform to go from origin to camera DoubleVector originDirFacing = new DoubleVector(0, 0, 1, 0, 1, 0); Quaternion rotationToCameraRay = originDirFacing.GetRotation(new DoubleVector(_rayDirection, Math3D.GetArbitraryOrhonganal(_rayDirection))); Transform3DGroup transformToCamera = new Transform3DGroup(); transformToCamera.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotationToCameraRay))); transformToCamera.Children.Add(new TranslateTransform3D(_rayPoint.ToVector())); for (int cntr = 0; cntr < 10; cntr++) { Vector3D pos2D = Math3D.GetRandomVector_Circular(1d); //Vector3D vel2D = new Vector3D(pos2D.X, pos2D.Y, trkBulletSpeed.Value * 2d); //Point3D position = _rayPoint; velocity = _rayDirection.ToUnit() * trkBulletSpeed.Value * 2d; //TODO: Diverge the shot Point3D position = transformToCamera.Transform(pos2D.ToPoint()); //velocity = transformToCamera.Transform(vel2D); directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity)); AddCannonBall( CollisionShapeType.Sphere, Color.FromRgb(25, 25, 25), new Vector3D(.1d, .1d, .1d), .2d, position, velocity, new Vector3D(), directionFacing); } #endregion break; default: MessageBox.Show("Unknown ball type: " + cboLeftBallType.Text, this.Title, MessageBoxButton.OK, MessageBoxImage.Error); return; } }
private void BuildSpike(Point3D startPoint, bool isOneOfMany) { #region Figure out how many bricks double zLimit, zStep; if (radFew.IsChecked.Value) { zLimit = 30d; zStep = isOneOfMany ? 3d : 1d; } else if (radNormal.IsChecked.Value) { zLimit = 50d; zStep = isOneOfMany ? 2.5d : .5d; } else if (radMany.IsChecked.Value) { zLimit = 60d; zStep = isOneOfMany ? 1.5d : .33d; } else if (radExtreme.IsChecked.Value) { zLimit = 100d; zStep = isOneOfMany ? 1d : .25d; } else { MessageBox.Show("Unknow number of bricks", this.Title, MessageBoxButton.OK, MessageBoxImage.Error); return; } #endregion DoubleVector dirFacingColumn = new DoubleVector(0, 0, 1, -1, 0, 0); // x becomes z Color baseColor = UtilityWPF.GetRandomColor(64, 192); for (double z = 0d; z <= zLimit; z += zStep) // start on the floor { Color color = UtilityWPF.AlphaBlend(Colors.Black, baseColor, UtilityCore.GetScaledValue_Capped(0d, .5d, 0, zLimit, zLimit - z)); double radius = UtilityCore.GetScaledValue_Capped(.25d, 2d, 0d, zLimit, zLimit - z); Vector3D size = new Vector3D(radius, zStep, 0d); // x is radius, y is height double mass = radius * 2d; Point3D position = new Point3D(startPoint.X, startPoint.Y, startPoint.Z + z + (zStep / 2d)); AddBrick(CollisionShapeType.Cylinder, color, size, mass, position, dirFacingColumn); } _lastTowerHeight = zLimit + zStep; }
/// <summary> /// This fires combinations of thrusters to get to the destination /// </summary> /// <remarks> /// This is a higher level method than SetVelocity /// /// This sort of method would be useful when following a target /// </remarks> /// <param name="velocity">This is the velocity to be when the ship as at the destination point (doesn't matter what the velocity is when getting there)</param> /// <param name="spin">This is the spin to have when at the destination point</param> /// <param name="direction">This is the direction to face when at the destination point</param> private void SetDestination(Point3D point, Vector3D velocity, Vector3D? spin = null, DoubleVector? direction = null) { throw new ApplicationException("finish this"); }
private void btnTestIt_Click(object sender, RoutedEventArgs e) { Vector3D defaultStand = new Vector3D(LINELENGTH_X * .75d, 0, 0); Vector3D defaultOrth = new Vector3D(0, 0, LINELENGTH_Z * .75d); DoubleVector from = new DoubleVector(_orientationTrackballFrom.Transform.Transform(defaultStand), _orientationTrackballFrom.Transform.Transform(defaultOrth)); DoubleVector to = new DoubleVector(_orientationTrackballTo.Transform.Transform(defaultStand), _orientationTrackballTo.Transform.Transform(defaultOrth)); // This is the method that this form is testing Quaternion quat = from.GetRotation(to); //DoubleVector rotated = new DoubleVector(quat.GetRotatedVector(defaultStand), quat.GetRotatedVector(defaultOrth)); DoubleVector rotated = new DoubleVector(quat.GetRotatedVector(from.Standard), quat.GetRotatedVector(from.Orth)); // quat describes how to rotate from From to To (not from Default to To) //Vector3D axis = quat.Axis.ToUnit() * (LINELENGTH_X * 2d); Vector3D axis = _orientationTrackballFrom.Transform.Transform(quat.Axis.ToUnit() * (LINELENGTH_X * 1.5d)); // I rotate axis by from, because I want it relative to from (axis isn't in world coords) pnlReport.Children.Clear(); ClearTempVisuals(); ClearLines(_lineTransformed); _lineTransformed = AddLines(rotated, axis); }
/// <summary> /// This fires combinations of thrusters to try to get to the velocity/orientation passed in /// </summary> /// <remarks> /// The SetForce method is a direct control. SetVelocity is one step higher. /// /// The advantage of calling SetVelocity is that if there are unknown forces acting on the ship, this will /// account for that over time (less logic for the caller to implement) /// </remarks> private void SetVelocity(Vector3D velocity, Vector3D? spin = null, DoubleVector? direction = null) { throw new ApplicationException("finish this"); }
private ScreenSpaceLines3D[] AddLines(DoubleVector transformedLine, Vector3D rotationAxis) { ScreenSpaceLines3D[] retVal = new ScreenSpaceLines3D[4]; for (int cntr = 0; cntr < retVal.Length; cntr++) { retVal[cntr] = new ScreenSpaceLines3D(true); retVal[cntr].Color = _colors.RotatedLine; if (cntr == 1) { retVal[cntr].Thickness = 3d; // this one isn't really used } else if (cntr == 3) { retVal[cntr].Thickness = 1d; } else { retVal[cntr].Thickness = 6d; } } retVal[0].AddLine(new Point3D(0, 0, 0), transformedLine.Standard.ToPoint()); retVal[1].AddLine(new Point3D(0, 0, 0), new Point3D(0, 0, 0)); // just adding this so everything stays lined up retVal[2].AddLine(new Point3D(0, 0, 0), transformedLine.Orth.ToPoint()); retVal[3].AddLine(new Point3D(0, 0, 0), rotationAxis.ToPoint()); for (int cntr = 0; cntr < retVal.Length; cntr++) { _viewport.Children.Add(retVal[cntr]); } return retVal; }
/// <summary> /// This returns each link dotted with up /// NOTE: up must be a unit vector /// </summary> private static double[] GetDots(LinkResult2[] links, DoubleVector up, Point3D center, Vector3D line, Point3D[] points) { throw new ApplicationException("flawed"); // If it's an exact match, then the link is sitting on the center point if (links.Length == 1 && links[0].IsExactMatch) { return null; } double[] retVal = new double[links.Length]; for (int cntr = 0; cntr < links.Length; cntr++) { if (links[cntr].IsExactMatch) { throw new ApplicationException("Can't have an exact match in a list of non exact matches"); // or in any list greater than one } Point3D pointOnLine = Math3D.GetClosestPoint_Line_Point(center, line, points[links[cntr].Index]); // See if it's on the line //if( } // Exit Function return retVal; }
private ModelVisual3D GetWPFModel(out CollisionHull hull, out Transform3DGroup transform, out Quaternion rotation, out DiffuseMaterial bodyMaterial, CollisionShapeType shape, Color color, Color reflectionColor, double reflectionIntensity, Vector3D size, Point3D position, DoubleVector directionFacing, bool createHull) { // Material MaterialGroup materials = new MaterialGroup(); bodyMaterial = new DiffuseMaterial(new SolidColorBrush(color)); materials.Children.Add(bodyMaterial); materials.Children.Add(new SpecularMaterial(new SolidColorBrush(reflectionColor), reflectionIntensity)); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; hull = null; switch (shape) { case CollisionShapeType.Box: Vector3D halfSize = size / 2d; geometry.Geometry = UtilityWPF.GetCube_IndependentFaces(new Point3D(-halfSize.X, -halfSize.Y, -halfSize.Z), new Point3D(halfSize.X, halfSize.Y, halfSize.Z)); if (createHull) { hull = CollisionHull.CreateBox(_world, 0, size, null); } break; case CollisionShapeType.Sphere: geometry.Geometry = UtilityWPF.GetSphere_LatLon(5, size.X, size.Y, size.Z); if (createHull) { hull = CollisionHull.CreateSphere(_world, 0, size, null); } break; case CollisionShapeType.Cylinder: geometry.Geometry = UtilityWPF.GetCylinder_AlongX(20, size.X, size.Y); if (createHull) { hull = CollisionHull.CreateCylinder(_world, 0, size.X, size.Y, null); } break; case CollisionShapeType.Cone: geometry.Geometry = UtilityWPF.GetCone_AlongX(20, size.X, size.Y); if (createHull) { hull = CollisionHull.CreateCone(_world, 0, size.X, size.Y, null); } break; default: throw new ApplicationException("Unexpected CollisionShapeType: " + shape.ToString()); } // Transform transform = new Transform3DGroup(); // rotate needs to be added before translate //rotation = _defaultDirectionFacing.GetAngleAroundAxis(directionFacing); // can't use double vector, it over rotates (not anymore, but this is still isn't rotating correctly) rotation = Math3D.GetRotation(_defaultDirectionFacing.Standard, directionFacing.Standard); transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation))); transform.Children.Add(new TranslateTransform3D(position.ToVector())); // Model Visual ModelVisual3D retVal = new ModelVisual3D(); retVal.Content = geometry; retVal.Transform = transform; // Exit Function return retVal; }
public static void GetRotatedVector(this Quaternion quaternion, DoubleVector[] doubleVectors) { Matrix3D matrix = new Matrix3D(); matrix.Rotate(quaternion); MatrixTransform3D transform = new MatrixTransform3D(matrix); for (int cntr = 0; cntr < doubleVectors.Length; cntr++) { doubleVectors[cntr] = new DoubleVector(transform.Transform(doubleVectors[cntr].Standard), transform.Transform(doubleVectors[cntr].Orth)); } }
private void DrawMassBreakdown(UtilityNewt.IObjectMassBreakdown breakdown, double cellSize) { #region Draw masses as cubes double radMult = (cellSize * .75d) / breakdown.Max(o => o.Item2); DoubleVector dirFacing = new DoubleVector(1, 0, 0, 0, 1, 0); Model3DGroup geometries = new Model3DGroup(); foreach (var pointMass in breakdown) { double radius = pointMass.Item2 * radMult; CollisionHull dummy1; Transform3DGroup dummy2; Quaternion dummy3; DiffuseMaterial dummy4; geometries.Children.Add(GetWPFGeometry(out dummy1, out dummy2, out dummy3, out dummy4, CollisionShapeType.Box, _colors.MassBall, _colors.MassBallReflect, _colors.MassBallReflectIntensity, new Vector3D(radius, radius, radius), pointMass.Item1, dirFacing, false)); } ModelVisual3D visual = new ModelVisual3D(); visual.Content = geometries; _viewport.Children.Add(visual); _currentVisuals.Add(visual); #endregion #region Draw Axiis ScreenSpaceLines3D line = new ScreenSpaceLines3D(); line.Color = Colors.DimGray; line.Thickness = 2d; line.AddLine(new Point3D(0, 0, 0), new Point3D(10, 0, 0)); _viewport.Children.Add(line); _currentVisuals.Add(line); line = new ScreenSpaceLines3D(); line.Color = Colors.Silver; line.Thickness = 2d; line.AddLine(new Point3D(0, 0, 0), new Point3D(0, 10, 0)); _viewport.Children.Add(line); _currentVisuals.Add(line); line = new ScreenSpaceLines3D(); line.Color = Colors.White; line.Thickness = 2d; line.AddLine(new Point3D(0, 0, 0), new Point3D(0, 0, 10)); _viewport.Children.Add(line); _currentVisuals.Add(line); #endregion }
private void MoveHoverLight(MouseEventArgs e) { Point mousePos = e.GetPosition(pnlIconBorder); double width = pnlIconBorder.ActualWidth; double height = pnlIconBorder.ActualHeight; DoubleVector standard = new DoubleVector( ProjectToTrackball(width, height, new Point(width * .5d, height * .5d)), ProjectToTrackball(width, height, new Point(width * .5d, height))); Vector3D camPos = _camera.Position.ToVector(); Vector3D cross1 = Vector3D.CrossProduct(camPos, _camera.UpDirection * -1d); Vector3D cross2 = Vector3D.CrossProduct(cross1, camPos); DoubleVector camera = new DoubleVector(camPos, cross2); // can't use camera.up directly, because it's not nessassarily orthogonal // Attach the point to a sphere around the ship Vector3D projectedPos = ProjectToTrackball(width, height, mousePos); // Rotate this so that it's relative to the camera Quaternion rotation = standard.GetRotation(camera); _hoverLight.Position = rotation.GetRotatedVector(projectedPos * 2d).ToPoint(); }
private static Transform3D GetTransformTo2D(ITriangle triangle) { Vector3D line1 = triangle.Point1 - triangle.Point0; DoubleVector from = new DoubleVector(line1, Math3D.GetOrthogonal(line1, triangle.Point2 - triangle.Point0)); DoubleVector to = new DoubleVector(new Vector3D(1, 0, 0), new Vector3D(0, 1, 0)); Quaternion rotation = from.GetRotation(to); Transform3DGroup retVal = new Transform3DGroup(); // Rotate retVal.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation))); // Then translate retVal.Children.Add(new TranslateTransform3D(0, 0, -triangle.Point0.Z)); return retVal; }
private static RayHitTestParameters CastRay_PlaneLimitedSprtGetSnapLine(ITriangle plane, Vector3D lookDirection) { const double THRESHOLD = .33d; #region Get orthogonal vectors Point3D centerPoint = new Point3D(); DoubleVector testVectors = new DoubleVector(); //This assumes that the plane was set up with orthogonal vectors, and that these are the ones to use in this case for (int cntr = 0; cntr < 3; cntr++) { switch (cntr) { case 0: centerPoint = plane.Point0; testVectors = new DoubleVector((plane.Point1 - plane.Point0).ToUnit(), (plane.Point2 - plane.Point0).ToUnit()); break; case 1: centerPoint = plane.Point1; testVectors = new DoubleVector((plane.Point2 - plane.Point1).ToUnit(), (plane.Point0 - plane.Point1).ToUnit()); break; case 2: centerPoint = plane.Point2; testVectors = new DoubleVector((plane.Point0 - plane.Point2).ToUnit(), (plane.Point1 - plane.Point2).ToUnit()); break; default: throw new ApplicationException("Unexpected cntr: " + cntr.ToString()); } if (Math1D.IsNearZero(Vector3D.DotProduct(testVectors.Standard, testVectors.Orth))) { break; } } #endregion double dot = Vector3D.DotProduct(testVectors.Standard, lookDirection.ToUnit()); if (Math.Abs(dot) < THRESHOLD) { return new RayHitTestParameters(centerPoint, testVectors.Standard); // standard is fairly orhogonal to the camera's look direction, so only allow the part to slide along this axis } dot = Vector3D.DotProduct(testVectors.Orth, lookDirection.ToUnit()); if (Math.Abs(dot) < THRESHOLD) { return new RayHitTestParameters(centerPoint, testVectors.Orth); } return null; }
private void AddCannonBall(CollisionShapeType shape, Color color, Vector3D size, double mass, Point3D position, Vector3D velocity, Vector3D angularVelocity, DoubleVector directionFacing) { // Get the wpf model CollisionHull hull; Transform3DGroup transform; Quaternion rotation; DiffuseMaterial bodyMaterial; ModelVisual3D model = GetWPFModel(out hull, out transform, out rotation, out bodyMaterial, shape, color, Colors.Gray, 50d, size, position, directionFacing, true); // Add to the viewport _viewport.Children.Add(model); // Make a physics body that represents this shape Body body = new Body(hull, transform.Value, mass, new Visual3D[] { model }); hull.Dispose(); body.IsContinuousCollision = true; body.MaterialGroupID = _material_Projectile; body.Velocity = velocity; //body.AngularVelocity = Math3D.RotateAroundAxis(angularVelocity, axis, radians); body.AngularVelocity = rotation.GetRotatedVector(angularVelocity); body.AngularDamping = new Vector3D(0, 0, 0); // this one becomes very noticable with the big spinner body.ApplyForceAndTorque += new EventHandler<BodyApplyForceAndTorqueArgs>(Body_ApplyForceAndTorque); _projectiles.Add(body); _bodyMaterials.Add(body, new BodyMaterial(bodyMaterial, color, size.Length)); }