Max() 공개 정적인 메소드

public static Max ( Vector3D, lhs, Vector3D, rhs ) : Vector3D,
lhs Vector3D,
rhs Vector3D,
리턴 Vector3D,
예제 #1
0
        public static (double Size, Vector3D Center) GetBound(IEnumerable <Vector3D> positions)
        {
            var minPos = positions.Aggregate(Vector3D.MaxValue, (s, n) => Vector3D.Min(s, n));
            var maxPos = positions.Aggregate(Vector3D.MinValue, (s, n) => Vector3D.Max(s, n));
            var size   = Vector3D.Distance(minPos, maxPos);
            var center = (minPos + maxPos) / 2;

            return(size, center);
        }
            private int GetDivideIndex(ref Vector3D translation)
            {
                Vector3I     renderCellCoord;
                BoundingBoxD lodAabb             = m_boundingBoxes.GetAabb(m_boundingBoxes.GetRoot());
                Vector3D     relativeTranslation = Vector3D.Max(translation - lodAabb.Min, Vector3D.Zero);

                MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lod, ref relativeTranslation, out renderCellCoord);
                return(GetDivideIndex(ref renderCellCoord));
            }
예제 #3
0
        public MyBBSetSampler(Vector3D min, Vector3D max)
        {
            Vector3D newMax = Vector3D.Max(min, max);
            Vector3D newMin = Vector3D.Min(min, max);

            m_bBox = new BoundingBoxD(newMin, newMax);

            m_sampler = new IntervalSampler(newMin.X, newMax.X, (newMax.Y - newMin.Y) * (newMax.Z - newMin.Z), Base6Directions.Axis.LeftRight);
        }
예제 #4
0
        public static void CreateMerged(ref BoundingBoxD original, ref BoundingBoxD additional, out BoundingBoxD result)
        {
            Vector3D vectord;
            Vector3D vectord2;

            Vector3D.Min(ref original.Min, ref additional.Min, out vectord);
            Vector3D.Max(ref original.Max, ref additional.Max, out vectord2);
            result.Min = vectord;
            result.Max = vectord2;
        }
예제 #5
0
        /// <summary>
        /// Creates the smallest BoundingBox that contains the two specified BoundingBox instances.
        /// </summary>
        /// <param name="original">One of the BoundingBox instances to contain.</param><param name="additional">One of the BoundingBox instances to contain.</param><param name="result">[OutAttribute] The created BoundingBox.</param>
        public static void CreateMerged(ref BoundingBoxD original, ref BoundingBoxD additional, out BoundingBoxD result)
        {
            Vector3D result1;

            Vector3D.Min(ref original.Min, ref additional.Min, out result1);
            Vector3D result2;

            Vector3D.Max(ref original.Max, ref additional.Max, out result2);
            result.Min = result1;
            result.Max = result2;
        }
예제 #6
0
        public Vector3D MaxCoord()
        {
            Vector3D maxCoord = new Vector3D(double.MinValue, double.MinValue, double.MinValue);

            for (int i = 0, j = 0; i < vertexCount; i++, j += 3)
            {
                Vector3D v = new Vector3D(vertexPos, j);
                maxCoord = Vector3D.Max(maxCoord, v);
            }
            return(maxCoord);
        }
예제 #7
0
        public void Vector3MaxTest()
        {
            Vector3D <float> a = new Vector3D <float>(-1.0f, 4.0f, -3.0f);
            Vector3D <float> b = new Vector3D <float>(2.0f, 1.0f, -1.0f);

            Vector3D <float> expected = new Vector3D <float>(2.0f, 4.0f, -1.0f);
            Vector3D <float> actual;

            actual = Vector3D.Max(a, b);
            Assert.True(MathHelper.Equal(expected, actual), "Vector3D<float>.Max did not return the expected value.");
        }
예제 #8
0
        public static Vector3D MaxCoord(TriMesh mesh)
        {
            Vector3D maxCoord = new Vector3D(double.MinValue, double.MinValue, double.MinValue);

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                Vector3D v = mesh.Vertices[i].Traits.Position;
                maxCoord = Vector3D.Max(maxCoord, v);
            }
            return(maxCoord);
        }
예제 #9
0
    private bool TickThrusters(MotionState state, MotionTarget target)
    {
        Vector3D currentVelocity = state.VelocityLocal;
        Vector3D currentPosition = Vector3D.Transform(state.Position, state.WorldMatrixInverse);
        Vector3D currentGravity  = state.GravityLocal;

        Vector3D targetSpeed    = target.Speed;
        Vector3D targetPosition = Vector3D.Transform(target.Position ?? (state.Position + (targetSpeed + currentVelocity) * DELTA * .66), state.WorldMatrixInverse);

        Vector3D speedDifference    = targetSpeed - currentVelocity;
        Vector3D positionDifference = targetPosition - currentPosition;

        if (speedDifference.LengthSquared() < velocityPrecision && positionDifference.LengthSquared() < positionPrecision)
        {
            ClearThrustersOverride();
            SetDampeners(true);
            return(true);
        }


        Vector3D deceleration       = GetAccelerations(speedDifference) + currentGravity;
        Vector3D decelerationTimes  = speedDifference / deceleration;
        Vector3D positionAtFullStop = currentPosition + currentVelocity * decelerationTimes + deceleration * decelerationTimes * decelerationTimes / 2;

        Vector3D maxAccelerationDelta = targetPosition - positionAtFullStop;
        Vector3D shipAcceleration     = GetAccelerations(maxAccelerationDelta);
        Vector3D acceleration         = shipAcceleration + currentGravity;
        Vector3D accelerationForTick  = (maxAccelerationDelta - currentVelocity * DELTA) / DELTA_SQ_2 - currentGravity;
        Vector3D overrides            = Vector3D.Max(-Vector3D.One, Vector3D.Min(Vector3D.One, 0.5 * accelerationForTick / shipAcceleration)) * 100;

        if (maxAccelerationDelta.X < 0)
        {
            overrides.X = -overrides.X;
        }
        if (maxAccelerationDelta.Y < 0)
        {
            overrides.Y = -overrides.Y;
        }
        if (maxAccelerationDelta.Z < 0)
        {
            overrides.Z = -overrides.Z;
        }

        if (currentVelocity.LengthSquared() >= maxSpeed * maxSpeed && (overrides * currentVelocity).Min() >= -0.01)
        {
            ClearThrustersOverride();
            return(false);
        }

        SetDampeners(decelerationTimes.Max() < DELTA);
        SetThrustersOverride(overrides);
        return(false);
    }
예제 #10
0
        public override float GetVolume(ref Vector3D voxelPosition)
        {
            if (base.m_inverseIsDirty)
            {
                base.m_inverse        = MatrixD.Invert(base.m_transformation);
                base.m_inverseIsDirty = false;
            }
            voxelPosition = Vector3D.Transform(voxelPosition, base.m_inverse);
            Vector3D vectord = Vector3D.Abs(voxelPosition) - this.Boundaries.HalfExtents;
            double   num     = Vector3D.Dot(voxelPosition, this.RampNormal) + this.RampNormalW;

            return(base.SignedDistanceToDensity((float)Math.Max(vectord.Max(), -num)));
        }
예제 #11
0
        public override float GetVolume(ref Vector3D voxelPosition)
        {
            if (base.m_inverseIsDirty)
            {
                base.m_inverse        = MatrixD.Invert(base.m_transformation);
                base.m_inverseIsDirty = false;
            }
            voxelPosition = Vector3D.Transform(voxelPosition, base.m_inverse);
            Vector3D center   = this.Boundaries.Center;
            Vector3D vectord2 = Vector3D.Abs(voxelPosition - center) - (center - this.Boundaries.Min);

            return(base.SignedDistanceToDensity((float)vectord2.Max()));
        }
        public static Vector3D Center(this IEnumerable <IMyCubeGrid> grids)
        {
            Vector3D min = Vector3D.MaxValue;
            Vector3D max = Vector3D.MinValue;

            foreach (var grid in grids)
            {
                min = Vector3D.Min(min, grid.WorldAABB.Min);
                max = Vector3D.Max(max, grid.WorldAABB.Max);
            }

            return((min + max) / 2.0);
        }
예제 #13
0
        public static MatrixD AsMatrixD(this MyPositionAndOrientation posAndOrient)
        {
            var         matrix = MatrixD.CreateWorld(posAndOrient.Position, posAndOrient.Forward, posAndOrient.Up);
            const float offset = 100.0f;

            if (MyAPIGatewayShortcuts.GetWorldBoundaries == null)
            {
                return(matrix);
            }
            var bound = MyAPIGatewayShortcuts.GetWorldBoundaries();

            matrix.Translation = Vector3D.Min(Vector3D.Max(matrix.Translation, bound.Min + offset), bound.Max - offset);
            return(matrix);
        }
예제 #14
0
        public static MyDefinitionId?VoxelMaterialAt(this MyVoxelBase voxel, Vector3D min, Vector3D grow,
                                                     ref MyStorageData cache)
        {
            if (cache == null)
            {
                cache = new MyStorageData();
            }
            var      shape = new BoundingBoxD(Vector3D.Min(min, min + grow), Vector3D.Max(min, min + grow));
            Vector3I voxMin;
            Vector3I voxMax;
            Vector3I voxCells;

            GetVoxelShapeDimensions(voxel, shape, out voxMin, out voxMax, out voxCells);
            Vector3I_RangeIterator cellsItr = new Vector3I_RangeIterator(ref Vector3I.Zero, ref voxCells);

            while (cellsItr.IsValid())
            {
                Vector3I cellMinCorner;
                Vector3I cellMaxCorner;
                GetCellCorners(ref voxMin, ref voxMax, ref cellsItr, out cellMinCorner, out cellMaxCorner);
                Vector3I rangeMin = cellMinCorner - 1;
                Vector3I rangeMax = cellMaxCorner + 1;
                voxel.Storage.ClampVoxelCoord(ref rangeMin);
                voxel.Storage.ClampVoxelCoord(ref rangeMax);
                cache.Resize(rangeMin, rangeMax);
                voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, rangeMin, rangeMax);

                var mortonCode    = -1;
                var maxMortonCode = cache.Size3D.Size;
                while (++mortonCode < maxMortonCode)
                {
                    Vector3I pos;
                    MyMortonCode3D.Decode(mortonCode, out pos);
                    var content = cache.Content(ref pos);
                    if (content <= MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                    {
                        continue;
                    }
                    var material = cache.Material(ref pos);
                    var def      = MyDefinitionManager.Static.GetVoxelMaterialDefinition(material);
                    if (def != null)
                    {
                        return(def.Id);
                    }
                }
                cellsItr.MoveNext();
            }

            return(null);
        }
예제 #15
0
 public Solve(List <Vector3D> _points, List <Thetra> _thetras, double[,] _coefficients, double[] _q, Func <double, double, double, double> _exact)
 {
     q      = _q;
     points = _points;
     max    = points[0];
     min    = points[0];
     foreach (Vector3D item in points)
     {
         max = Vector3D.Max(item, max);
         min = Vector3D.Min(item, min);
     }
     thetras      = _thetras;
     coefficients = _coefficients;
     exact        = _exact;
 }
예제 #16
0
            private bool TryGetDivideIndex(ref Vector3D translation, out int divideIndex)
            {
                divideIndex = 0;
                if (m_boundingBoxes.GetRoot() < 0)
                {
                    return(false);
                }

                Vector3I     renderCellCoord;
                BoundingBoxD lodAabb             = m_boundingBoxes.GetAabb(m_boundingBoxes.GetRoot());
                Vector3D     relativeTranslation = Vector3D.Max(translation - lodAabb.Min, Vector3D.Zero);

                MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lod, ref relativeTranslation, out renderCellCoord);
                divideIndex = GetDivideIndex(ref renderCellCoord);
                return(true);
            }
예제 #17
0
        /// <summary>
        /// Constructs a <see cref="SlimMath.BoundingBox"/> that fully contains the given points.
        /// </summary>
        /// <param name="points">The points that will be contained by the box.</param>
        /// <returns>The newly constructed bounding box.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="points"/> is <c>null</c>.</exception>
        public static BoundingBox FromPoints(Vector3D[] points)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            Vector3D min = new Vector3D(double.MaxValue);
            Vector3D max = new Vector3D(double.MinValue);

            for (int i = 0; i < points.Length; ++i)
            {
                Vector3D.Min(ref min, ref points[i], out min);
                Vector3D.Max(ref max, ref points[i], out max);
            }

            return(new BoundingBox(min, max));
        }
예제 #18
0
        public void Vector3MinMaxCodeCoverageTest()
        {
            Vector3D <float> min = Vector3D <float> .Zero;
            Vector3D <float> max = Vector3D <float> .One;
            Vector3D <float> actual;

            // Min.
            actual = Vector3D.Min(min, max);
            Assert.Equal(actual, min);

            actual = Vector3D.Min(max, min);
            Assert.Equal(actual, min);

            // Max.
            actual = Vector3D.Max(min, max);
            Assert.Equal(actual, max);

            actual = Vector3D.Max(max, min);
            Assert.Equal(actual, max);
        }
예제 #19
0
        public void Vector3MinMaxCodeCoverageTest()
        {
            Vector3D min = Vector3D.Zero;
            Vector3D max = Vector3D.One;
            Vector3D actual;

            // Min.
            actual = Vector3D.Min(min, max);
            Assert.AreEqual(actual, min);

            actual = Vector3D.Min(max, min);
            Assert.AreEqual(actual, min);

            // Max.
            actual = Vector3D.Max(min, max);
            Assert.AreEqual(actual, max);

            actual = Vector3D.Max(max, min);
            Assert.AreEqual(actual, max);
        }
예제 #20
0
        public void Draw()
        {
            MatrixD  transfromMatrix = this.Origin.TransformMatrix;
            Vector3D min             = Vector3D.One;
            Vector3D max             = Vector3D.Zero;

            for (int i = 0; i < 8; i++)
            {
                Vector3D corner = World.MySector.MainCamera.WorldToScreen(ref m_corners[i]);
                min = Vector3D.Min(min, corner);
                max = Vector3D.Max(max, corner);
            }

            Vector3D distProj  = max - min; // distance vec in screen coordinates (from 0 to 1, where 1 is screen width(for X) or height(for Y)
            float    lineWidth = BBOX_BORDER_THICKNESS_MODIF / (float)MathHelper.Clamp(distProj.Length(), 0.01, 1);

            Color boxColor = RenderColor;

            BoundingBoxD box = new BoundingBoxD(-m_boundingBox.HalfExtent, m_boundingBox.HalfExtent);

            MySimpleObjectDraw.DrawTransparentBox(ref transfromMatrix, ref box, ref boxColor, MySimpleObjectRasterizer.SolidAndWireframe, 1, lineWidth, "Square", "Square");

            if (Engine.Utils.MyFakes.ENABLE_DEBUG_DRAW_COORD_SYS)
            {
                //x
                for (int i = -10; i < 11; i++)
                {
                    Vector3D v1 = this.Origin.Position + transfromMatrix.Forward * 20 + transfromMatrix.Right * (i * 2.5);
                    Vector3D v2 = this.Origin.Position - transfromMatrix.Forward * 20 + transfromMatrix.Right * (i * 2.5);
                    VRageRender.MyRenderProxy.DebugDrawLine3D(v1, v2, boxColor, boxColor, false);
                }
                //y
                for (int i = -10; i < 11; i++)
                {
                    Vector3D v1 = this.Origin.Position + transfromMatrix.Right * 20 + transfromMatrix.Forward * (i * 2.5);
                    Vector3D v2 = this.Origin.Position - transfromMatrix.Right * 20 + transfromMatrix.Forward * (i * 2.5);
                    VRageRender.MyRenderProxy.DebugDrawLine3D(v1, v2, boxColor, boxColor, false);
                }
            }
        }
예제 #21
0
        public void Draw()
        {
            MatrixD  transfromMatrix = this.Origin.TransformMatrix;
            Vector3D min             = Vector3D.One;
            Vector3D max             = Vector3D.Zero;

            for (int i = 0; i < 8; i++)
            {
                Vector3D corner = World.MySector.MainCamera.WorldToScreen(ref m_corners[i]);
                min = Vector3D.Min(min, corner);
                max = Vector3D.Max(max, corner);
            }

            Vector3D distProj  = max - min; // distance vec in screen coordinates (from 0 to 1, where 1 is screen width(for X) or height(for Y)
            float    lineWidth = BBOX_BORDER_THICKNESS_MODIF / (float)MathHelper.Clamp(distProj.Length(), 0.01, 1);

            Color boxColor = RenderColor;

            BoundingBoxD box = new BoundingBoxD(-m_boundingBox.HalfExtent, m_boundingBox.HalfExtent);

            MySimpleObjectDraw.DrawTransparentBox(ref transfromMatrix, ref box, ref boxColor, MySimpleObjectRasterizer.SolidAndWireframe, 1, lineWidth, "Square", "Square");
        }
예제 #22
0
        internal void DebugDraw(Vector3I sectorPos, float sectorSize)
        {
            foreach (var part in m_instanceParts.Values)
            {
                foreach (var data in part.InstanceData)
                {
                    var dist = (data.LocalMatrix.Translation - Sandbox.Game.World.MySector.MainCamera.Position).Length();
                    if (dist < 30)
                    {
                        MyRenderProxy.DebugDrawText3D(data.LocalMatrix.Translation, part.SubtypeId.ToString(), Color.Red, (float)(7.0 / dist), true);
                    }
                }
            }

            BoundingBoxD bb  = new BoundingBoxD(sectorPos * sectorSize, (sectorPos + Vector3I.One) * sectorSize);
            BoundingBoxD bb2 = new BoundingBoxD(m_AABB.Min, m_AABB.Max);

            bb2.Min = Vector3D.Max(bb2.Min, bb.Min);
            bb2.Max = Vector3D.Min(bb2.Max, bb.Max);
            MyRenderProxy.DebugDrawAABB(bb, Color.Orange, 1.0f, 1.0f, true);
            MyRenderProxy.DebugDrawAABB(bb2, Color.OrangeRed, 1.0f, 1.0f, true);
        }
예제 #23
0
        public static BoundingBoxD CreateFromPoints(IEnumerable <Vector3D> points)
        {
            if (points == null)
            {
                throw new ArgumentNullException();
            }
            bool     flag     = false;
            Vector3D vectord  = new Vector3D(double.MaxValue);
            Vector3D vectord2 = new Vector3D(double.MinValue);

            foreach (Vector3D vectord3 in points)
            {
                Vector3D vectord4 = vectord3;
                Vector3D.Min(ref vectord, ref vectord4, out vectord);
                Vector3D.Max(ref vectord2, ref vectord4, out vectord2);
                flag = true;
            }
            if (!flag)
            {
                throw new ArgumentException();
            }
            return(new BoundingBoxD(vectord, vectord2));
        }
예제 #24
0
        //double IntersectionLineAndSphere(Vector3D centerPoint, double radius, Vector3D lineOrigin, Vector3D lineDir)
        //{
        //    // https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection
        //    Vector3D c = centerPoint;
        //    double r = radius;
        //    Vector3D o = lineOrigin;
        //    Vector3D l = lineDir;

        //    double sq1 = Math.Pow(Vector3D.Dot((o - c)*(o - c), l), 2);
        //    double sq2 = l.LengthSquared() * ((o - c).LengthSquared() - r*r);
        //    double sq = sq1 - sq2;
        //    MyRenderProxy.Assert(sq >= 0, "the line needs to be crossing sphere! Some internal bug...");
        //    double d1 = Vector3D.Dot(l, o - c);
        //    return -d1 + Math.Sqrt(sq);

        //}

        MatrixD CreateRigidLightMatrix(Vector3D[] verts, Vector3D lightDir, double zOffset)
        {
            // Create orthoghonal vectors:
            Vector3D lightUp    = Math.Abs(Vector3.UnitX.Dot(lightDir)) < 0.99f ? Vector3.UnitX : Vector3.UnitY;
            Vector3D lightRight = Vector3.Cross(lightDir, lightUp);

            lightUp = Vector3D.Cross(lightRight, lightDir);
            lightUp.Normalize();
            lightRight.Normalize();

            // Look for the most compact encapsulation of verts: ... vMin and vMax will contain corners of encapsulation box with sides defined lightUp, lightRight,and lightDir
            var lightMatrix    = MatrixD.CreateLookAt(new Vector3D(0, 0, 0), lightDir, lightUp);
            var invLightMatrix = MatrixD.Invert(lightMatrix);

            Vector3D.Transform(verts, ref lightMatrix, m_tmpCreateOrthoVertsLS);
            Vector3D vMinLS = m_tmpCreateOrthoVertsLS[0];
            Vector3D vMaxLS = m_tmpCreateOrthoVertsLS[0];

            for (uint i = 1; i < verts.Length; i++)
            {
                vMinLS = Vector3D.Min(vMinLS, m_tmpCreateOrthoVertsLS[i]);
                vMaxLS = Vector3D.Max(vMaxLS, m_tmpCreateOrthoVertsLS[i]);
            }
            Vector3D vMinWS = Vector3D.Transform(vMinLS, ref invLightMatrix);
            Vector3D vMaxWS = Vector3D.Transform(vMaxLS, ref invLightMatrix);

            // Create matrices:
            Vector3D vMinOffsetLS = -(vMaxLS - vMinLS) / 2;
            Vector3D vMaxOffsetLS = (vMaxLS - vMinLS) / 2;
            Vector3D vCenterWS    = (vMaxWS + vMinWS) / 2;

            MatrixD matrixLightPlacer = MatrixD.CreateLookAt(vCenterWS, vCenterWS - lightDir, lightUp);
            MatrixD matrixLightSizer  = MatrixD.CreateOrthographicOffCenter(vMinOffsetLS.X, vMaxOffsetLS.X,
                                                                            vMinOffsetLS.Y, vMaxOffsetLS.Y, vMaxOffsetLS.Z + zOffset, vMinOffsetLS.Z);

            return(matrixLightPlacer * matrixLightSizer);
        }
예제 #25
0
 /// <summary>
 ///   <para>Grows the Bounds to include the point.</para>
 /// </summary>
 /// <param name="point"></param>
 public void Encapsulate(Vector3D point)
 {
     this.SetMinMax(Vector3D.Min(this.min, point), Vector3D.Max(this.max, point));
 }
예제 #26
0
        public MyObjectBuilder_EntityBase BuildEntity()
        {
            // Realign both asteroids to a common grid, so voxels can be lined up.
            Vector3I roundedPosLeft  = SelectionLeft.WorldAABB.Min.RoundToVector3I();
            Vector3D offsetPosLeft   = SelectionLeft.WorldAABB.Min - (Vector3D)roundedPosLeft;   // Use for everything.
            Vector3I roundedPosRight = (SelectionRight.WorldAABB.Min - offsetPosLeft).RoundToVector3I();
            Vector3D offsetPosRight  = SelectionRight.WorldAABB.Min - (Vector3D)roundedPosRight; // Use for everything.

            // calculate smallest allowable size for contents of both.
            const int paddCells = 3;

            // Force a calculation of the ContentBounds, as multi select in the ListView doesn't necessarily make it happen, or make it happen fast enough.
            SelectionLeft.LoadDetailsSync();
            SelectionRight.LoadDetailsSync();

            var minLeft      = SelectionLeft.WorldAABB.Min + SelectionLeft.InflatedContentBounds.Min - offsetPosLeft;
            var minRight     = SelectionRight.WorldAABB.Min + SelectionRight.InflatedContentBounds.Min - offsetPosRight;
            var min          = Vector3D.Zero;
            var posOffset    = Vector3D.Zero;
            var asteroidSize = Vector3I.Zero;

            switch (VoxelMergeType)
            {
            case VoxelMergeType.UnionVolumeLeftToRight:
            case VoxelMergeType.UnionVolumeRightToLeft:
                min = Vector3D.Min(minLeft, minRight) - paddCells;
                var max = Vector3D.Max(SelectionLeft.WorldAABB.Min + SelectionLeft.InflatedContentBounds.Max - offsetPosLeft, SelectionRight.WorldAABB.Min + SelectionRight.InflatedContentBounds.Max - offsetPosRight) + paddCells;
                posOffset = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z);
                var size = (max - min).RoundToVector3I();
                asteroidSize = MyVoxelBuilder.CalcRequiredSize(size);
                break;

            case VoxelMergeType.UnionMaterialLeftToRight:
                min          = SelectionRight.WorldAABB.Min - offsetPosRight;
                posOffset    = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z);
                asteroidSize = SelectionRight.Size;
                break;

            case VoxelMergeType.UnionMaterialRightToLeft:
                min          = SelectionLeft.WorldAABB.Min - offsetPosLeft;
                posOffset    = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z);
                asteroidSize = SelectionLeft.Size;
                break;

            case VoxelMergeType.SubtractVolumeLeftFromRight:
                min          = SelectionRight.WorldAABB.Min - offsetPosRight;
                posOffset    = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z);
                asteroidSize = SelectionRight.Size;
                break;

            case VoxelMergeType.SubtractVolumeRightFromLeft:
                min          = SelectionLeft.WorldAABB.Min - offsetPosLeft;
                posOffset    = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z);
                asteroidSize = SelectionLeft.Size;
                break;
            }

            // Prepare new asteroid.
            var newAsteroid = new MyVoxelMap();

            newAsteroid.Create(asteroidSize, SpaceEngineersCore.Resources.GetDefaultMaterialIndex());
            if (string.IsNullOrEmpty(MergeFileName))
            {
                MergeFileName = "merge";
            }
            var filename = MainViewModel.CreateUniqueVoxelStorageName(MergeFileName);

            // merge.
            switch (VoxelMergeType)
            {
            case VoxelMergeType.UnionVolumeLeftToRight:
                MergeAsteroidVolumeInto(ref newAsteroid, min, SelectionRight, SelectionLeft, minRight, minLeft);
                break;

            case VoxelMergeType.UnionVolumeRightToLeft:
                MergeAsteroidVolumeInto(ref newAsteroid, min, SelectionLeft, SelectionRight, minLeft, minRight);
                break;

            case VoxelMergeType.UnionMaterialLeftToRight:
                MergeAsteroidMaterialFrom(ref newAsteroid, min, SelectionRight, SelectionLeft, minRight, minLeft);
                break;

            case VoxelMergeType.UnionMaterialRightToLeft:
                MergeAsteroidMaterialFrom(ref newAsteroid, min, SelectionLeft, SelectionRight, minLeft, minRight);
                break;

            case VoxelMergeType.SubtractVolumeLeftFromRight:
                SubtractAsteroidVolumeFrom(ref newAsteroid, min, SelectionRight, SelectionLeft, minRight, minLeft);
                break;

            case VoxelMergeType.SubtractVolumeRightFromLeft:
                SubtractAsteroidVolumeFrom(ref newAsteroid, min, SelectionLeft, SelectionRight, minLeft, minRight);
                break;
            }

            // Generate Entity
            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            newAsteroid.Save(tempfilename);
            SourceFile = tempfilename;

            var position = min + posOffset;
            var entity   = new MyObjectBuilder_VoxelMap(position, filename)
            {
                EntityId               = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID),
                PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                StorageName            = Path.GetFileNameWithoutExtension(filename),
                PositionAndOrientation = new MyPositionAndOrientation
                {
                    Position = position,
                    Forward  = Vector3.Forward,
                    Up       = Vector3.Up
                }
            };

            return(entity);
        }
            public OrientedBoundingBoxFaces(IMyTerminalBlock block)
            {
                Corners = new Vector3D[8];
                if (block == null)
                {
                    Position = new Vector3D();
                    localMin = new Vector3D();
                    localMax = new Vector3D();
                    return;
                }

                // Reconstruct bounding box vectors in world dimensions
                // For a 1x1x1 cube where Min = Max we still have the 1x1x1 cube as bounding box,
                // hence half that gets added in each direction.
                //		var localMin = new Vector3D(block.CubeGrid.Min) - new Vector3D(0.5, 0.5, 0.5);
                localMin  = new Vector3D(block.CubeGrid.Min) - new Vector3D(0.5, 0.5, 0.5);
                localMin *= block.CubeGrid.GridSize;
                //		var localMax = new Vector3D(block.CubeGrid.Max) + new Vector3D(0.5, 0.5, 0.5);
                localMax  = new Vector3D(block.CubeGrid.Max) + new Vector3D(0.5, 0.5, 0.5);
                localMax *= block.CubeGrid.GridSize;

                // The reference-blocks orientation.
                var blockOrient = block.WorldMatrix.GetOrientation();

                // Get the matrix that transforms from the cube grids orientation to the blocks orientation.
                var matrix = block.CubeGrid.WorldMatrix.GetOrientation() * MatrixD.Transpose(blockOrient);

                // Transform the cubegrid-relative min/max to block-relative min/max.
                Vector3D.TransformNormal(ref localMin, ref matrix, out localMin);
                Vector3D.TransformNormal(ref localMax, ref matrix, out localMax);

                // Form clean min/max again.
                var tmpMin = Vector3D.Min(localMin, localMax);

                localMax = Vector3D.Max(localMin, localMax);
                localMin = tmpMin;


                // Get the center for the offset correction into worldspace.
                var center = block.CubeGrid.GetPosition();

                Vector3D tmp2;
                Vector3D tmp3;

                tmp2 = localMin;
                Vector3D.TransformNormal(ref tmp2, ref blockOrient, out tmp2);
                tmp2 += center;

                tmp3 = localMax;
                Vector3D.TransformNormal(ref tmp3, ref blockOrient, out tmp3);
                tmp3 += center;

                BoundingBox bb = new BoundingBox(tmp2, tmp3);

                Position = bb.Center;


                // Iterate over all edges and get them into world space.
                Vector3D tmp;

                for (int i = 0; i < 8; i++)
                {
                    tmp.X = ((i & 1) == 0 ? localMin : localMax).X;
                    tmp.Y = ((i & 2) == 0 ? localMin : localMax).Y;
                    tmp.Z = ((i & 4) == 0 ? localMin : localMax).Z;
                    Vector3D.TransformNormal(ref tmp, ref blockOrient, out tmp);
                    tmp       += center;
                    Corners[i] = tmp;
                }
            }
예제 #28
0
        /// <summary>
        /// Performes a physics raycast
        /// It can be recursive (it calls CastDDA when it hits a grid).
        /// </summary>
        /// <param name="fromWorldPos"></param>
        /// <returns>Returns starting damage for current stack</returns>
        private MyRaycastDamageInfo CastPhysicsRay(Vector3D fromWorldPos)
        {
            Vector3D  pos       = Vector3D.Zero;
            IMyEntity hitEntity = null;

            var hitInfo = MyPhysics.CastRay(fromWorldPos, m_explosion.Center, MyPhysics.CollisionLayers.ExplosionRaycastLayer);

            if (hitInfo.HasValue)
            {
                hitEntity = (hitInfo.Value.HkHitInfo.Body.UserObject != null) ? ((MyPhysicsBody)hitInfo.Value.HkHitInfo.Body.UserObject).Entity : null;
                pos       = hitInfo.Value.Position;
            }
            Vector3D direction      = (m_explosion.Center - fromWorldPos);
            float    lengthToCenter = (float)direction.Normalize();

            var grid = (hitEntity as MyCubeGrid);

            if (grid == null)
            {
                MyCubeBlock hitBlock = hitEntity as MyCubeBlock;
                if (hitBlock != null)
                {
                    grid = hitBlock.CubeGrid;
                }
            }
            if (grid != null)
            {
                var localPos = Vector3D.Transform(pos, grid.PositionComp.WorldMatrixNormalizedInv) * grid.GridSizeR;
                var localDir = Vector3D.TransformNormal(direction, grid.PositionComp.WorldMatrixNormalizedInv) * 1 / 8f;
                //Try advancing the point to find the intersected block
                //If the block is a cube, this is necessary because the raycast will return a point somewhere outside the cube
                //If the block is not a full cube (slope, special block), the raycast can return inside the cube
                //It advances 4 times, each time one 8th the grid size
                for (int i = 0; i < 5; i++)
                {
                    Vector3I gridPos   = Vector3I.Round(localPos);
                    var      cubeBlock = grid.GetCubeBlock(gridPos);
                    if (cubeBlock != null)
                    {
                        if (m_castBlocks.Contains(cubeBlock))
                        {
                            //This shouldn't happen
                            //There is a corner case where the explosion position is inside the empty cell, but this should be handleded somewhere higher
                            System.Diagnostics.Debug.Fail("Raycast failed!");
                            DrawRay(fromWorldPos, pos, Color.Red);
                            return(new MyRaycastDamageInfo(0f, lengthToCenter));
                        }
                        else
                        {
                            //if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                            //    DrawRay(fromWorldPos, pos, Color.Blue);
                            return(CastDDA(cubeBlock));
                        }
                    }
                    localPos += localDir;
                }
                pos = Vector3D.Transform(localPos * grid.GridSize, grid.WorldMatrix);

                //We hit a grid but were unable to find the hit cube. Send another raycast
                //Ideally, we would want to get the cube in all cases, but it also has to be fast
                //We need to check if the explosion center is between the initial start position (fromWorldPos) and the new one (pos)

                Vector3D min = Vector3D.Min(fromWorldPos, pos);
                Vector3D max = Vector3D.Max(fromWorldPos, pos);

                BoundingBoxD boundingBox = new BoundingBoxD(min, max);
                if (boundingBox.Contains(m_explosion.Center) == ContainmentType.Contains)
                {
                    return(new MyRaycastDamageInfo(m_explosionDamage, lengthToCenter));
                }

                stackOverflowGuard++;
                if (stackOverflowGuard > MAX_PHYSICS_RECURSION_COUNT)
                {
                    System.Diagnostics.Debug.Fail("Potential stack overflow!");
                    if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                    {
                        DrawRay(fromWorldPos, pos, Color.Red);
                    }
                    return(new MyRaycastDamageInfo(0f, lengthToCenter));
                }
                else
                {
                    if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                    {
                        DrawRay(fromWorldPos, pos, Color.White);
                    }
                    return(CastPhysicsRay(pos));
                }
            }
            else if (hitInfo.HasValue)
            {
                //Something was hit, but it wasn't a grid. This needs to be handled somehow
                if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
                {
                    DrawRay(fromWorldPos, pos, Color.Violet);
                }
                return(new MyRaycastDamageInfo(0, lengthToCenter));
            }

            //Nothing was hit, so we can assume the there was nothing blocking the explosion
            //if (MyDebugDrawSettings.DEBUG_DRAW_EXPLOSION_HAVOK_RAYCASTS)
            //    DrawRay(fromWorldPos, pos, Color.Salmon);
            return(new MyRaycastDamageInfo(m_explosionDamage, lengthToCenter));
        }
예제 #29
0
 public BoundingBoxD GetBoundingBox() =>
 new BoundingBoxD(Vector3D.Min(this.From, this.To), Vector3D.Max(this.From, this.To));
예제 #30
0
 public BoundingBoxD Include(ref BoundingBoxD box)
 {
     this.Min = Vector3D.Min(this.Min, box.Min);
     this.Max = Vector3D.Max(this.Max, box.Max);
     return(this);
 }