public DXEventManager3DWrapperSample() { InitializeComponent(); _selectedMaterial = new DiffuseMaterial(Brushes.Red); _unSelectedMaterial = new DiffuseMaterial(Brushes.Blue); LowerBoxVisual3D.SetName("LowerBoxVisual3D"); PassageBoxVisual3D.SetName("PassageBoxVisual3D"); UpperBoxVisual3D.SetName("UpperBoxVisual3D"); MovableVisualParent.SetName("MovableVisualParent"); MovableBoxVisual3D.SetName("MovableBoxVisual3D"); ArrowLineVisual3D.SetName("ArrowLineVisual3D"); Cylinder1.SetName("Cylinder1"); Cylinder2.SetName("Cylinder2"); Cylinder3.SetName("Cylinder3"); TransparentPlaneVisual3D.SetName("TransparentPlaneVisual3D"); this.Loaded += new RoutedEventHandler(DXEventManager3DWrapperSample_Loaded); // IMPORTANT: // It is very important to call Dispose method on DXSceneView after the control is not used any more (see help file for more info) this.Unloaded += (sender, args) => MainDXViewportView.Dispose(); }
// Token: 0x06000146 RID: 326 RVA: 0x00005CA4 File Offset: 0x00003EA4 public Face(Cylinder3 cylinder) { AffineTransform3 affineTransform = Transform3Factory.CreateOrthonormalBasis(cylinder.Axis.Direction); this.Surface = new CylinderSurface(cylinder.Axis.Origin, affineTransform.AxisX, affineTransform.AxisY, true, cylinder.Radius); this.Orientation = Orientation.Forward; this.Wires = new List <Wire3>().AsReadOnly(); }
public static void Test( Entity entity1, object[] boundingVolumes1, ref Matrix worldTransform1, ref Vector3 translation1, ref Quaternion rotation1, ref Vector3 scale1, Entity entity2, object[] boundingVolumes2, ref Matrix worldTransform2, ref Vector3 translation2, ref Quaternion rotation2, ref Vector3 scale2, bool needAllContacts, ref Contact contact ) { Debug.Assert(scale1.X == scale1.Y && scale1.Y == scale1.Z); Debug.Assert(scale2.X == scale2.Y && scale2.Y == scale2.Z); for (int i = 0; i < boundingVolumes1.Length; ++i) { Cylinder3 cylinder1 = (Cylinder3)boundingVolumes1[i]; for (int j = 0; j < boundingVolumes2.Length; ++j) { Cylinder3 cylinder2 = (Cylinder3)boundingVolumes2[j]; Vector3 top1 = Vector3.Transform(cylinder1.Top, worldTransform1); Vector3 bottom1 = Vector3.Transform(cylinder1.Bottom, worldTransform1); Vector3 top2 = Vector3.Transform(cylinder2.Top, worldTransform2); Vector3 bottom2 = Vector3.Transform(cylinder2.Bottom, worldTransform2); float radius1 = scale1.X * cylinder1.Radius; float radius2 = scale2.X * cylinder2.Radius; float minTop = top1.Y < top2.Y ? top1.Y : top2.Y; float maxBottom = bottom1.Y > bottom2.Y ? bottom1.Y : bottom2.Y; float overlap = minTop - maxBottom; if (overlap >= 0) { Vector3 projected1 = new Vector3(top1.X, 0, top1.Z); Vector3 projected2 = new Vector3(top2.X, 0, top2.Z); Vector3 normal = projected2 - projected1; float radiusSum = radius1 + radius2; if (normal.LengthSquared() < radiusSum * radiusSum) { // collision normal.Normalize(); Vector3 position = projected1 + normal * radius1 + Vector3.UnitY * (minTop - overlap / 2.0f); contact.AddContactPoint(ref position, ref normal); } } } } }
/// <summary>Tests whether a cylinder is touching a sphere</summary> /// <param name="cylinderTransform">Orientation and position of the cylinder</param> /// <param name="cylinderRadius">The cylinder's radius</param> /// <param name="cylinderLength">The cylinder's length</param> /// <param name="sphereCenter">Location of the sphere's center</param> /// <param name="sphereRadius">The sphere's radius</param> /// <returns>True if the objects are touching each other</returns> public static bool CheckContact( Matrix cylinderTransform, float cylinderRadius, float cylinderLength, Vector3 sphereCenter, float sphereRadius ) { // Determine the sphere's center in the cylinder's relative orientation Vector3 localSphereCenter = new Vector3( Vector3.Dot(sphereCenter, cylinderTransform.Right), Vector3.Dot(sphereCenter, cylinderTransform.Up), Vector3.Dot(sphereCenter, cylinderTransform.Forward) ); Vector3 closest = Cylinder3.GetClosestPoint( cylinderRadius, cylinderLength, localSphereCenter ); // If the closest point is within the sphere's radius, we've got a collision return((closest - localSphereCenter).LengthSquared() < (sphereRadius * sphereRadius)); }
public void TestCheckContact() { Cylinder3 testCylinder = new Cylinder3( Matrix.Identity, 10.0f, 5.0f ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, Vector3.Zero, 5.0f ), "Fully contained sphere is detected to overlap with the cylinder" ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(-20.0f + Specifications.HullAccuracy, 0.0f, 0.0f), 10.0f ), "Close hit of cylinder on X axis (left side) detected" ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(20.0f - Specifications.HullAccuracy, 0.0f, 0.0f), 10.0f ), "Close hit of cylinder on X axis (right side) detected" ); Assert.IsFalse( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(-20.0f - Specifications.HullAccuracy, 0.0f, 0.0f), 10.0f ), "Close miss of cylinder on X axis (left side) properly handled" ); Assert.IsFalse( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(20.0f + Specifications.HullAccuracy, 0.0f, 0.0f), 10.0f ), "Close miss of cylinder on X axis (right side) properly handled" ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, -20.0f + Specifications.HullAccuracy, 0.0f), 10.0f ), "Close hit of cylinder on Y axis (lower side) detected" ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, 20.0f - Specifications.HullAccuracy, 0.0f), 10.0f ), "Close hit of cylinder on Y axis (upper side) detected" ); Assert.IsFalse( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, -20.0f - Specifications.HullAccuracy, 0.0f), 10.0f ), "Close miss of cylinder on Y axis (lower side) properly handled" ); Assert.IsFalse( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, 20.0f + Specifications.HullAccuracy, 0.0f), 10.0f ), "Close miss of cylinder on Y axis (upper side) properly handled" ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, 0.0f, -12.5f + Specifications.HullAccuracy), 10.0f ), "Close hit of cylinder on Z axis (front side) detected" ); Assert.IsTrue( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, 0.0f, 12.5f - Specifications.HullAccuracy), 10.0f ), "Close hit of cylinder on Z axis (back side) detected" ); Assert.IsFalse( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, 0.0f, -12.5f - Specifications.HullAccuracy), 10.0f ), "Close miss of cylinder on Z axis (front side) properly handled" ); Assert.IsFalse( CylinderSphereCollider.CheckContact( testCylinder.Transform, testCylinder.Radius, testCylinder.Height, new Vector3(0.0f, 0.0f, 12.5f + Specifications.HullAccuracy), 10.0f ), "Close miss of cylinder on Z axis (back side) properly handled" ); }
public static void Test( Entity entity1, object[] boundingVolumes1, ref Matrix worldTransform1, ref Vector3 translation1, ref Quaternion rotation1, ref Vector3 scale1, Entity entity2, object[] boundingVolumes2, ref Matrix worldTransform2, ref Vector3 translation2, ref Quaternion rotation2, ref Vector3 scale2, bool needAllContacts, ref Contact contact ) { Debug.Assert(scale1.X == scale1.Y && scale1.Y == scale1.Z); Debug.Assert(scale2.X == scale2.Y && scale2.Y == scale2.Z); for (int i = 0; i < boundingVolumes1.Length; ++i) { Sphere3 sphere1 = (Sphere3)boundingVolumes1[i]; for (int j = 0; j < boundingVolumes2.Length; ++j) { Cylinder3 cylinder2 = (Cylinder3)boundingVolumes2[j]; Vector3 center1 = Vector3.Transform(sphere1.Center, worldTransform1); float radius1 = scale1.X * sphere1.Radius; Vector3 top2 = Vector3.Transform(cylinder2.Top, worldTransform2); Vector3 bottom2 = Vector3.Transform(cylinder2.Bottom, worldTransform2); float radius2 = scale2.X * cylinder2.Radius; // sphere is on same level as the cylinder if (center1.Y <= top2.Y && center1.Y >= bottom2.Y) { // distance between the two Vector3 diff = top2 - center1; diff.Y = 0; // we are only interested in horizontal distance float collisionLengthSquared = (radius2 + radius1) * (radius2 + radius1); if (diff.LengthSquared() < collisionLengthSquared) { diff.Normalize(); Vector3 point = center1 + diff * radius1; contact.AddContactPoint(ref point, ref diff); } } // above cylinder... else if (center1.Y > top2.Y) { if (center1.Y - radius1 < top2.Y) { // project to top cylinder 'plane' Vector3 projected = center1; projected.Y = top2.Y; Vector3 toProjected = projected - top2; if (toProjected.LengthSquared() < radius2 * radius2) { Vector3 normal = -Vector3.UnitY; contact.AddContactPoint(ref projected, ref normal); } else { toProjected.Normalize(); Vector3 nearestPoint = top2 + toProjected * radius2; Vector3 diff = nearestPoint - center1; if (diff.LengthSquared() < radius1 * radius1) { Vector3 normal = -Vector3.UnitY; contact.AddContactPoint(ref nearestPoint, ref normal); } } } } // below cylinder else if (center1.Y < bottom2.Y) { if (center1.Y + radius1 < bottom2.Y) { // project to bottom cylinder 'plane' Vector3 projected = center1; projected.Y = bottom2.Y; Vector3 toProjected = projected - bottom2; if (toProjected.LengthSquared() < radius2 * radius2) { Vector3 normal = Vector3.UnitY; contact.AddContactPoint(ref projected, ref normal); } else { toProjected.Normalize(); Vector3 nearestPoint = bottom2 + toProjected * radius2; Vector3 diff = nearestPoint - center1; if (diff.LengthSquared() < radius1 * radius1) { Vector3 normal = Vector3.UnitY; contact.AddContactPoint(ref nearestPoint, ref normal); } } } } else { // we covered all cases... Debug.Assert(false); } } } }