예제 #1
0
        //NOTE:  I'm keeping the number of constructor overloads small, and instead making the user call one of the static creation methods.  Otherwise it would be very
        //confusing to know what you're creating

        protected CollisionHull(IntPtr handle, WorldBase world, float[] offsetMatrix, CollisionShapeType collisionShape)
        {
            _handle = handle;
            _world = world;
            _offsetMatrix = offsetMatrix;
            _collisionShape = collisionShape;

            ObjectStorage.Instance.AddCollisionHull(_handle, this);
        }
예제 #2
0
        internal static CollisionHull CreateSensorCollisionHull(WorldBase world, Vector3D scale, Quaternion orientation, Point3D position)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(orientation)));
            transform.Children.Add(new TranslateTransform3D(position.ToVector()));

            // Scale X and Y should be identical, but average them to be safe
            double radius = ((SIZEPERCENTOFSCALE_XY * scale.X) + (SIZEPERCENTOFSCALE_XY * scale.Y)) / 2d;

            return CollisionHull.CreateCylinder(world, 0, radius, SIZEPERCENTOFSCALE_Z * scale.Z, transform.Value);
        }
예제 #3
0
        internal static CollisionHull CreateSensorCollisionHull(WorldBase world, Vector3D scale, Quaternion orientation, Point3D position)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(orientation)));
            transform.Children.Add(new TranslateTransform3D(position.ToVector()));

            Vector3D size = new Vector3D(SIZEPERCENTOFSCALE * scale.X, SIZEPERCENTOFSCALE * scale.Y, SIZEPERCENTOFSCALE * scale.Z);

            return CollisionHull.CreateBox(world, 0, size, transform.Value);
        }
예제 #4
0
 public override CollisionHull CreateCollisionHull(WorldBase world)
 {
     return ShieldEnergyDesign.CreateCollisionHull(world, this.Scale, this.Orientation, this.Position);
 }
예제 #5
0
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            Vector3D size = new Vector3D(this.Scale.X * SCALE * .5d, this.Scale.Y * SCALE * .5d, this.Scale.Z * SCALE * .5d);

            return CollisionHull.CreateSphere(world, 0, size, transform.Value);
        }
예제 #6
0
 public CollisionHullDestroyedArgs(WorldBase world, CollisionHull collisionHull)
 {
     this.World = world;
     this.CollisionHull = collisionHull;
 }
예제 #7
0
 private CollisionHullTree(IntPtr handle, WorldBase world, float[] offsetMatrix)
     : base(handle, world, offsetMatrix, CollisionShapeType.Tree) { }
예제 #8
0
        public static CollisionHull CreateCompoundCollision(WorldBase world, int shapeID, CollisionHull[] hulls)
        {
            IntPtr[] handles = new IntPtr[hulls.Length];
            for (int cntr = 0; cntr < hulls.Length; cntr++)
            {
                handles[cntr] = hulls[cntr].Handle;
            }

            IntPtr handle = Newton.NewtonCreateCompoundCollision(world.Handle, hulls.Length, handles, shapeID);

            return new CollisionHull(handle, world, null, CollisionShapeType.Compound);
        }
예제 #9
0
        public static CollisionHull CreateConvexHull(WorldBase world, int shapeID, IEnumerable<Point3D> verticies, Matrix3D? offsetMatrix = null, double tolerance = .002d)
        {
            //NOTE:  If the mesh passed in is concave, newton will make it convex.  If you require concave, build up a complex collision out of convex primitives
            //NOTE:  Must have at least 4 verticies

            #region Tolerance Comments

            // Got this from here:
            //http://newtondynamics.com/wiki/index.php5?title=NewtonCreateConvexHull

            // dFloat tolerance - the vertex optimization tolerance. A higher number means the hull can be simplified where there are multiple vertices with distance lower than
            // the tolerance; this is useful when generating simpler convex hulls from highly detailed meshes.


            // It's new in Newton 2 and can speed up the performance by reducing the count of vertices of a convex hull.
            // Here is the description by Julio Jerez (author of Newton):

            // The convex hull tolerance does not always apply and it is hard to predict, say for example you have a box, then the parameter will do nothing because adjacent plane
            // bend 90 degree.
            //
            // Say some body have a cube with bevel edges, the at the corner you will have many points that are very close to each other this result on a convex hull that is very dense
            // on the edges and the vertex.
            //
            // In that case the tolerance parameter does make a difference. What is does is that after the Hull is made, for each vertex, an average plane is created by fanning of all the
            // vertices that can be reach from a direct edge going out of that vertex.
            //
            // If the distance from each vertex to the average plane is very small, 
            // And the distance from the center vertex to the plane is smaller than the tolerance, 
            // Then the center vertex can be extracted from the hull and the hull can be reconstructed, 
            // The resulting shape will not be too different from the ideal one. 
            //
            // It continues doing that until not more vertex can be subtracted from the original shape.
            //
            // Basically what is does is that is remove lots of vertices that are too close and make the shep to dense for collision.
            //
            // A tolerance of 0.002 is good candidate especially when you have large cloud of vertices because it will eliminate points that are a 2 millimeter of less from the ideal hull,
            // It leads to a great speed up in collision time.
            //
            // (additional note: this value depends to the kind of application and their dimensions)
            // Since Newton 2.25 the tolerance depend of the diagonal of the cloud point (or bounding box). Ex: A prism with large and small dimension (580 x 0.5 x 580) will have
            // a large diagonal (820). If you set tolerance at 0.001 then the function will eliminate point that are less close of 820*0.001=0.8 units. So your prism become a plane and
            // the function return NULL. To resolve this error just set a lower tolerance. This change was made to get same shape for hull with different scale.

            #endregion

            // Offset Matrix
            float[] newtOffsetMatrix = null;		// null means no offset
            if (offsetMatrix != null)
            {
                newtOffsetMatrix = new NewtonMatrix(offsetMatrix.Value).Matrix;
            }

            int vertexCount = verticies.Count();

            // Verticies
            float[,] vertexArray = new float[vertexCount, 3];

            int i = 0;
            foreach (Point3D vertex in verticies)
            {
                vertexArray[i, 0] = (float)vertex.X;
                vertexArray[i, 1] = (float)vertex.Y;
                vertexArray[i, 2] = (float)vertex.Z;
                i++;
            }

            // Create in newton
            IntPtr handle = Newton.NewtonCreateConvexHull(world.Handle, vertexCount, vertexArray, sizeof(float) * 3, Convert.ToSingle(tolerance), shapeID, newtOffsetMatrix);

            // Exit Function
            return new CollisionHull(handle, world, newtOffsetMatrix, CollisionShapeType.ConvexHull);
        }
예제 #10
0
 public virtual CollisionHull CreateCollisionHull(WorldBase world)
 {
     return this.Design.CreateCollisionHull(world);
 }
예제 #11
0
        internal static CollisionHull CreateTankCollisionHull(WorldBase world, Vector3D scale, Quaternion orientation, Point3D position)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)));		// the physics hull is along x, but dna is along z
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(orientation)));
            transform.Children.Add(new TranslateTransform3D(position.ToVector()));

            double radius = RADIUSPERCENTOFSCALE * (scale.X + scale.Y) * .5d;
            double height = scale.Z;

            if (height < radius * 2d)
            {
                // Newton keeps the capsule caps spherical, but the visual scales them.  So when the height is less than the radius, newton
                // make a sphere.  So just make a cylinder instead
                //return CollisionHull.CreateChamferCylinder(world, 0, radius, height, transform.Value);
                return CollisionHull.CreateCylinder(world, 0, radius, height, transform.Value);
            }
            else
            {
                //NOTE: The visual changes the caps around, but I want the physics to be a capsule
                return CollisionHull.CreateCapsule(world, 0, radius, height, transform.Value);
            }
        }
예제 #12
0
 public override CollisionHull CreateCollisionHull(WorldBase world)
 {
     return FuelTankDesign.CreateTankCollisionHull(world, this.Scale, this.Orientation, this.Position);
 }
예제 #13
0
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            //transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)));		// only needed for one/two types
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            Vector3D scale = this.Scale;

            switch (this.ThrusterType)
            {
                case ShipParts.ThrusterType.One:
                case ShipParts.ThrusterType.Two:
                    #region Cylinder

                    transform.Children.Insert(0, new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)));		// the physics hull is along x, but dna is along z

                    double radius = RADIUSPERCENTOFSCALE * (scale.X + scale.Y) * .5d;
                    double height = scale.Z;

                    if (height < radius * 2d)
                    {
                        // Newton keeps the capsule caps spherical, but the visual scales them.  So when the height is less than the radius, newton
                        // make a sphere.  So just make a cylinder instead
                        //return CollisionHull.CreateChamferCylinder(world, 0, radius, height, transform.Value);
                        return CollisionHull.CreateCylinder(world, 0, radius, height, transform.Value);
                    }
                    else
                    {
                        //NOTE: The visual changes the caps around, but I want the physics to be a capsule
                        return CollisionHull.CreateCapsule(world, 0, radius, height, transform.Value);
                    }

                #endregion

                default:
                    #region Convex Hull

                    if (_pointsForHull == null)
                    {
                        CreateGeometry(true, false);        // passing false, because this may be executing in a different thread
                    }

                    double maxScale = Math1D.Max(scale.X * RADIUSPERCENTOFSCALE, scale.Y * RADIUSPERCENTOFSCALE, scale.Z);

                    //NOTE: _pointsForHull comes off the wpf model points, and is already rotated properly
                    Point3D[] points = _pointsForHull.Select(o => new Point3D(o.X * maxScale, o.Y * maxScale, o.Z * maxScale)).ToArray();

                    return CollisionHull.CreateConvexHull(world, 0, points, transform.Value);

                    #endregion
            }
        }
 public override CollisionHull CreateCollisionHull(WorldBase world)
 {
     return ConverterEnergyToFuelDesign.CreateCollisionHull(world, this.Scale, this.Orientation, this.Position);
 }
예제 #15
0
        public static CollisionHull CreateCapsule(WorldBase world, int shapeID, double radius, double height, Matrix3D? offsetMatrix)
        {
            //NOTE:  Height must be >= diameter.  If you want less, use ChamferCylinder

            float[] newtOffsetMatrix = null;		// null means no offset
            if (offsetMatrix != null)
            {
                newtOffsetMatrix = new NewtonMatrix(offsetMatrix.Value).Matrix;
            }

            IntPtr handle = Newton.NewtonCreateCapsule(world.Handle, Convert.ToSingle(radius), Convert.ToSingle(height), shapeID, newtOffsetMatrix);

            return new CollisionHull(handle, world, newtOffsetMatrix, CollisionShapeType.Capsule);
        }
예제 #16
0
        public static CollisionHull CreateChamferCylinder(WorldBase world, int shapeID, double radius, double height, Matrix3D? offsetMatrix)
        {
            //TODO: Figure out what is wrong when this is tall and skinny

            float[] newtOffsetMatrix = null;		// null means no offset
            if (offsetMatrix != null)
            {
                newtOffsetMatrix = new NewtonMatrix(offsetMatrix.Value).Matrix;
            }

            IntPtr handle = Newton.NewtonCreateChamferCylinder(world.Handle, Convert.ToSingle(radius), Convert.ToSingle(height), shapeID, newtOffsetMatrix);

            return new CollisionHull(handle, world, newtOffsetMatrix, CollisionShapeType.ChamferCylinder);
        }
예제 #17
0
        //public abstract Model3D GetFinalModel();

        //TODO: Make this abstract
        /// <summary>
        /// This is what gets handed to the physics body
        /// </summary>
        public virtual CollisionHull CreateCollisionHull(WorldBase world)
        {
            throw new ApplicationException("make this abstract");
        }
예제 #18
0
        public static CollisionHull CreateHeightFieldCollision(WorldBase world, int shapeID, short[,] heights, byte[,] materialIDs, bool gridsDiagonals_TopleftToBottomright, double horizontalScale, double verticalScale)
        {
            //NOTE:  Height field doesn't look at the body's mass, it is static (terrain).  Other stuff bounces off of this

            // I believe materialIDs is the material ID for each grid point, so the terrain can have different elasticities/friction

            //TODO:  Make a helper method that builds a height field out of a bitmap (or 2 bitmaps, one for the heights, one for the materials)

            // Turn the 2D array into a 1D array
            int width = heights.GetUpperBound(0);
            int height = heights.GetUpperBound(1);
            if (materialIDs.GetUpperBound(0) != width || materialIDs.GetUpperBound(1) != height)
            {
                throw new ArgumentException(string.Format("The height array is a different size than the materialID array (height={0}x{1}, material={2}x{3}", width.ToString(), height.ToString(), materialIDs.GetUpperBound(0).ToString(), materialIDs.GetUpperBound(1).ToString()));
            }

            short[] heights1D = new short[width * height];
            byte[] materials1D = new byte[heights1D.Length];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    heights1D[(width * x) + y] = heights[x, y];
                    materials1D[(width * x) + y] = materialIDs[x, y];
                }
            }

            // Convert bool to int
            int gridsDiagonals = gridsDiagonals_TopleftToBottomright ? 1 : 0;		// false is bottom left to top right

            // Create in newton
            IntPtr handle = Newton.NewtonCreateHeightFieldCollision(world.Handle, width, height, gridsDiagonals, heights1D, materials1D, Convert.ToSingle(horizontalScale), Convert.ToSingle(verticalScale), shapeID);

            // Exit Function
            return new CollisionHull(handle, world, null, CollisionShapeType.HeightField);
        }
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            Vector3D scale = this.Scale;

            return CollisionHull.CreateSphere(world, 0, new Vector3D(scale.X * RADIUSPERCENTOFSCALE, scale.Y * RADIUSPERCENTOFSCALE, scale.Z * HEIGHTPERCENTOFSCALE), transform.Value);
        }
        internal static CollisionHull CreateCollisionHull(WorldBase world, Vector3D scale, Quaternion orientation, Point3D position)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)));		// the physics hull is along x, but dna is along z
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(orientation)));
            transform.Children.Add(new TranslateTransform3D(position.ToVector()));

            double radius = RADIUSPERCENTOFSCALE * (scale.X + scale.Y) * .5d;
            double height = scale.Z * HEIGHTPERCENTOFSCALE;

            //return CollisionHull.CreateChamferCylinder(world, 0, radius, height, transform.Value);
            return CollisionHull.CreateCylinder(world, 0, radius, height, transform.Value);
        }
예제 #21
0
        internal static CollisionHull CreateCollisionHull(WorldBase world, Vector3D scale, Quaternion orientation, Point3D position)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(orientation)));
            transform.Children.Add(new TranslateTransform3D(position.ToVector()));

            Vector3D size = new Vector3D(scale.X * .5d, scale.Y * .5d, scale.Z * .5d);

            return CollisionHull.CreateSphere(world, 0, size, transform.Value);
        }
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            return CollisionHull.CreateBox(world, 0, this.Scale * ConverterMatterToFuelDesign.SCALE, transform.Value);
        }
예제 #23
0
 public override CollisionHull CreateCollisionHull(WorldBase world)
 {
     return CreateSensorCollisionHull(world, this.Scale, this.Orientation, this.Position);
 }
예제 #24
0
 public MaterialManager(WorldBase world)
 {
     _world = world;
 }
예제 #25
0
 // These methods are used to create a collision (see class remarks for a description of the shapeID)
 //NOTE:  ShapeID means nothing to newton, it's just a way for the consumer to give special tokens to things (safe to pass zero for everything)
 //NOTE:  Elsewhere, the shapeID is considered a uint.  So to be safe, stay positive
 public static CollisionHull CreateNull(WorldBase world)
 {
     IntPtr handle = Newton.NewtonCreateNull(world.Handle);
     return new CollisionHull(handle, world, null, CollisionShapeType.Null);
 }
예제 #26
0
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)));		// the physics hull is along x, but dna is along z
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            Vector3D scale = this.Scale;
            double radius = Math1D.Avg(RADIUSPERCENTOFSCALE_WIDE, RADIUSPERCENTOFSCALE_NARROW) * Math1D.Avg(scale.X, scale.Y);
            double height = HEIGHT * scale.Z;

            return CollisionHull.CreateCylinder(world, 0, radius, height, transform.Value);
        }
예제 #27
0
        public static CollisionHull CreateBox(WorldBase world, int shapeID, Vector3D size, Matrix3D? offsetMatrix)
        {
            float[] newtOffsetMatrix = null;		// null means no offset
            if (offsetMatrix != null)
            {
                newtOffsetMatrix = new NewtonMatrix(offsetMatrix.Value).Matrix;
            }

            IntPtr handle = Newton.NewtonCreateBox(world.Handle, Convert.ToSingle(size.X), Convert.ToSingle(size.Y), Convert.ToSingle(size.Z), shapeID, newtOffsetMatrix);

            return new CollisionHull(handle, world, newtOffsetMatrix, CollisionShapeType.Box);
        }
예제 #28
0
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)));		// the physics hull is along x, but dna is along z
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            Vector3D scale = this.Scale;
            double radius = RADIUSPERCENTOFSCALE * ((scale.X + scale.Y) * .5d);
            double height = scale.Z;

            return CollisionHull.CreateCylinder(world, 0, radius, height, transform.Value);
            //return CollisionHull.CreateChamferCylinder(world, 0, radius, height, transform.Value);		//Chamfer collides weird when it's tall and skinny
        }
예제 #29
0
        public override CollisionHull CreateCollisionHull(WorldBase world)
        {
            Transform3DGroup transform = new Transform3DGroup();
            //transform.Children.Add(new ScaleTransform3D(this.Scale));		// it ignores scale
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(this.Orientation)));
            transform.Children.Add(new TranslateTransform3D(this.Position.ToVector()));

            Vector3D scale = this.Scale;
            Vector3D size = new Vector3D(1d * scale.X, RATIOY * scale.Y, RATIOZ * scale.Z);

            return CollisionHull.CreateBox(world, 0, size, transform.Value);
        }