示例#1
0
        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();
        }
示例#2
0
文件: Face.cs 项目: mh-soft/mh-master
        // 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 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);
                    }
                }
            }
        }