Normalize() 공개 정적인 메소드

public static Normalize ( Vector3D, value ) : Vector3D,
value Vector3D,
리턴 Vector3D,
예제 #1
0
        public void Normalize()
        {
            Vector3D v, n1, n2;
            double magnitude;

            v = new Vector3D(3.0, 4.0, 0.0);
            n1 = v.Normalize();
            n2 = v.Normalize(out magnitude);
            Assert.AreEqual(1.0, n1.Magnitude, 1e-14);
            Assert.AreEqual(1.0, n2.Magnitude, 1e-14);
            Assert.AreEqual(5.0, magnitude, 1e-14);

            v = new Vector3D(3.0, 0.0, 4.0);
            n1 = v.Normalize();
            n2 = v.Normalize(out magnitude);
            Assert.AreEqual(1.0, n1.Magnitude, 1e-14);
            Assert.AreEqual(1.0, n2.Magnitude, 1e-14);
            Assert.AreEqual(5.0, magnitude, 1e-14);

            v = new Vector3D(0.0, 3.0, 4.0);
            n1 = v.Normalize();
            n2 = v.Normalize(out magnitude);
            Assert.AreEqual(1.0, n1.Magnitude, 1e-14);
            Assert.AreEqual(1.0, n2.Magnitude, 1e-14);
            Assert.AreEqual(5.0, magnitude, 1e-14);
        }
예제 #2
0
            public virtual void ReadFromXMLNode(XmlNode node)
            {
                try
                {
                    // Deal with model path, must be only one
                    LoadModelPathNode(node);

                    // Deal with the start position
                    XmlNode startPositionNode = node.SelectSingleNode(ModelXMLDefinition.StartPosition);
                    if (startPositionNode != null)
                    {
                        m_ptStartPoint = CPoint3DSerializer.ReadPoint(startPositionNode);
                    }

                    // Read the scaleDirection
                    XmlNode scaleDirectionNode = node.SelectSingleNode(ModelXMLDefinition.SacleDirection);
                    CPoint3D scaleDirection = CPoint3DSerializer.ReadPoint(scaleDirectionNode);

                    Vector3D vec = new Vector3D(scaleDirection.X, scaleDirection.Y, scaleDirection.Z);
                    if (vec.LengthSquared != 0)
                    {
                        vec.Normalize();
                        m_scaleDirection = vec;
                    }
                }
                catch (SystemException ex)
                {
                    string errMsg = ex.Message + "\n" + ex.StackTrace;
                    vtk.vtkOutputWindow.GetInstance().DisplayErrorText(errMsg);
                    throw;
                }
            }
예제 #3
0
        public void TestDecompose()
        {
            Vector3D axis = new Vector3D(.25f, .5f, 0.0f);
            axis.Normalize();

            Quaternion rot = new Quaternion(axis, TK.MathHelper.Pi);
            float x = 50.0f;
            float y = 100.0f;
            float z = -50.0f;

            float scale = 2.0f;

            Matrix4x4 m = Matrix4x4.FromScaling(new Vector3D(scale, scale, scale)) * Matrix4x4.FromAngleAxis(TK.MathHelper.Pi, axis) * Matrix4x4.FromTranslation(new Vector3D(x, y, z));

            Vector3D scaling1;
            Quaternion rotation1;
            Vector3D translation1;
            Assimp.Unmanaged.AssimpMethods.DecomposeMatrix(ref m, out scaling1, out rotation1, out translation1);

            Vector3D scaling2;
            Quaternion rotation2;
            Vector3D translation2;
            m.Decompose(out scaling2, out rotation2, out translation2);

            TestHelper.AssertEquals(scaling1.X, scaling1.Y, scaling1.Z, scaling2, "Testing decomposed scaling output");
            TestHelper.AssertEquals(rotation1.X, rotation1.Y, rotation1.Z, rotation1.W, rotation2, "Testing decomposed rotation output");
            TestHelper.AssertEquals(translation1.X, translation1.Y, translation1.Z, translation2, "Testing decomposed translation output");

            m = Matrix4x4.FromAngleAxis(TK.MathHelper.Pi, axis) * Matrix4x4.FromTranslation(new Vector3D(x, y, z));

            m.DecomposeNoScaling(out rotation2, out translation2);

            TestHelper.AssertEquals(rot.X, rot.Y, rot.Z, rot.W, rotation2, "Testing no scaling decomposed rotation output");
            TestHelper.AssertEquals(x, y, z, translation2, "Testing no scaling decomposed translation output");
        }
예제 #4
0
		public VolumeSliceArgs(int rows, int columns,
		                       float rowSpacing, float columnSpacing,
		                       Vector3D rowOrientationPatient,
		                       Vector3D columnOrientationPatient,
		                       float sliceThickness, int subsamples,
		                       VolumeInterpolationMode interpolation,
		                       VolumeProjectionMode projection)
		{
			Platform.CheckPositive(rows, "rows");
			Platform.CheckPositive(columns, "columns");
			Platform.CheckPositive(rowSpacing, "rowSpacing");
			Platform.CheckPositive(columnSpacing, "columnSpacing");
			Platform.CheckPositive(sliceThickness, "sliceThickness");
			Platform.CheckForNullReference(rowOrientationPatient, "rowOrientationPatient");
			Platform.CheckForNullReference(columnOrientationPatient, "columnOrientationPatient");

			_rows = rows;
			_columns = columns;
			_rowSpacing = rowSpacing;
			_columnSpacing = columnSpacing;
			_rowOrientationPatient = rowOrientationPatient.Normalize();
			_columnOrientationPatient = columnOrientationPatient.Normalize();
			_sliceThickness = sliceThickness;
			_subsamples = subsamples;
			_interpolation = interpolation;
			_projection = projection;
		}
예제 #5
0
 //  IMPORTANT: This struct must be initialized using this constructor, or by filling all four fields. It's because
 //  some code may need length or distance, and if they aren't calculated, we can have problems.
 public LineD(Vector3D from, Vector3D to)
 {
     From = from;
     To = to;
     Direction = to - from;
     Length = Direction.Normalize();
 }
예제 #6
0
 /// <summary>
 /// Offsets a vector by a hyperbolic distance.
 /// </summary>
 public static Vector3D Offset( Vector3D v, double hDist )
 {
     double mag = v.Abs();
     mag = DonHatch.h2eNorm( DonHatch.e2hNorm( mag ) + hDist );
     v.Normalize();
     v *= mag;
     return v;
 }
예제 #7
0
		public void TestNormalize()
		{
			Vector3D v1 = new Vector3D(2.2F, -6.1F, 7.4F);
			Assert.IsTrue(FloatComparer.AreEqual(v1.Magnitude, 9.8392072851F));

			Vector3D normalized = v1.Normalize();
			Assert.IsTrue(FloatComparer.AreEqual(normalized.Magnitude, 1.0F));
		}
예제 #8
0
        public IfcDirection(DatabaseIfc db, Vector3D v)
            : base(db)
        {
            UnitVector3D unit = v.Normalize();

            mDirectionRatioX = unit.X;
            mDirectionRatioY = unit.Y;
            mDirectionRatioZ = unit.Z;
        }
예제 #9
0
 public static OrthoNormalBasis MakeFromWV(Vector3D w, Vector3D v)
 {
     OrthoNormalBasis onb = new OrthoNormalBasis();
     w.Normalize();
     onb.w = w;
     onb.u = onb.w ^ v;
     onb.u.Normalize();
     onb.v = (onb.w ^ onb.u);
     return onb;
 }
예제 #10
0
        public static Matrix3D Orthogonalize(Vector3D u, Vector3D v)
        {
            Vector3D a = u.Normalize();

            Vector3D temp = v - (v.Dot(a)) * a;
            Vector3D b = temp.Normalize();
            Vector3D c = a.Cross(b).Normalize();

            Matrix3D e = new Matrix3D(a, b, c);

            return e;
        }
예제 #11
0
		private void UpdateTransformMatrix(Particle particle, BillboardMode mode)
		{
			lastFacingDirection = inverseView.Translation - particle.Position;
			lastCameraUp = inverseView.Up;
			AlignBillboardDirection(mode);
			lastCameraUp.Normalize();
			lastFacingDirection.Normalize();
			Vector3D right = Vector3D.Cross(lastCameraUp, lastFacingDirection);
			Vector3D up = Vector3D.Cross(lastFacingDirection, right);
			lastParticleTransform = Matrix.Identity;
			lastParticleTransform.Right = -right;
			lastParticleTransform.Up = lastFacingDirection;
			lastParticleTransform.Forward = up;
			lastParticleTransform *=
				Matrix.CreateRotationZYX(lastParticleTransform.Forward.X, lastParticleTransform.Forward.Y,
				lastParticleTransform.Forward.Z);
			lastParticleTransform.Translation = particle.Position;
		}
예제 #12
0
        public void NormalizeZeroVector()
        {
            Vector3D v = new Vector3D(0.0, 0.0, 0.0);
            
            Vector3D n1 = v.Normalize();
            Assert.IsNaN(n1.X);
            Assert.IsNaN(n1.Y);
            Assert.IsNaN(n1.Z);
            Assert.IsTrue(n1.IsUndefined);

            double magnitude;
            Vector3D n2 = v.Normalize(out magnitude);
            Assert.IsNaN(n2.X);
            Assert.IsNaN(n2.Y);
            Assert.IsNaN(n2.Z);
            Assert.IsTrue(n2.IsUndefined);
            Assert.AreEqual(0.0, magnitude);
        }
예제 #13
0
 public static OrthoNormalBasis MakeFromW(Vector3D w)
 {
     OrthoNormalBasis onb = new OrthoNormalBasis();
     w.Normalize();
     onb.w = w;
     if ((Math.Abs(onb.w.X) < Math.Abs(onb.w.Y)) && (Math.Abs(onb.w.X) < Math.Abs(onb.w.Z))) {
         onb.v.X = 0;
         onb.v.Y = onb.w.Z;
         onb.v.Z = -onb.w.Y;
     } else if (Math.Abs(onb.w.Y) < Math.Abs(onb.w.Z)) {
         onb.v.X = onb.w.Z;
         onb.v.Y = 0;
         onb.v.Z = -onb.w.X;
     } else {
         onb.v.X = onb.w.Y;
         onb.v.Y = -onb.w.X;
         onb.v.Z = 0;
     }
     onb.v.Normalize();
     onb.u = onb.v ^ onb.w;
     return onb;
 }
        public static Bitmap Render(Light_ lgt)
        {
            light = lgt;
            Vector3D direction = new Vector3D();
            Color color;

            for (int i = 0; i < xResolution; i++)
            {
                for (int j = 0; j < yResolution; j++)
                {
                    direction = vectorU * (i / (float)(xResolution - 1)) + vectorV * (j / (float)(yResolution - 1));
                    direction += topLeft;
                    direction -= observer;
                    direction.Normalize();

                    color = CalculateColor(observer, direction, 0);

                    image.SetPixel(i, j, color);
                }
            }

            return image;
        }
예제 #15
0
    public void DetermineVelocity(ZACommons commons, EventDriver eventDriver)
    {
        if (!Enabled) return;

        var shipControl = (ShipControlCommons)commons;

        var velocity = (shipControl.ReferencePoint - LastPosition) /
            ((double)SampleDelay / 60.0);

        TargetVector = -velocity;
        var speed = TargetVector.Normalize();
        if (speed > 0.1)
        {
            eventDriver.Schedule(FramesPerRun, Reorient);
        }
        else
        {
            var gyroControl = shipControl.GyroControl;
            gyroControl.Reset();
            gyroControl.EnableOverride(false);
            shipControl.ThrustControl.Enable(true);
        }
    }
예제 #16
0
            public void Update(MyDetectedEntityInfo target, Vector3D T, Vector3D PointerPos, Vector3D PointerDir)
            {
                if (!Launched)
                {
                    foreach (IMyThrust thr in thrusters)
                    {
                        thr.Enabled = true;
                        thr.ThrustOverridePercentage = 1;
                    }
                    Launched = true;
                }
                else
                {
                    counter++;
                    if (remcon.IsFunctional && (counter > VerticalDelay))
                    {
                        double   currentVelocity = remcon.GetShipVelocities().LinearVelocity.Length();
                        Vector3D targetvector    = new Vector3D();
                        if (LASER_GUIDED)
                        {
                            targetvector = ((remcon.GetPosition() - PointerPos).Dot(PointerDir) + 700) * PointerDir + PointerPos - remcon.GetPosition();
                        }
                        else
                        {
                            targetvector = FindInterceptVector(remcon.GetPosition(),
                                                               currentVelocity * INTERCEPT_COURSE,
                                                               T,
                                                               target.Velocity);
                        }

                        Vector3D trgNorm = Vector3D.Normalize(targetvector);

                        if ((target.Position - remcon.GetPosition()).Length() < WH_ARM_DIST)
                        {
                            if (currentVelocity - MyVelocity < -ACCEL_DET)
                            {
                                foreach (IMyWarhead wh in warheads)
                                {
                                    wh.Detonate();
                                }
                            }

                            MyVelocity = currentVelocity;
                        }

                        Vector3D velNorm          = Vector3D.Normalize(remcon.GetShipVelocities().LinearVelocity);
                        Vector3D CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm;
                        Vector3D G = remcon.GetNaturalGravity();

                        if (G.LengthSquared() == 0)
                        {
                            CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm;
                        }
                        else
                        {
                            if (JAVELIN)
                            {
                                //trgNorm = Vector3D.Normalize(Vector3D.Reflect(-G, trgNorm));
                                trgNorm = Vector3D.Normalize(G.Dot(trgNorm) * trgNorm * JAVELIN_CURVE - G);
                            }
                            CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm;
                            double A = 0;
                            foreach (IMyThrust thr in thrusters)
                            {
                                A += thr.MaxEffectiveThrust;
                            }
                            A /= remcon.CalculateShipMass().PhysicalMass;

                            Vector3D CorrectionNorm = Vector3D.Normalize(CorrectionVector);
                            //CorrectionVector = CorrectionNorm * A - G;
                            Vector3D gr = Vector3D.Reject(remcon.GetNaturalGravity(), CorrectionNorm);
                            CorrectionVector = CorrectionNorm * Math.Sqrt(A * A + gr.LengthSquared()) - gr;
                        }


                        Vector3D Axis = Vector3D.Normalize(CorrectionVector).Cross(remcon.WorldMatrix.Forward);
                        if (Axis.LengthSquared() < 0.1)
                        {
                            Axis += remcon.WorldMatrix.Backward * ROLL;
                        }
                        Axis *= GyroMult;
                        foreach (IMyGyro gyro in gyros)
                        {
                            gyro.Pitch = (float)Axis.Dot(gyro.WorldMatrix.Right);
                            gyro.Yaw   = (float)Axis.Dot(gyro.WorldMatrix.Up);
                            gyro.Roll  = (float)Axis.Dot(gyro.WorldMatrix.Backward);
                        }
                    }
                    else
                    {
                        foreach (IMyGyro gyro in gyros)
                        {
                            gyro.Pitch = 0;
                            gyro.Yaw   = 0;
                            gyro.Roll  = 0;
                        }
                    }
                }
            }
예제 #17
0
		private void SetPatientOrientation(Vector3D rowDirectionPatient, Vector3D columnDirectionPatient)
		{
			if (!CanRotate())
				return;

			if (rowDirectionPatient == null || columnDirectionPatient == null || !rowDirectionPatient.IsOrthogonalTo(columnDirectionPatient, (float) (5/180d*Math.PI)))
				return;

			var patientPresentation = SelectedPresentationImage as IPatientPresentationProvider;
			if (patientPresentation == null || !patientPresentation.PatientPresentation.IsValid)
				return;

			// Note the inverted column orientation vectors in both matrices - this is due to implicit Y axis inversion in the 3D transform
			columnDirectionPatient = -columnDirectionPatient;

			var currentRowOrientation = patientPresentation.PatientPresentation.OrientationX;
			var currentColumnOrientation = -patientPresentation.PatientPresentation.OrientationY;
			var currentOrientation = Matrix3D.FromRows(currentRowOrientation.Normalize(), currentColumnOrientation.Normalize(), currentRowOrientation.Cross(currentColumnOrientation).Normalize());
			var requestedOrientation = Matrix3D.FromRows(rowDirectionPatient.Normalize(), columnDirectionPatient.Normalize(), rowDirectionPatient.Cross(columnDirectionPatient).Normalize());

			var transform = _operation.GetOriginator(SelectedPresentationImage);

			// (because we're dealing with rotation matrices (i.e. orthogonal!), the Inverse is just Transpose)
			var rotation = requestedOrientation*currentOrientation.Transpose();
			transform.Rotation = rotation*transform.Rotation; // this rotation is cumulative upon current rotation, since IPatientPresentationProvider is based on *current* view

			SelectedPresentationImage.Draw();
		}
예제 #18
0
        private void ProcessDamage()
        {
            try
            {
                foreach (var planet in _planets)
                {
                    var sphere = new BoundingSphereD(planet.PositionComp.GetPosition(), 180000);

                    var topEntities = MyAPIGateway.Entities.GetTopMostEntitiesInSphere(ref sphere);
                    foreach (var entity in topEntities)
                    {
                        var grid = entity as IMyCubeGrid;
                        if (grid?.Physics != null)
                        {
                            if (grid.Closed || grid.MarkedForClose)
                            {
                                continue;
                            }

                            if (!IGNORE_ATMOSPHERE && !ACID_RAIN && IsEntityInsideGrid(grid))
                            {
                                //MyAPIGateway.Utilities.ShowMessage("GRID INSIDE", grid.DisplayName);
                                continue;
                            }

                            //if (ACID_RAIN && IsEntityCovered(grid, sphere.Center))
                            //{
                            //    //MyAPIGateway.Utilities.ShowMessage("GRID COVERED", grid.DisplayName);
                            //    continue;
                            //}

                            var blocks = new List <IMySlimBlock>();
                            grid.GetBlocks(blocks);

                            Vector3D offset = Vector3D.Zero;
                            if (ACID_RAIN)
                            {
                                Vector3D direction = grid.WorldVolume.Center - sphere.Center;
                                direction.Normalize();
                                offset = direction;
                            }

                            float damage = grid.GridSizeEnum == MyCubeSize.Small ? SMALL_SHIP_DAMAGE : LARGE_SHIP_DAMAGE;
                            for (int i = 0; i < Math.Max(1, blocks.Count * 0.3); i++)
                            {
                                IMySlimBlock block;
                                if (ACID_RAIN)
                                {
                                    block = GetRandomSkyFacingBlock(grid, blocks, offset, true);
                                }
                                else
                                {
                                    block = GetRandomExteriorBlock(grid, blocks);
                                }

                                if (block == null)
                                {
                                    continue;
                                }

                                if (!_damageEntities.ContainsKey(block))
                                {
                                    _damageEntities.Add(block, 0);
                                }

                                _damageEntities[block] += damage;

                                //blocks.Remove(block);
                                //QueueInvoke(() =>
                                //            {
                                //                if (block != null && !block.Closed())
                                //                    block.DoDamage(damage, _damageHash, true);
                                //            });
                            }

                            continue;
                        }

                        var floating = entity as IMyFloatingObject;
                        if (floating != null)
                        {
                            if (floating.Closed || floating.MarkedForClose)
                            {
                                continue;
                            }

                            if (!IGNORE_ATMOSPHERE && IsEntityInsideGrid(grid))
                            {
                                continue;
                            }

                            if (ACID_RAIN && IsEntityCovered(grid, sphere.Center))
                            {
                                continue;
                            }

                            //QueueInvoke(() => floating.DoDamage(SMALL_SHIP_DAMAGE, _damageHash, true));
                            if (!_damageEntities.ContainsKey(floating))
                            {
                                _damageEntities.Add(floating, 0);
                            }

                            _damageEntities[floating] += SMALL_SHIP_DAMAGE;
                            continue;
                        }
                    }
                }

                foreach (var entry in _damageEntities)
                {
                    _actionQueue.Enqueue(entry);
                }

                _damageEntities.Clear();
            }
            catch (Exception ex)
            {
                //MyAPIGateway.Utilities.ShowMessage("", ex.ToString());
                MyLog.Default.WriteLineAndConsole(ex.ToString());
            }
            finally
            {
                _actionsPerTick = _actionQueue.Count / UPDATE_RATE + 1;
                _processing     = false;
            }
        }
예제 #19
0
            } // Stop method

            // Supporting Methods ----------------------------------------------
            protected void GetChangeInDirection(Vector3D cur, Vector3D targ, out Vector3D axis, out double angle)
            {
                axis  = Vector3D.Cross(targ, cur); // get cross product (axis) between vectors
                angle = axis.Normalize();
                angle = Math.Atan2(angle, Math.Sqrt(Math.Max(0.0, 1.0 - angle * angle)));
            } //GetChangeInDirection()
예제 #20
0
        private Vector3D?FindSuitableJumpLocation(Vector3D desiredLocation)
        {
            BoundingBoxD shipBBox = GetAggregateBBox();

            // 1 Km distante to other objects to prevent spawning in bases
            shipBBox.Inflate(1000f);

            BoundingBoxD regionBBox = shipBBox.GetInflated(shipBBox.HalfExtents * 10);

            regionBBox.Translate(desiredLocation - regionBBox.Center);


            MyProceduralWorldGenerator.Static.OverlapAllPlanetSeedsInSphere(new BoundingSphereD(regionBBox.Center, regionBBox.HalfExtents.AbsMax()), m_objectsInRange);
            Vector3D currentSearchPosition = desiredLocation;

            foreach (var planet in m_objectsInRange)
            {
                if (planet.BoundingVolume.Contains(currentSearchPosition) != ContainmentType.Disjoint)
                {
                    Vector3D v = currentSearchPosition - planet.BoundingVolume.Center;
                    v.Normalize();
                    v *= planet.BoundingVolume.HalfExtents * 1.5;
                    currentSearchPosition = planet.BoundingVolume.Center + v;
                    break;
                }
            }
            m_objectsInRange.Clear();

            MyProceduralWorldGenerator.Static.OverlapAllAsteroidSeedsInSphere(new BoundingSphereD(regionBBox.Center, regionBBox.HalfExtents.AbsMax()), m_objectsInRange);
            foreach (var asteroid in m_objectsInRange)
            {
                m_obstaclesInRange.Add(asteroid.BoundingVolume);
            }
            m_objectsInRange.Clear();

            MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref regionBBox, m_entitiesInRange);

            // Inflate the obstacles so we only need to check the center of the ship for collisions
            foreach (var entity in m_entitiesInRange)
            {
                if (!(entity is MyPlanet))
                {
                    m_obstaclesInRange.Add(entity.PositionComp.WorldAABB.GetInflated(shipBBox.HalfExtents));
                }
            }

            int maxStepCount = 10;
            int stepCount    = 0;

            // When we collide with an obsticle, we add it here
            BoundingBoxD?aggregateCollidedObstacles = null;
            bool         obstructed = false;
            bool         found      = false;

            while (stepCount < maxStepCount)
            {
                stepCount++;
                obstructed = false;
                foreach (var obstacle in m_obstaclesInRange)
                {
                    var contains = obstacle.Contains(currentSearchPosition);
                    if (contains == ContainmentType.Contains ||
                        contains == ContainmentType.Intersects)
                    {
                        if (!aggregateCollidedObstacles.HasValue)
                        {
                            aggregateCollidedObstacles = obstacle;
                        }
                        aggregateCollidedObstacles = aggregateCollidedObstacles.Value.Include(obstacle);
                        aggregateCollidedObstacles = aggregateCollidedObstacles.Value.Inflate(1.0);
                        currentSearchPosition      = ClosestPointOnBounds(aggregateCollidedObstacles.Value, currentSearchPosition);
                        obstructed = true;
                        break;
                    }
                }

                if (!obstructed)
                {
                    // No obstacle found, return current search position
                    found = true;
                    break;
                }
            }

            m_obstaclesInRange.Clear();
            m_entitiesInRange.Clear();
            m_objectsInRange.Clear();

            if (found)
            {
                return(currentSearchPosition);
            }
            else
            {
                return(null);
            }
        }
예제 #21
0
        public void Update(int behaviorTicks)
        {
            m_stuckDetection.SetCurrentTicks(behaviorTicks);

            ProfilerShort.Begin("MyBotNavigation.Update");
            AssertIsValid();

            if (m_entity == null)
            {
                return;
            }

            ProfilerShort.Begin("UpdateMatrices");
            UpdateMatrices();
            ProfilerShort.End();

            m_gravityDirection = MyGravityProviderSystem.CalculateTotalGravityInPoint(m_entity.PositionComp.WorldMatrix.Translation);
            if (!Vector3.IsZero(m_gravityDirection, 0.01f))
            {
                m_gravityDirection = Vector3D.Normalize(m_gravityDirection);
            }

            if (MyPerGameSettings.NavmeshPresumesDownwardGravity)
            {
                m_upVector = Vector3.Up;
            }
            else
            {
                m_upVector = -m_gravityDirection;
            }

            if (!m_speed.IsValid())
            {
                m_forwardVector         = PositionAndOrientation.Forward;
                m_speed                 = 0.0f;
                m_rotationSpeedModifier = 1;
            }

            ProfilerShort.Begin("Steering update");
            foreach (var steering in m_steerings)
            {
                ProfilerShort.Begin(steering.GetName());
                steering.Update();
                ProfilerShort.End();
            }
            ProfilerShort.End();

            ProfilerShort.Begin("Aiming");
            m_aiming.Update();
            ProfilerShort.End();

            ProfilerShort.Begin("Steering accumulate correction");
            CorrectMovement(m_aiming.RotationHint);
            ProfilerShort.End();

            if (m_speed < 0.1f)// hotfix for flickering of animation from running left to running right
            {
                m_speed = 0;
            }

            ProfilerShort.Begin("MoveCharacter");
            MoveCharacter();
            ProfilerShort.End();

            AssertIsValid();
            ProfilerShort.End();
        }
예제 #22
0
        public override void UpdateAfterSimulation()
        {
            try
            {
                if (Range < RANGE_OFF_EXCLUSIVE)
                {
                    return;
                }

                bool applyForce = false;
                if (++skipTicks >= APPLY_FORCE_SKIP_TICKS)
                {
                    skipTicks  = 0;
                    applyForce = true;
                }

                if (!applyForce && MyAPIGateway.Utilities.IsDedicated)
                {
                    return;
                }

                var  conePos     = block.WorldMatrix.Translation + (block.WorldMatrix.Forward * -offset);
                bool inViewRange = false;

                if (!MyAPIGateway.Utilities.IsDedicated)
                {
                    var cameraMatrix = MyAPIGateway.Session.Camera.WorldMatrix;
                    inViewRange = Vector3D.DistanceSquared(cameraMatrix.Translation, conePos) <= MAX_VIEW_RANGE_SQ;

                    if (inViewRange && DrawCone)
                    {
                        DrawInfluenceCone(conePos);
                    }
                }

                if (!applyForce && !inViewRange)
                {
                    return;
                }

                if (floatingObjects.Count == 0)
                {
                    UpdateEmissive();
                    return;
                }

                var collectPos = block.WorldMatrix.Translation + (block.WorldMatrix.Forward * offset);
                var blockVel   = block.CubeGrid.Physics.GetVelocityAtPoint(collectPos);
                var rangeSq    = Range * Range;
                int pulling    = 0;

                for (int i = (floatingObjects.Count - 1); i >= 0; --i)
                {
                    var floatingObject = floatingObjects[i];

                    if (floatingObject.MarkedForClose || !floatingObject.Physics.Enabled)
                    {
                        continue; // it'll get removed by FindFloatingObjects()
                    }
                    var objPos = floatingObject.GetPosition();
                    var distSq = Vector3D.DistanceSquared(collectPos, objPos);

                    if (distSq > rangeSq)
                    {
                        continue; // too far from cone
                    }
                    var dirNormalized = Vector3D.Normalize(objPos - conePos);
                    var angle         = Math.Acos(MathHelper.Clamp(Vector3D.Dot(block.WorldMatrix.Forward, dirNormalized), -1, 1));

                    if (angle > coneAngle)
                    {
                        continue; // outside of the cone's FOV
                    }
                    if (applyForce)
                    {
                        var collectDir = Vector3D.Normalize(objPos - collectPos);

                        var vel   = floatingObject.Physics.LinearVelocity - blockVel;
                        var stop  = vel - (collectDir * collectDir.Dot(vel));
                        var force = -(stop + collectDir) * Math.Min(floatingObject.Physics.Mass * MASS_MUL, MAX_MASS) * StrengthMul;

                        force *= APPLY_FORCE_SKIP_TICKS; // multiplied by how many ticks were skipped

                        //MyTransparentGeometry.AddLineBillboard(Mod.MATERIAL_SQUARE, Color.Yellow, objPos, force, 1f, 0.1f);

                        floatingObject.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, force, null, null);
                    }

                    if (inViewRange)
                    {
                        var mul    = (float)Math.Sin(DateTime.UtcNow.TimeOfDay.TotalMilliseconds * 0.01);
                        var radius = floatingObject.Model.BoundingSphere.Radius * MinMaxPercent(0.75f, 1.25f, mul);

                        MyTransparentGeometry.AddPointBillboard(Mod.MATERIAL_DOT, Color.LightSkyBlue * MinMaxPercent(0.2f, 0.4f, mul), objPos, radius, 0);
                    }

                    pulling++;
                }

                if (applyForce)
                {
                    UpdateEmissive(pulling > 0);
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }
예제 #23
0
        /// <summary>
        /// Adds a point to the current trace with a specified color.
        /// </summary>
        /// <param name="point">The (X,Y,Z) location.</param>
        /// <param name="color">The color.</param>
        /// <param name="thickness">The line thickness (optional).</param>
        /// <seealso cref="AddPoint(double, double, double, Color, double)"/>
        public void AddPoint(Point3D point, Color color, double thickness = -1)
        {
            //if ((point - point0).LengthSquared < minDistanceSquared) return;  // less than min distance from last point

            if ((thickness == 0) && (marker != null))
            {
                marker.Origin   = point;
                coords.Position = new Point3D(point.X - labelOffset, point.Y - labelOffset, point.Z + labelOffset);
                coords.Text     = string.Format(coordinateFormat, point.X, point.Y, point.Z);
                return;
            }

            if (trace == null)
            {
                NewTrace(point, color, (thickness > 0) ? thickness : 1);
                return;
            }

            if (path.Color != color || (thickness > 0 && path.Thickness != thickness))
            {
                if (thickness <= 0)
                {
                    thickness = path.Thickness;
                }

                path           = new LinesVisual3D();
                path.Color     = color;
                path.Thickness = thickness;
                trace.Add(path);
                Children.Add(path);
            }

            // If line segments AB and BC have the same direction (small cross product) then remove point B.
            bool sameDir = false;
            var  delta   = new Vector3D(point.X - point0.X, point.Y - point0.Y, point.Z - point0.Z);

            delta.Normalize();  // use unit vectors (magnitude 1) for the cross product calculations
            if (path.Points.Count > 0)
            {
                double xp2 = Vector3D.CrossProduct(delta, delta0).LengthSquared;
                sameDir = (xp2 < 0.0005);  // approx 0.001 seems to be a reasonable threshold from logging xp2 values
                //if (!sameDir) Title = string.Format("xp2={0:F6}", xp2);
            }

            if (sameDir)  // extend the current line segment
            {
                path.Points[path.Points.Count - 1] = point;
                point0  = point;
                delta0 += delta;
            }
            else  // add a new line segment
            {
                path.Points.Add(point0);
                path.Points.Add(point);
                point0 = point;
                delta0 = delta;
            }

            if (marker != null)
            {
                marker.Origin   = point;
                coords.Position = new Point3D(point.X - labelOffset, point.Y - labelOffset, point.Z + labelOffset);
                coords.Text     = string.Format(coordinateFormat, point.X, point.Y, point.Z);
            }
        }
예제 #24
0
        internal bool SelectTarget(bool manualSelect = true)
        {
            var s  = _session;
            var ai = s.TrackingAi;

            if (!_cachedPointerPos)
            {
                InitPointerOffset(0.05);
            }
            if (!_cachedTargetPos)
            {
                InitTargetOffset();
            }
            var      cockPit = s.ActiveCockPit;
            Vector3D end;

            if (s.UiInput.InSpyCam)
            {
                var offetPosition = Vector3D.Transform(PointerOffset, s.ActiveCockPit.WorldMatrix);
                AimPosition  = s.ActiveCockPit.PositionComp.WorldAABB.Center;
                AimDirection = s.ActiveCockPit.WorldMatrix.Forward;
                end          = AimPosition + (AimDirection * ai.MaxTargetingRange);
            }
            else if (!s.UiInput.FirstPersonView)
            {
                var offetPosition = Vector3D.Transform(PointerOffset, s.CameraMatrix);
                AimPosition  = offetPosition;
                AimDirection = Vector3D.Normalize(AimPosition - s.CameraPos);
                end          = offetPosition + (AimDirection * ai.MaxTargetingRange);
            }
            else
            {
                if (!_session.UiInput.AltPressed)
                {
                    AimDirection = cockPit.PositionComp.WorldMatrix.Forward;
                    AimPosition  = cockPit.PositionComp.WorldAABB.Center;
                    end          = AimPosition + (AimDirection * s.TrackingAi.MaxTargetingRange);
                }
                else
                {
                    var offetPosition = Vector3D.Transform(PointerOffset, s.CameraMatrix);
                    AimPosition  = offetPosition;
                    AimDirection = Vector3D.Normalize(AimPosition - s.CameraPos);
                    end          = offetPosition + (AimDirection * ai.MaxTargetingRange);
                }
            }

            /*
             * var up = s.ActiveCockPit.WorldMatrix.Up;
             * var forward = s.ActiveCockPit.WorldMatrix.Forward;
             * var centerPos = s.ActiveCockPit.PositionComp.WorldAABB.Center;
             * var sphere = BoundingSphereD.CreateFromBoundingBox(s.ActiveCockPit.CubeGrid.GetPhysicalGroupAABB());
             * var dir = Vector3D.Normalize(centerPos - end);
             * var ray = new RayD(ref end, ref dir);
             * var dist = (ray.Intersects(sphere) ?? 0);
             * //Log.Line($"{dist} - {sphere.Center} - {sphere.Radius}");
             * var sphereEdge = new Vector3D(end + (dir * dist));
             * MatrixD.CreateWorld(ref sphereEdge, ref forward, ref up, out AimMatrix);
             */
            var foundTarget    = false;
            var rayOnlyHitSelf = false;
            var rayHitSelf     = false;

            MyEntity closestEnt = null;

            _session.Physics.CastRay(AimPosition, end, _hitInfo);

            for (int i = 0; i < _hitInfo.Count; i++)
            {
                var hit = _hitInfo[i];
                closestEnt = hit.HitEntity.GetTopMostParent() as MyEntity;

                var hitGrid = closestEnt as MyCubeGrid;

                if (hitGrid != null && hitGrid.IsSameConstructAs(ai.MyGrid))
                {
                    rayHitSelf     = true;
                    rayOnlyHitSelf = true;
                    continue;
                }

                if (rayOnlyHitSelf)
                {
                    rayOnlyHitSelf = false;
                }

                if (manualSelect)
                {
                    if (hitGrid == null || !ai.Targets.ContainsKey(hitGrid))
                    {
                        continue;
                    }

                    s.SetTarget(hitGrid, ai);
                    return(true);
                }

                foundTarget = true;
                ai.DummyTarget.Update(hit.Position, ai, closestEnt);
                break;
            }

            if (rayHitSelf)
            {
                ReticleOnSelfTick = s.Tick;
                ReticleAgeOnSelf++;
                if (rayOnlyHitSelf)
                {
                    ai.DummyTarget.Update(end, ai);
                }
            }
            else
            {
                ReticleAgeOnSelf = 0;
            }

            Vector3D hitPos;
            bool     foundOther = false;

            if (!foundTarget && RayCheckTargets(AimPosition, AimDirection, out closestEnt, out hitPos, out foundOther, !manualSelect))
            {
                foundTarget = true;
                if (manualSelect)
                {
                    s.SetTarget(closestEnt, ai);
                    return(true);
                }
                ai.DummyTarget.Update(hitPos, ai, closestEnt);
            }

            if (!manualSelect)
            {
                var activeColor = closestEnt != null && !ai.Targets.ContainsKey(closestEnt) || foundOther ? Color.DeepSkyBlue : Color.Red;
                _reticleColor = closestEnt != null && !(closestEnt is MyVoxelBase) ? activeColor : Color.White;
                if (!foundTarget)
                {
                    ai.DummyTarget.Update(end, ai);
                }
            }

            return(foundTarget || foundOther);
        }
예제 #25
0
        public override bool HandleRespawnRequest(bool joinGame, bool newIdentity, long medicalRoomId, string respawnShipId, MyPlayer.PlayerId playerId, Vector3D?spawnPosition, VRage.ObjectBuilders.SerializableDefinitionId?botDefinitionId)
        {
            MyPlayer player = Sync.Players.GetPlayerById(playerId);

            bool spawnAsNewPlayer = newIdentity || player == null;

            Debug.Assert(player == null || player.Identity != null, "Respawning player has no identity!");

            if (!MySessionComponentMissionTriggers.CanRespawn(playerId))
            {
                return(false);
            }

            Vector3D currentPosition = Vector3D.Zero;

            if (player != null && player.Character != null)
            {
                currentPosition = player.Character.PositionComp.GetPosition();
            }

            // Send postback message to a client that there was new identity created
            MyMultiplayer.RaiseStaticEvent(s => NewIdentityCreated_Response, playerId, joinGame, new EndpointId(playerId.SteamId));

            if (TryFindCryoChamberCharacter(player))
            {
                //Player found in chamber;
                return(true);
            }

            MyBotDefinition botDefinition = null;

            if (botDefinitionId != null)
            {
                MyDefinitionManager.Static.TryGetBotDefinition((MyDefinitionId)botDefinitionId, out botDefinition);
            }

            if (!spawnAsNewPlayer)
            {
                if (spawnPosition.HasValue)
                {
                    Vector3D gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(spawnPosition.Value);
                    if (Vector3D.IsZero(gravity))
                    {
                        gravity = Vector3D.Down;
                    }
                    else
                    {
                        gravity.Normalize();
                    }
                    Vector3D perpendicular;
                    gravity.CalculatePerpendicularVector(out perpendicular);
                    player.SpawnAt(MatrixD.CreateWorld(spawnPosition.Value, perpendicular, -gravity), Vector3.Zero, null, botDefinition, true);

                    return(true);
                }

                // Find respawn block to spawn at
                MyRespawnComponent foundRespawn = null;
                if (medicalRoomId == 0 || !MyFakes.SHOW_FACTIONS_GUI)
                {
                    List <MyRespawnComponent> respawns = null;
                    var nearestRespawn = GetNearestRespawn(currentPosition, out respawns, MySession.Static.CreativeMode ? (long?)null : player.Identity.IdentityId);
                    if (joinGame && respawns.Count > 0)
                    {
                        foundRespawn = respawns[MyRandom.Instance.Next(0, respawns.Count)];
                    }
                }
                else
                {
                    foundRespawn = FindRespawnById(medicalRoomId, player);
                    if (foundRespawn == null)
                    {
                        return(false);
                    }
                }

                // If spawning in respawn block fails, we will spawn as a new player
                if (foundRespawn != null)
                {
                    SpawnInRespawn(player, foundRespawn, botDefinition);
                }
                else
                {
                    spawnAsNewPlayer = true;
                }
            }

            if (spawnAsNewPlayer)
            {
                bool resetIdentity = MySession.Static.Settings.PermanentDeath.Value;
                if (player == null)
                {
                    var identity = Sync.Players.CreateNewIdentity(player.DisplayName);
                    player        = Sync.Players.CreateNewPlayer(identity, playerId, player.DisplayName);
                    resetIdentity = false;
                }

                if (MySession.Static.CreativeMode)
                {
                    Vector3D?correctedPos = MyEntities.FindFreePlace(currentPosition, 2, 200);
                    if (correctedPos.HasValue)
                    {
                        currentPosition = correctedPos.Value;
                    }
                    player.SpawnAt(Matrix.CreateTranslation(currentPosition), Vector3.Zero, null, botDefinition);
                }
                else
                {
                    SpawnAsNewPlayer(player, currentPosition, respawnShipId, resetIdentity, botDefinition);
                }
            }

            return(true);
        }
예제 #26
0
        public override void CreateVertices()
        {
            my_VertexCount = (my_Steps + 1) * (my_Slices + 1);
            Matrix3D rm = CalculateRotationMatrix(InitialRotationAxis.X, InitialRotationAxis.Y, InitialRotationAxis.Z);

            my_Vertices  = new Vector3D[my_VertexCount];
            centerPoints = new Vector3D[my_Steps + 1];
            int                 count = 0;
            double              beta;
            double              theta;
            double              phi;
            double              r;
            double              x;
            double              y;
            double              z;
            Vector3D            V;
            Vector3D            V1 = new Vector3D();
            AxisAngleRotation3D Aar;
            RotateTransform3D   rotT;

            //Calculate the knot center coordinates
            for (int I = 0; I <= my_Steps; I++)
            {
                beta            = I * Math.PI / my_Steps;
                r               = my_Size * (a1 * Math.Sin(a2 * beta + a3));
                theta           = b1 * beta;
                phi             = c1 * Math.Sin(c2 * beta);
                x               = r * Math.Cos(phi) * Math.Cos(theta);
                y               = r * Math.Cos(phi) * Math.Sin(theta);
                z               = r * Math.Sin(phi);
                centerPoints[I] = new Vector3D(x, y, z);
            }
            //Calculate the vertex positions at my_Diameter / 2 around the knot center coordinates
            for (int I = 0; I < my_Steps; I++)
            {
                V    = centerPoints[I + 1] - centerPoints[I];
                Aar  = new AxisAngleRotation3D(V, 360.0 / my_Slices);
                rotT = new RotateTransform3D(Aar);
                if (V.X != 0 | V.Z != 0)
                {
                    V1 = Vector3D.CrossProduct(V, new Vector3D(0, 1, 0));
                }
                else if (V.Y != 0)
                {
                    V1 = Vector3D.CrossProduct(V, new Vector3D(0, 0, 1));
                }
                V1.Normalize();
                V1 = (my_Diameter / 2.0) * V1;
                for (int J = 0; J <= my_Slices; J++)
                {
                    my_Vertices[count] = V1 + centerPoints[I];
                    V1     = rotT.Transform(V1);
                    count += 1;
                }
            }
            //Add vertices around the first knot coordinate again to close the knot.
            V    = centerPoints[1] - centerPoints[0];
            Aar  = new AxisAngleRotation3D(V, 360.0 / my_Slices);
            rotT = new RotateTransform3D(Aar);
            if (V.X != 0 | V.Z != 0)
            {
                V1 = Vector3D.CrossProduct(V, new Vector3D(0, 1, 0));
            }
            else if (V.Y != 0)
            {
                V1 = Vector3D.CrossProduct(V, new Vector3D(0, 0, 1));
            }
            V1.Normalize();
            V1 = (my_Diameter / 2.0) * V1;
            for (int J = 0; J <= my_Slices; J++)
            {
                my_Vertices[count] = V1 + centerPoints[0];
                V1     = rotT.Transform(V1);
                count += 1;
            }
            //Apply the initial rotation
            for (int I = 0; I < my_VertexCount; I++)
            {
                my_Vertices[I] = rm.Transform(my_Vertices[I]);
            }
        }
예제 #27
0
        private void ProcessInput(double dTime)
        {
            if (Keyboard.IsKeyDown(Key.Right))
            {
                this.camYaw -= keyAngleSpeed * dTime;
            }
            if (Keyboard.IsKeyDown(Key.Left))
            {
                this.camYaw += keyAngleSpeed * dTime;
            }
            if (Keyboard.IsKeyDown(Key.Up))
            {
                this.camPitch += keyAngleSpeed * dTime;
            }
            if (Keyboard.IsKeyDown(Key.Down))
            {
                this.camPitch -= keyAngleSpeed * dTime;
            }

            var diff = ScreenMouse.Position - viewCenterPt;

            ScreenMouse.Position = viewCenterPt;

            this.camPitch -= diff.Y * mouseAngleSPeed * dTime;
            if (this.camPitch > Math.PI / 2 - 0.01)
            {
                this.camPitch = Math.PI / 2 - 0.01;
            }
            if (this.camPitch < -Math.PI / 2 + 0.01)
            {
                this.camPitch = -Math.PI / 2 + 0.01;
            }
            this.camYaw -= diff.X * mouseAngleSPeed * dTime;

            Vector3D vMove = new Vector3D(0, 0, 0);

            if (Keyboard.IsKeyDown(Key.D))
            {
                vMove.X += 1;
            }
            if (Keyboard.IsKeyDown(Key.A))
            {
                vMove.X -= 1;
            }
            if (Keyboard.IsKeyDown(Key.W))
            {
                vMove.Y += 1;
            }
            if (Keyboard.IsKeyDown(Key.S))
            {
                vMove.Y -= 1;
            }
            if (vMove.Length != 0)
            {
                vMove.Normalize();
                vMove = vMove * moveSpeed * dTime;
                PerspectiveCamera cam = this.view.Camera as PerspectiveCamera;
                var vLook             = cam.LookDirection;
                var vUp    = cam.UpDirection;
                var vRight = Vector3D.CrossProduct(vLook, vUp);
                vRight.Normalize();
                var vMove2 = vLook * vMove.Y + vRight * vMove.X;
                this.camPos += vMove2;
            }
        }
예제 #28
0
        /// <summary>
        /// Hull making.
        /// </summary>
        /// <remarks>Based/Completely from http://www.xbdev.net/physics/MinkowskiDifference/index.php
        /// I don't (100%) see why this should always work.
        /// </remarks>
        /// <param name="triangleList"></param>
        /// <param name="generationThreshold"></param>
        public virtual void MakeHull(ref List <Vector3D> triangleList, int generationThreshold)
        {
            double distanceThreshold = 0.0f;

            if (generationThreshold < 0)
            {
                generationThreshold = 4;
            }

            Stack <ClipTriangle> activeTriList = new Stack <ClipTriangle>();

            Vector3D[] v = new Vector3D[] // 6 Array
            {
                new Vector3D(-1, 0, 0),
                new Vector3D(1, 0, 0),

                new Vector3D(0, -1, 0),
                new Vector3D(0, 1, 0),

                new Vector3D(0, 0, -1),
                new Vector3D(0, 0, 1),
            };

            int[,] kTriangleVerts = new int[8, 3] // 8 x 3 Array
            {
                { 5, 1, 3 },
                { 4, 3, 1 },
                { 3, 4, 0 },
                { 0, 5, 3 },

                { 5, 2, 1 },
                { 4, 1, 2 },
                { 2, 0, 4 },
                { 0, 2, 5 }
            };

            for (int i = 0; i < 8; i++)
            {
                ClipTriangle tri = new ClipTriangle();
                tri.n1         = v[kTriangleVerts[i, 0]];
                tri.n2         = v[kTriangleVerts[i, 1]];
                tri.n3         = v[kTriangleVerts[i, 2]];
                tri.generation = 0;
                activeTriList.Push(tri);
            }

            List <Vector3D> pointSet = new List <Vector3D>();

            // surfaceTriList
            while (activeTriList.Count > 0)
            {
                ClipTriangle tri = activeTriList.Pop();

                Vector3D p1; SupportMapping(ref tri.n1, out p1);
                Vector3D p2; SupportMapping(ref tri.n2, out p2);
                Vector3D p3; SupportMapping(ref tri.n3, out p3);

                double d1 = (p2 - p1).LengthSquared();
                double d2 = (p3 - p2).LengthSquared();
                double d3 = (p1 - p3).LengthSquared();

                if (Math.Max(Math.Max(d1, d2), d3) > distanceThreshold && tri.generation < generationThreshold)
                {
                    ClipTriangle tri1 = new ClipTriangle();
                    ClipTriangle tri2 = new ClipTriangle();
                    ClipTriangle tri3 = new ClipTriangle();
                    ClipTriangle tri4 = new ClipTriangle();

                    tri1.generation = tri.generation + 1;
                    tri2.generation = tri.generation + 1;
                    tri3.generation = tri.generation + 1;
                    tri4.generation = tri.generation + 1;

                    tri1.n1 = tri.n1;
                    tri2.n2 = tri.n2;
                    tri3.n3 = tri.n3;

                    Vector3D n = 0.5f * (tri.n1 + tri.n2);
                    n.Normalize();

                    tri1.n2 = n;
                    tri2.n1 = n;
                    tri4.n3 = n;

                    n = 0.5f * (tri.n2 + tri.n3);
                    n.Normalize();

                    tri2.n3 = n;
                    tri3.n2 = n;
                    tri4.n1 = n;

                    n = 0.5f * (tri.n3 + tri.n1);
                    n.Normalize();

                    tri1.n3 = n;
                    tri3.n1 = n;
                    tri4.n2 = n;

                    activeTriList.Push(tri1);
                    activeTriList.Push(tri2);
                    activeTriList.Push(tri3);
                    activeTriList.Push(tri4);
                }
                else
                {
                    //if (((p3 - p1) % (p2 - p1)).LengthSquared() > MathHelper.EPSILON)
                    if (Vector3D.Cross(p3 - p1, p2 - p1).LengthSquared() > MathHelper.EPSILON)

                    {
                        triangleList.Add(p1);
                        triangleList.Add(p2);
                        triangleList.Add(p3);
                    }
                }
            }
        }
예제 #29
0
            public void Lock(bool TryLock = false, double InitialRange = 10000)
            {
                int initCamIndex = CamIndex++;

                if (CamIndex >= CamArray.Count)
                {
                    CamIndex = 0;
                }
                MyDetectedEntityInfo lastDetectedInfo;
                bool CanScan = true;

                // найдем первую после использованной в последний раз камеру, которая способна кастануть лучик на заданную дистанцию.
                if (CurrentTarget.EntityId == 0)
                {
                    TargetDistance = InitialRange;
                }

                while ((CamArray[CamIndex] as IMyCameraBlock)?.CanScan(TargetDistance) == false)
                {
                    CamIndex++;
                    if (CamIndex >= CamArray.Count)
                    {
                        CamIndex = 0;
                    }
                    if (CamIndex == initCamIndex)
                    {
                        CanScan = false;
                        break;
                    }
                }
                //если такая камера в массиве найдена - кастуем ей луч.
                if (CanScan)
                {
                    //в случае, если мы осуществляем первоначальный захват цели, кастуем луч вперед
                    if ((TryLock) && (CurrentTarget.IsEmpty()))
                    {
                        lastDetectedInfo = (CamArray[CamIndex] as IMyCameraBlock).Raycast(InitialRange, 0, 0);
                        if ((!lastDetectedInfo.IsEmpty()) && (lastDetectedInfo.Relationship != MyRelationsBetweenPlayerAndBlock.Owner))
                        {
                            Locked = true;
                            Vector3D deep_point = lastDetectedInfo.HitPosition.Value +
                                                  Vector3D.Normalize(lastDetectedInfo.HitPosition.Value - CamArray[CamIndex].GetPosition()) * LOCK_POINT_DEPTH;
                            O = WorldToGrid(lastDetectedInfo.HitPosition.Value, lastDetectedInfo.Position, lastDetectedInfo.Orientation);
                        }
                    }
                    else                     //иначе - до координат предполагаемого нахождения цели.
                    {
                        lastDetectedInfo = (CamArray[CamIndex] as IMyCameraBlock).Raycast(correctedTargetLocation);
                    }
                    //если что-то нашли лучем, то захват обновлен
                    if ((!lastDetectedInfo.IsEmpty()) && (lastDetectedInfo.Relationship != MyRelationsBetweenPlayerAndBlock.Owner))
                    {
                        Locked        = true;
                        CurrentTarget = lastDetectedInfo;
                        LastLockTick  = Tick;
                        IMyTextPanel LCD = gts.GetBlockWithName("LCD") as IMyTextPanel;
                        TicksPassed = 0;
                    }
                    else                     //иначе - захват потерян
                    {
                        Locked = false;
                        //CurrentTarget = lastDetectedInfo;
                    }
                }
            }
예제 #30
0
        public void ProcessAction(TriggerProfile trigger, ActionProfile actions, long attackerEntityId = 0, long detectedEntity = 0, Command command = null)
        {
            Logger.MsgDebug(trigger.ProfileSubtypeId + " Attempting To Execute Action Profile " + actions.ProfileSubtypeId, DebugTypeEnum.Action);

            if (actions.Chance < 100)
            {
                var roll = Utilities.Rnd.Next(0, 101);

                if (roll > actions.Chance)
                {
                    Logger.MsgDebug(actions.ProfileSubtypeId + ": Did Not Pass Chance Check", DebugTypeEnum.Action);
                    return;
                }
            }

            Logger.MsgDebug(actions.ProfileSubtypeId + ": Performing Eligible Actions", DebugTypeEnum.Action);

            //ChatBroadcast
            if (actions.UseChatBroadcast == true)
            {
                foreach (var chatData in actions.ChatData)
                {
                    Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Chat Broadcast", DebugTypeEnum.Action);
                    _broadcast.BroadcastRequest(chatData);
                }
            }

            //BarrellRoll
            if (actions.BarrelRoll == true)
            {
                _behavior.AutoPilot.ActivateBarrelRoll();
            }

            //Ramming
            if (actions.Ramming == true)
            {
                _behavior.AutoPilot.ActivateRamming();
            }

            //Strafe - Implement Post Release
            if (actions.Strafe == true)
            {
                //_autopilot.ChangeAutoPilotMode(AutoPilotMode.Strafe);
            }

            //ChangeAutopilotSpeed
            if (actions.ChangeAutopilotSpeed == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Changing AutoPilot Speed To: " + actions.NewAutopilotSpeed.ToString(), DebugTypeEnum.Action);
                _autopilot.Data.IdealMaxSpeed = actions.NewAutopilotSpeed;
                var blockList = TargetHelper.GetAllBlocks(RemoteControl.SlimBlock.CubeGrid);

                foreach (var block in blockList.Where(x => x.FatBlock != null))
                {
                    var tBlock = block.FatBlock as IMyRemoteControl;

                    if (tBlock != null)
                    {
                        tBlock.SpeedLimit = actions.NewAutopilotSpeed;
                    }
                }
            }

            //SpawnReinforcements
            if (actions.SpawnEncounter == true)
            {
                foreach (var spawner in actions.Spawner)
                {
                    if (spawner.UseSpawn)
                    {
                        Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Spawn", DebugTypeEnum.Spawn);
                        if (spawner.IsReadyToSpawn())
                        {
                            //Logger.AddMsg("Do Spawn", true);
                            spawner.AssignInitialMatrix(RemoteControl.WorldMatrix);
                            spawner.CurrentFactionTag = spawner.ForceSameFactionOwnership && !string.IsNullOrWhiteSpace(_owner.Faction?.Tag) ? _owner.Faction.Tag : "";
                            SpawnHelper.SpawnRequest(spawner);
                        }
                    }
                }
            }
            else
            {
            }

            //SelfDestruct
            if (actions.SelfDestruct == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting SelfDestruct", DebugTypeEnum.Action);
                var blockList     = TargetHelper.GetAllBlocks(RemoteControl.SlimBlock.CubeGrid);
                int totalWarheads = 0;

                foreach (var block in blockList.Where(x => x.FatBlock != null))
                {
                    var tBlock = block.FatBlock as IMyWarhead;

                    if (tBlock != null)
                    {
                        if (!actions.StaggerWarheadDetonation)
                        {
                            tBlock.IsArmed        = true;
                            tBlock.DetonationTime = 0;
                            tBlock.Detonate();
                            totalWarheads++;
                        }
                        else
                        {
                            totalWarheads++;
                            tBlock.IsArmed        = true;
                            tBlock.DetonationTime = (totalWarheads * actions.SelfDestructTimeBetweenBlasts) + actions.SelfDestructTimerPadding;
                            tBlock.StartCountdown();
                        }
                    }
                }

                //Logger.AddMsg("TotalBlocks:  " + blockList.Count.ToString(), true);
                //Logger.AddMsg("TotalWarheads: " + totalWarheads.ToString(), true);

                //TODO: Shield EMP
            }

            //Retreat
            if (actions.Retreat)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Retreat", DebugTypeEnum.Action);
                _despawn.Retreat();
            }

            //ForceDespawn
            if (actions.ForceDespawn)
            {
                _despawn.DespawnGrid();
            }

            //TerminateBehavior
            if (actions.TerminateBehavior)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Termination Of Behavior", DebugTypeEnum.Action);
                _autopilot.ActivateAutoPilot(Vector3D.Zero, NewAutoPilotMode.None);
                _behavior.BehaviorTerminated = true;
            }

            //BroadcastGenericCommand
            if (actions.BroadcastGenericCommand == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Broadcast of Generic Command", DebugTypeEnum.Action);

                double sendRadius = 0;

                if (actions.SendCommandWithoutAntenna)
                {
                    sendRadius = actions.SendCommandWithoutAntennaRadius;
                }
                else
                {
                    var antenna = _behavior.Grid.GetAntennaWithHighestRange();

                    if (antenna != null)
                    {
                        sendRadius = antenna.Radius;
                    }
                }

                if (sendRadius != 0)
                {
                    var newCommand = new Command();
                    newCommand.CommandCode   = actions.BroadcastSendCode;
                    newCommand.RemoteControl = RemoteControl;
                    newCommand.Radius        = sendRadius;
                    CommandHelper.CommandTrigger?.Invoke(newCommand);
                }
            }

            //BroadcastDamagerTarget
            if (actions.BroadcastDamagerTarget == true && detectedEntity != 0)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Broadcast of Damager", DebugTypeEnum.Action);

                double sendRadius = 0;

                if (actions.SendCommandWithoutAntenna)
                {
                    sendRadius = actions.SendCommandWithoutAntennaRadius;
                }
                else
                {
                    var antenna = _behavior.Grid.GetAntennaWithHighestRange();

                    if (antenna != null)
                    {
                        sendRadius = antenna.Radius;
                    }
                }

                if (sendRadius != 0)
                {
                    var newCommand = new Command();
                    newCommand.CommandCode    = actions.BroadcastSendCode;
                    newCommand.RemoteControl  = RemoteControl;
                    newCommand.Radius         = sendRadius;
                    newCommand.TargetEntityId = detectedEntity;
                    CommandHelper.CommandTrigger?.Invoke(newCommand);
                }
            }

            //SwitchToReceivedTarget
            if (actions.SwitchToReceivedTarget == true && (command != null || detectedEntity != 0))
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Switch to Received Target Data", DebugTypeEnum.Action);
                long switchToId = 0;

                if (command != null && command.TargetEntityId != 0)
                {
                    switchToId = command.TargetEntityId;
                }
                else if (detectedEntity != 0)
                {
                    switchToId = detectedEntity;
                }

                IMyEntity tempEntity = null;

                if (MyAPIGateway.Entities.TryGetEntityById(switchToId, out tempEntity))
                {
                    _autopilot.Targeting.ForceTargetEntityId = switchToId;
                    _autopilot.Targeting.ForceTargetEntity   = tempEntity;
                    _autopilot.Targeting.ForceRefresh        = true;
                }
            }

            //SwitchToDamagerTarget
            if (actions.SwitchToDamagerTarget == true && detectedEntity != 0)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Switch to Damager Target Data", DebugTypeEnum.Action);
                _autopilot.Targeting.ForceTargetEntityId = detectedEntity;
                _autopilot.Targeting.ForceRefresh        = true;
            }

            //SwitchToBehavior
            if (actions.SwitchToBehavior == true)
            {
                _behavior.ChangeBehavior(actions.NewBehavior, actions.PreserveSettingsOnBehaviorSwitch, actions.PreserveTriggersOnBehaviorSwitch, actions.PreserveTargetDataOnBehaviorSwitch);
            }

            //ChangePlayerCredits
            if (actions.ChangePlayerCredits && command != null && command.Type == CommandType.PlayerChat)
            {
                if (command.PlayerIdentity != 0)
                {
                    var playerList = new List <IMyPlayer>();
                    MyAPIGateway.Players.GetPlayers(playerList, p => p.IdentityId == command.PlayerIdentity);

                    foreach (var player in playerList)
                    {
                        long credits = 0;
                        player.TryGetBalanceInfo(out credits);

                        if (actions.ChangePlayerCreditsAmount > 0)
                        {
                            player.RequestChangeBalance(actions.ChangePlayerCreditsAmount);
                            PaymentSuccessTriggered = true;
                        }
                        else
                        {
                            if (actions.ChangePlayerCreditsAmount > credits)
                            {
                                PaymentFailureTriggered = true;
                            }
                            else
                            {
                                player.RequestChangeBalance(actions.ChangePlayerCreditsAmount);
                                PaymentSuccessTriggered = true;
                            }
                        }
                    }
                }
            }

            //ChangeNpcFactionCredits
            if (actions.ChangeNpcFactionCredits)
            {
                IMyFaction faction = null;

                if (string.IsNullOrWhiteSpace(actions.ChangeNpcFactionCreditsTag))
                {
                    faction = _behavior.Owner.Faction;
                }
                else
                {
                    faction = MyAPIGateway.Session.Factions.TryGetFactionByTag(actions.ChangeNpcFactionCreditsTag);
                }

                if (faction != null)
                {
                    long credits = 0;
                    faction.TryGetBalanceInfo(out credits);

                    if (actions.ChangePlayerCreditsAmount > 0)
                    {
                        faction.RequestChangeBalance(actions.ChangePlayerCreditsAmount);
                        PaymentSuccessTriggered = true;
                    }
                    else
                    {
                        if (actions.ChangePlayerCreditsAmount > credits)
                        {
                            PaymentFailureTriggered = true;
                        }
                        else
                        {
                            faction.RequestChangeBalance(actions.ChangePlayerCreditsAmount);
                            PaymentSuccessTriggered = true;
                        }
                    }
                }
            }

            //RefreshTarget
            if (actions.RefreshTarget == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Target Refresh", DebugTypeEnum.Action);
                _autopilot.Targeting.ForceRefresh = true;
            }

            //ChangeTargetProfile
            if (actions.ChangeTargetProfile == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Target Profile Change", DebugTypeEnum.Action);
                _autopilot.Targeting.UseNewTargetProfile  = true;
                _autopilot.Targeting.NewTargetProfileName = actions.NewTargetProfileId;
            }

            //ChangeReputationWithPlayers
            if (actions.ChangeReputationWithPlayers == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Reputation Change With Players In Radius", DebugTypeEnum.Action);
                OwnershipHelper.ChangeReputationWithPlayersInRadius(RemoteControl, actions.ReputationChangeRadius, actions.ReputationChangeAmount, actions.ReputationChangeFactions, actions.ReputationChangesForAllRadiusPlayerFactionMembers);
            }

            //ChangeAttackerReputation
            if (actions.ChangeAttackerReputation == true && detectedEntity != 0)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Reputation Change for Attacker", DebugTypeEnum.Action);
                OwnershipHelper.ChangeDamageOwnerReputation(actions.ChangeAttackerReputationFaction, detectedEntity, actions.ChangeAttackerReputationAmount, actions.ReputationChangesForAllAttackPlayerFactionMembers);
            }


            //TriggerTimerBlock
            if (actions.TriggerTimerBlocks == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Trigger of Timer Blocks", DebugTypeEnum.Action);
                var blockList = BlockHelper.GetBlocksWithNames(RemoteControl.SlimBlock.CubeGrid, actions.TimerBlockNames);

                foreach (var block in blockList)
                {
                    var tBlock = block as IMyTimerBlock;

                    if (tBlock != null)
                    {
                        tBlock.Trigger();
                    }
                }
            }

            //ChangeBlockNames
            if (actions.ChangeBlockNames)
            {
                _behavior.Grid.RenameBlocks(actions.ChangeBlockNamesFrom, actions.ChangeBlockNamesTo, actions.ProfileSubtypeId);
            }

            //ChangeAntennaRanges
            if (actions.ChangeAntennaRanges)
            {
                _behavior.Grid.SetGridAntennaRanges(actions.AntennaNamesForRangeChange, actions.AntennaRangeChangeType, actions.AntennaRangeChangeAmount);
            }

            //ChangeAntennaOwnership
            if (actions.ChangeAntennaOwnership == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Antenna Ownership Change", DebugTypeEnum.Action);
                OwnershipHelper.ChangeAntennaBlockOwnership(AntennaList, actions.AntennaFactionOwner);
            }

            //CreateKnownPlayerArea
            if (actions.CreateKnownPlayerArea == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Creation of Known Player Area in MES", DebugTypeEnum.Action);
                MESApi.AddKnownPlayerLocation(RemoteControl.GetPosition(), _owner.Faction?.Tag, actions.KnownPlayerAreaRadius, actions.KnownPlayerAreaTimer, actions.KnownPlayerAreaMaxSpawns, actions.KnownPlayerAreaMinThreatForAvoidingAbandonment);
            }

            //RemoveKnownPlayerLocation
            if (actions.RemoveKnownPlayerArea == true)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Removal of Known Player Area in MES", DebugTypeEnum.Action);
                MESApi.RemoveKnownPlayerLocation(RemoteControl.GetPosition(), _owner.Faction?.Tag, actions.RemoveAllKnownPlayerAreas);
            }

            //DamageAttacker
            if (actions.DamageToolAttacker == true && detectedEntity != 0)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + ": Attempting Damage to Tool User", DebugTypeEnum.Action);
                DamageHelper.ApplyDamageToTarget(attackerEntityId, actions.DamageToolAttackerAmount, actions.DamageToolAttackerParticle, actions.DamageToolAttackerSound);
            }

            //PlayParticleEffectAtRemote
            if (actions.PlayParticleEffectAtRemote == true)
            {
                EffectManager.SendParticleEffectRequest(actions.ParticleEffectId, RemoteControl.WorldMatrix, actions.ParticleEffectOffset, actions.ParticleEffectScale, actions.ParticleEffectMaxTime, actions.ParticleEffectColor);
            }

            //ResetCooldownTimeOfTriggers
            if (actions.ResetCooldownTimeOfTriggers)
            {
                foreach (var resetTrigger in Triggers)
                {
                    if (actions.ResetTriggerCooldownNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.LastTriggerTime = MyAPIGateway.Session.GameDateTime;
                    }
                }

                foreach (var resetTrigger in DamageTriggers)
                {
                    if (actions.ResetTriggerCooldownNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.LastTriggerTime = MyAPIGateway.Session.GameDateTime;
                    }
                }

                foreach (var resetTrigger in CommandTriggers)
                {
                    if (actions.ResetTriggerCooldownNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.LastTriggerTime = MyAPIGateway.Session.GameDateTime;
                    }
                }
            }

            //EnableTriggers
            if (actions.EnableTriggers)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + " Attempting To Enable Triggers.", DebugTypeEnum.Action);

                foreach (var resetTrigger in Triggers)
                {
                    if (actions.EnableTriggerNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.UseTrigger = true;
                    }
                }

                foreach (var resetTrigger in DamageTriggers)
                {
                    if (actions.EnableTriggerNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.UseTrigger = true;
                    }
                }

                foreach (var resetTrigger in CommandTriggers)
                {
                    if (actions.EnableTriggerNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.UseTrigger = true;
                    }
                }
            }

            //DisableTriggers
            if (actions.DisableTriggers)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + " Attempting To Disable Triggers.", DebugTypeEnum.Action);

                foreach (var resetTrigger in Triggers)
                {
                    if (actions.DisableTriggerNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.UseTrigger = false;
                    }
                }

                foreach (var resetTrigger in DamageTriggers)
                {
                    if (actions.DisableTriggerNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.UseTrigger = false;
                    }
                }

                foreach (var resetTrigger in CommandTriggers)
                {
                    if (actions.DisableTriggerNames.Contains(resetTrigger.ProfileSubtypeId))
                    {
                        resetTrigger.UseTrigger = false;
                    }
                }
            }

            //ManuallyActivateTrigger
            if (actions.ManuallyActivateTrigger)
            {
                Logger.MsgDebug(actions.ProfileSubtypeId + " Attempting To Manually Activate Triggers.", DebugTypeEnum.Action);

                foreach (var manualTrigger in Triggers)
                {
                    if (actions.ManuallyActivatedTriggerNames.Contains(manualTrigger.ProfileSubtypeId))
                    {
                        ProcessManualTrigger(manualTrigger, actions.ForceManualTriggerActivation);
                    }
                }
            }

            //ChangeInertiaDampeners
            if (actions.ChangeInertiaDampeners)
            {
                RemoteControl.DampenersOverride = actions.InertiaDampenersEnable;
            }

            //ChangeRotationDirection
            if (actions.ChangeRotationDirection)
            {
                _behavior.Settings.SetRotation(actions.RotationDirection);
            }

            //GenerateExplosion
            if (actions.GenerateExplosion)
            {
                var coords = Vector3D.Transform(actions.ExplosionOffsetFromRemote, RemoteControl.WorldMatrix);
                DamageHelper.CreateExplosion(coords, actions.ExplosionRange, actions.ExplosionDamage, RemoteControl, actions.ExplosionIgnoresVoxels);
            }

            //GridEditable
            if (actions.GridEditable != CheckEnum.Ignore)
            {
                _behavior.Grid.SetGridEditable(RemoteControl.SlimBlock.CubeGrid, actions.GridEditable == CheckEnum.Yes);

                if (actions.SubGridsEditable != CheckEnum.Ignore)
                {
                    foreach (var cubeGrid in MyAPIGateway.GridGroups.GetGroup(RemoteControl.SlimBlock.CubeGrid, GridLinkTypeEnum.Physical))
                    {
                        _behavior.Grid.SetGridEditable(cubeGrid, actions.SubGridsEditable == CheckEnum.Yes);
                    }
                }
            }

            //GridDestructible
            if (actions.GridDestructible != CheckEnum.Ignore)
            {
                _behavior.Grid.SetGridDestructible(RemoteControl.SlimBlock.CubeGrid, actions.GridDestructible == CheckEnum.Yes);

                if (actions.SubGridsDestructible != CheckEnum.Ignore)
                {
                    foreach (var cubeGrid in MyAPIGateway.GridGroups.GetGroup(RemoteControl.SlimBlock.CubeGrid, GridLinkTypeEnum.Physical))
                    {
                        _behavior.Grid.SetGridDestructible(cubeGrid, actions.SubGridsDestructible == CheckEnum.Yes);
                    }
                }
            }

            //RecolorGrid
            if (actions.RecolorGrid)
            {
                _behavior.Grid.RecolorBlocks(RemoteControl.SlimBlock.CubeGrid, actions.OldBlockColors, actions.NewBlockColors, actions.NewBlockSkins);

                if (actions.RecolorSubGrids)
                {
                    foreach (var cubeGrid in MyAPIGateway.GridGroups.GetGroup(RemoteControl.SlimBlock.CubeGrid, GridLinkTypeEnum.Physical))
                    {
                        _behavior.Grid.RecolorBlocks(cubeGrid, actions.OldBlockColors, actions.NewBlockColors, actions.NewBlockSkins);
                    }
                }
            }

            //Enable Blocks
            if (actions.EnableBlocks)
            {
                _behavior.Grid.EnableBlocks(actions.EnableBlockNames, actions.EnableBlockStates);
            }

            //BuildProjectedBlocks
            if (actions.BuildProjectedBlocks)
            {
                _behavior.Grid.BuildProjectedBlocks(actions.MaxProjectedBlocksToBuild);
            }

            //ChangeBlockOwnership
            if (actions.ChangeBlockOwnership)
            {
                BlockHelper.ChangeBlockOwnership(RemoteControl.SlimBlock.CubeGrid, actions.OwnershipBlockNames, actions.OwnershipBlockFactions);
            }

            //RazeBlocks
            if (actions.RazeBlocksWithNames)
            {
                _behavior.Grid.RazeBlocksWithNames(actions.RazeBlocksNames);
            }

            //ChangeAutoPilotProfile
            if (actions.ChangeAutopilotProfile)
            {
                _behavior.AutoPilot.SetAutoPilotDataMode(actions.AutopilotProfile);
            }

            //CreateRandomLightning
            if (actions.CreateRandomLightning)
            {
                if (_behavior.AutoPilot.InGravity() && _behavior.AutoPilot.CurrentPlanet.HasAtmosphere)
                {
                    var up = Vector3D.Normalize(RemoteControl.GetPosition() - _behavior.AutoPilot.CurrentPlanet.PositionComp.WorldAABB.Center);
                    var randomPerpendicular = MyUtils.GetRandomPerpendicularVector(ref up);
                    var strikeCoords        = _behavior.AutoPilot.CurrentPlanet.GetClosestSurfacePointGlobal(randomPerpendicular * MathTools.RandomBetween(actions.LightningMinDistance, actions.LightningMaxDistance) + RemoteControl.GetPosition());
                    DamageHelper.CreateLightning(strikeCoords, actions.LightningDamage, actions.LightningExplosionRadius, actions.LightningColor);
                }
            }

            //CreateLightningAtAttacker
            if (actions.CreateLightningAtAttacker && detectedEntity != 0)
            {
                if (_behavior.AutoPilot.InGravity() && _behavior.AutoPilot.CurrentPlanet.HasAtmosphere)
                {
                    IMyEntity entity = null;

                    if (MyAPIGateway.Entities.TryGetEntityById(detectedEntity, out entity))
                    {
                        DamageHelper.CreateLightning(entity.PositionComp.WorldAABB.Center, actions.LightningDamage, actions.LightningExplosionRadius, actions.LightningColor);
                    }
                }
            }

            //CreateLightningAtTarget
            if (actions.CreateLightningAtTarget && _behavior.AutoPilot.Targeting.HasTarget())
            {
                if (_behavior.AutoPilot.InGravity() && _behavior.AutoPilot.CurrentPlanet.HasAtmosphere)
                {
                    DamageHelper.CreateLightning(_behavior.AutoPilot.Targeting.TargetLastKnownCoords, actions.LightningDamage, actions.LightningExplosionRadius, actions.LightningColor);
                }
            }

            //InheritLastAttackerFromCommand
            if (actions.InheritLastAttackerFromCommand)
            {
                _behavior.Settings.LastDamagerEntity = command != null ? command.TargetEntityId : 0;
            }

            //SetBooleansTrue
            foreach (var variable in actions.SetBooleansTrue)
            {
                _settings.SetCustomBool(variable, true);
            }

            //SetBooleansFalse
            foreach (var variable in actions.SetBooleansFalse)
            {
                _settings.SetCustomBool(variable, false);
            }

            //IncreaseCounters
            foreach (var variable in actions.IncreaseCounters)
            {
                _settings.SetCustomCounter(variable, 1);
            }

            //DecreaseCounters
            foreach (var variable in actions.DecreaseCounters)
            {
                _settings.SetCustomCounter(variable, -1);
            }

            //ResetCounters
            foreach (var variable in actions.ResetCounters)
            {
                _settings.SetCustomCounter(variable, 0, true);
            }

            //SetCounters
            if (actions.SetCounters.Count == actions.SetCountersValues.Count)
            {
                for (int i = 0; i < actions.SetCounters.Count; i++)
                {
                    _settings.SetCustomCounter(actions.SetCounters[i], actions.SetCountersValues[i], false, true);
                }
            }

            //SetSandboxBooleansTrue
            foreach (var variable in actions.SetSandboxBooleansTrue)
            {
                SetSandboxBool(variable, true);
            }

            //SetSandboxBooleansFalse
            foreach (var variable in actions.SetSandboxBooleansFalse)
            {
                SetSandboxBool(variable, false);
            }

            //IncreaseSandboxCounters
            foreach (var variable in actions.IncreaseSandboxCounters)
            {
                SetSandboxCounter(variable, 1);
            }

            //DecreaseSandboxCounters
            foreach (var variable in actions.DecreaseSandboxCounters)
            {
                SetSandboxCounter(variable, -1);
            }

            //ResetSandboxCounters
            foreach (var variable in actions.ResetSandboxCounters)
            {
                SetSandboxCounter(variable, 0);
            }

            //SetSandboxCounters
            if (actions.SetSandboxCounters.Count != 0 && actions.SetSandboxCounters.Count == actions.SetSandboxCountersValues.Count)
            {
                for (int i = 0; i < actions.SetCounters.Count; i++)
                {
                    SetSandboxCounter(actions.SetSandboxCounters[i], actions.SetSandboxCountersValues[i], true);
                }
            }

            //BehaviorSpecificEventA
            if (actions.BehaviorSpecificEventA)
            {
                _behavior.BehaviorActionA = true;
            }

            //BehaviorSpecificEventB
            if (actions.BehaviorSpecificEventB)
            {
                _behavior.BehaviorActionB = true;
            }

            //BehaviorSpecificEventC
            if (actions.BehaviorSpecificEventC)
            {
                _behavior.BehaviorActionC = true;
            }

            //BehaviorSpecificEventD
            if (actions.BehaviorSpecificEventD)
            {
                _behavior.BehaviorActionD = true;
            }

            //BehaviorSpecificEventE
            if (actions.BehaviorSpecificEventE)
            {
                _behavior.BehaviorActionE = true;
            }

            //BehaviorSpecificEventF
            if (actions.BehaviorSpecificEventF)
            {
                _behavior.BehaviorActionF = true;
            }

            //BehaviorSpecificEventG
            if (actions.BehaviorSpecificEventG)
            {
                _behavior.BehaviorActionG = true;
            }

            //BehaviorSpecificEventH
            if (actions.BehaviorSpecificEventH)
            {
                _behavior.BehaviorActionH = true;
            }
        }
예제 #31
0
        public override void UpdateAfterSimulation()
        {
            base.UpdateAfterSimulation();

            //MyRenderProxy.DebugDrawSphere(m_gunBase.PositionMuzzleWorld, 0.2f, new Vector3(1, 0, 0), 1.0f, true);

            m_targetGrid           = null;
            m_targetDestroyable    = null;
            m_targetFloatingObject = null;
            m_targetCharacter      = null;

            if (Owner == null)
            {
                return;
            }

            var   entitiesInRange    = m_sensor.EntitiesInRange;
            int   closestEntityIndex = 0;
            float closestDistance    = float.MaxValue;

            if (entitiesInRange != null && entitiesInRange.Count > 0)
            {
                int i = 0;
                foreach (var entity in entitiesInRange.Values)
                {
                    var targetGrid = entity.Entity as MyCubeGrid;
                    var distanceSq = (float)Vector3D.DistanceSquared(entity.DetectionPoint, m_gunBase.GetMuzzleWorldPosition());
                    if (entity.Entity.Physics != null && entity.Entity.Physics.Enabled)
                    {
                        if (distanceSq < closestDistance)
                        {
                            m_targetGrid           = targetGrid;
                            m_targetDistanceSq     = (float)distanceSq;
                            m_targetDestroyable    = entity.Entity as IMyDestroyableObject;
                            m_targetFloatingObject = entity.Entity as MyFloatingObject;
                            m_targetCharacter      = entity.Entity as MyCharacter;
                            closestDistance        = m_targetDistanceSq;
                            closestEntityIndex     = i;
                        }
                    }
                    ++i;
                }
            }

            if (m_targetGrid != null)
            {
                m_targetPosition = entitiesInRange.Values.ElementAt(closestEntityIndex).DetectionPoint;
                var invWorld     = m_targetGrid.PositionComp.GetWorldMatrixNormalizedInv();
                var gridLocalPos = Vector3D.Transform(m_targetPosition, invWorld);
                var gridSpacePos = Vector3I.Round(gridLocalPos / m_targetGrid.GridSize);
                m_targetGrid.FixTargetCube(out m_targetCube, gridLocalPos / m_targetGrid.GridSize);

                var head        = PositionComp.WorldMatrix;
                var aimToMuzzle = Vector3D.Normalize(m_targetPosition - m_gunBase.GetMuzzleWorldPosition());
                if (Vector3.Dot(aimToMuzzle, head.Forward) > 0)
                {
                    m_targetDistanceSq = 0;
                }
                else
                {
                    m_targetDistanceSq = (float)Vector3D.DistanceSquared(m_targetPosition, m_gunBase.GetMuzzleWorldPosition());
                }
            }
            SinkComp.Update();

            if (IsShooting && !SinkComp.IsPowered)
            {
                EndShoot(MyShootActionEnum.PrimaryAction);
            }

            UpdateEffect();
            CheckEffectType();

            if (Owner != null && Owner.ControllerInfo.IsLocallyHumanControlled())
            {
                if (MySession.Static.SurvivalMode && (MySession.GetCameraControllerEnum() != MyCameraControllerEnum.Spectator || MyFinalBuildConstants.IS_OFFICIAL))
                {
                    var character = ((MyCharacter)this.CharacterInventory.Owner);
                    MyCubeBuilder.Static.MaxGridDistanceFrom = character.PositionComp.GetPosition() + character.WorldMatrix.Up * 1.8f;
                }
                else
                {
                    MyCubeBuilder.Static.MaxGridDistanceFrom = null;
                }
            }

            //MyTrace.Watch("MyEngineerToolBase.RequiredPowerInput", RequiredPowerInput);
        }
예제 #32
0
        private void ScanLine(Triangle triangle, byte[] pixels)
        {
            double ymin = triangle.Edges.Max((e) => { return(e.From.Y); }), miny;

            List <EdgeET>[] ET = new List <EdgeET> [(int)Math.Round(ymin) + 1];
            foreach (var edge in triangle.Edges)
            {
                if (edge.From.Y == edge.To.Y)
                {
                    continue;
                }
                miny = edge.From.Y < edge.To.Y ? edge.To.Y : edge.From.Y;
                if (ET[(int)Math.Round(miny)] == null)
                {
                    ET[(int)Math.Round(miny)] = new List <EdgeET>();
                }
                ET[(int)Math.Round(miny)].Add(new EdgeET(edge));
            }
            int y = -1;
            int i = 0;

            for (i = 0; i < ET.Length; i++)
            {
                var it = ET[i];
                if (it != null)
                {
                    if (y == -1 || i > y)
                    {
                        y = i;
                    }
                    it.Sort((el1, el2) =>
                    {
                        return((int)(el1.edge.To.X - el2.edge.From.X));
                    });
                }
            }
            List <EdgeET> AET = new List <EdgeET>();
            double        kd, ks, m;
            Color         c = Colors.Blue;
            Vector3D      N = new Vector3D(0, 0, 1);

            if (!appliedColorSettings.ColorFromTexture)
            {
                c = appliedColorInfo.ObjectColor;
            }
            if (appliedColorSettings.KMSliders)
            {
                kd = appliedColorInfo.Kd;
                ks = appliedColorInfo.Ks;
                m  = appliedColorInfo.M;
            }
            else
            {
                Random random = new Random();
                kd = random.NextDouble();
                ks = 1 - kd;
                m  = random.Next() % 100 + 1;
            }
            while (!(AET.Count == 0 && IsArrayEmpty(ET)))
            {
                if (y > 0 && ET[y] != null)
                {
                    foreach (var e in ET[y])
                    {
                        AET.Add(e);
                    }
                    ET[y] = null;
                }
                AET.Sort((el1, el2) =>
                {
                    return((int)(el1.xmin - el2.xmin) == 0 ? (int)(el1.ymax - el2.ymax) : (int)(el1.xmin - el2.xmin));
                });
                List <EdgeET> todel = new List <EdgeET>();
                for (int k = 0; k < AET.Count; k++)
                {
                    if (k < AET.Count - 1)
                    {
                        double x1 = AET[k].xmin;
                        double x2 = AET[k + 1].xmin;
                        for (double x = Math.Round(x1); x <= Math.Round(x2); x++)
                        {
                            int      index;
                            Vector3D vector = new Vector3D(0, 0, 0);
                            index = (int)Math.Round(x) * 4 + y * colBitmapStride;
                            Vector3D bubbleN = new Vector3D(0, 0, 1);
                            if (appliedColorSettings.Bubble && InsideBubble(new Point(x, y)))
                            {
                                double xx = (x - bubblePoint.X) * (x - bubblePoint.X);
                                double yy = (y - bubblePoint.Y) * (y - bubblePoint.Y);
                                double zz = 50 * 50 - xx - yy;
                                bubbleN = new Vector3D(xx, yy, zz);
                                bubbleN.Normalize();
                            }
                            if (appliedColorSettings.ColorFromTexture)
                            {
                                c = Color.FromRgb(ColBitmap[index + 2], ColBitmap[index + 1], ColBitmap[index]);
                            }
                            if (appliedColorSettings.InterpolMode)
                            {
                                int      wx1 = (int)triangle.Edges[0].From.X;
                                int      wx2 = (int)triangle.Edges[1].From.X;
                                int      wx3 = (int)triangle.Edges[2].From.X;
                                int      wy1 = (int)triangle.Edges[0].From.Y;
                                int      wy2 = (int)triangle.Edges[1].From.Y;
                                int      wy3 = (int)triangle.Edges[2].From.Y;
                                Vector3D bubbleN1 = new Vector3D(0, 0, 1), bubbleN2 = new Vector3D(0, 0, 1), bubbleN3 = new Vector3D(0, 0, 1);
                                if (appliedColorSettings.Bubble && InsideBubble(new Point(wx1, wy1)))
                                {
                                    double xx1 = (wx1 - bubblePoint.X) * (wx1 - bubblePoint.X);
                                    double yy1 = (wy1 - bubblePoint.Y) * (wy1 - bubblePoint.Y);
                                    double zz1 = 50 * 50 - xx1 - yy1;
                                    bubbleN1 = new Vector3D(xx1, yy1, zz1);
                                    bubbleN1.Normalize();
                                }
                                if (appliedColorSettings.Bubble && InsideBubble(new Point(wx2, wy2)))
                                {
                                    double xx2 = (wx2 - bubblePoint.X) * (wx2 - bubblePoint.X);
                                    double yy2 = (wy2 - bubblePoint.Y) * (wy2 - bubblePoint.Y);
                                    double zz2 = 50 * 50 - xx2 - yy2;
                                    bubbleN2 = new Vector3D(xx2, yy2, zz2);
                                    bubbleN2.Normalize();
                                }
                                if (appliedColorSettings.Bubble && InsideBubble(new Point(wx2, wy2)))
                                {
                                    double xx3 = (wx3 - bubblePoint.X) * (wx3 - bubblePoint.X);
                                    double yy3 = (wy3 - bubblePoint.Y) * (wy3 - bubblePoint.Y);
                                    double zz3 = 50 * 50 - xx3 - yy3;
                                    bubbleN3 = new Vector3D(xx3, yy3, zz3);
                                    bubbleN3.Normalize();
                                }
                                Vector3D v1, v2, v3;
                                if (appliedColorSettings.ColorFromTexture)
                                {
                                    int   index1 = wx1 * 4 + wy1 * colBitmapStride;
                                    Color c1     = Color.FromRgb(ColBitmap[index1 + 2], ColBitmap[index1 + 1], ColBitmap[index1]);
                                    int   index2 = wx2 * 4 + wy2 * colBitmapStride;
                                    Color c2     = Color.FromRgb(ColBitmap[index2 + 2], ColBitmap[index2 + 1], ColBitmap[index2]);
                                    int   index3 = wx3 * 4 + wy3 * colBitmapStride;
                                    Color c3     = Color.FromRgb(ColBitmap[index3 + 2], ColBitmap[index3 + 1], ColBitmap[index3]);
                                    v1 = I(kd, ks, m, c1, bubbleN1, wx1, wy1);
                                    v2 = I(kd, ks, m, c2, bubbleN2, wx2, wy2);
                                    v3 = I(kd, ks, m, c3, bubbleN3, wx3, wy3);
                                }
                                else
                                {
                                    v1 = I(kd, ks, m, c, bubbleN1, wx1, wy1);
                                    v2 = I(kd, ks, m, c, bubbleN2, wx2, wy2);
                                    v3 = I(kd, ks, m, c, bubbleN3, wx3, wy3);
                                }
                                double l1 = CalculateLength((int)x, y, wx1, wy1);
                                double l2 = CalculateLength((int)x, y, wx2, wy2);
                                double l3 = CalculateLength((int)x, y, wx3, wy3);
                                vector = (v1 * l1 + v2 * l2 + v3 * l3) / (l1 + l2 + l3);
                            }
                            else if (appliedColorSettings.HybridMode)
                            {
                                int    wx1   = (int)triangle.Edges[0].From.X;
                                int    wx2   = (int)triangle.Edges[1].From.X;
                                int    wx3   = (int)triangle.Edges[2].From.X;
                                int    wy1   = (int)triangle.Edges[0].From.Y;
                                int    wy2   = (int)triangle.Edges[1].From.Y;
                                int    wy3   = (int)triangle.Edges[2].From.Y;
                                double gamma = (y * wx2 - y * wx1 - wx2 * wy1 + x * wy1 - x * wy2 + wx1 * wy2)
                                               / (wy1 * wx3 - wy1 * wx2 + wx1 * wy2 - wx3 * wy2 + wy3 * wx2 - wy3 * wx1);
                                double   beta = (x + gamma * wx1 - gamma * wx3 - wx1) / (wx2 - wx1);
                                double   alfa = 1 - beta - gamma;
                                Vector3D v1, v2, v3;
                                Vector3D bubbleN1 = new Vector3D(0, 0, 1), bubbleN2 = new Vector3D(0, 0, 1), bubbleN3 = new Vector3D(0, 0, 1);
                                if (appliedColorSettings.Bubble && InsideBubble(new Point(wx1, wy1)))
                                {
                                    double xx1 = (wx1 - bubblePoint.X) * (wx1 - bubblePoint.X);
                                    double yy1 = (wy1 - bubblePoint.Y) * (wy1 - bubblePoint.Y);
                                    double zz1 = 50 * 50 - xx1 - yy1;
                                    bubbleN1 = new Vector3D(xx1, yy1, zz1);
                                    bubbleN1.Normalize();
                                }
                                if (appliedColorSettings.Bubble && InsideBubble(new Point(wx2, wy2)))
                                {
                                    double xx2 = (wx2 - bubblePoint.X) * (wx2 - bubblePoint.X);
                                    double yy2 = (wy2 - bubblePoint.Y) * (wy2 - bubblePoint.Y);
                                    double zz2 = 50 * 50 - xx2 - yy2;
                                    bubbleN2 = new Vector3D(xx2, yy2, zz2);
                                    bubbleN2.Normalize();
                                }
                                if (appliedColorSettings.Bubble && InsideBubble(new Point(wx2, wy2)))
                                {
                                    double xx3 = (wx3 - bubblePoint.X) * (wx3 - bubblePoint.X);
                                    double yy3 = (wy3 - bubblePoint.Y) * (wy3 - bubblePoint.Y);
                                    double zz3 = 50 * 50 - xx3 - yy3;
                                    bubbleN3 = new Vector3D(xx3, yy3, zz3);
                                    bubbleN3.Normalize();
                                }
                                bubbleN3.Normalize();
                                if (appliedColorSettings.ColorFromTexture)
                                {
                                    int   index1 = wx1 * 4 + wy1 * colBitmapStride;
                                    Color c1     = Color.FromRgb(ColBitmap[index1 + 2], ColBitmap[index1 + 1], ColBitmap[index1]);
                                    int   index2 = wx2 * 4 + wy2 * colBitmapStride;
                                    Color c2     = Color.FromRgb(ColBitmap[index2 + 2], ColBitmap[index2 + 1], ColBitmap[index2]);
                                    int   index3 = wx3 * 4 + wy3 * colBitmapStride;
                                    Color c3     = Color.FromRgb(ColBitmap[index3 + 2], ColBitmap[index3 + 1], ColBitmap[index3]);
                                    v1 = I(kd, ks, m, c1, bubbleN1, wx1, wy1);
                                    v2 = I(kd, ks, m, c2, bubbleN2, wx2, wy2);
                                    v3 = I(kd, ks, m, c3, bubbleN3, wx3, wy3);
                                }
                                else
                                {
                                    v1 = I(kd, ks, m, c, bubbleN1, wx1, wy1);
                                    v2 = I(kd, ks, m, c, bubbleN2, wx2, wy2);
                                    v3 = I(kd, ks, m, c, bubbleN3, wx3, wy3);
                                }
                                vector = alfa * v1 + beta * v2 + gamma * v3;
                            }
                            else
                            {
                                vector = I(kd, ks, m, c, bubbleN, (int)Math.Round(x), y);
                            }
                            Color col = Color.FromRgb((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
                            index             = (int)Math.Round(x) * 4 + y * mainStride;
                            pixels[index]     = col.B;
                            pixels[index + 1] = col.G;
                            pixels[index + 2] = col.R;
                            pixels[index + 3] = col.A;
                        }
                    }
                }
                for (int k = 0; k < AET.Count; k++)
                {
                    if (Math.Round(AET[k].ymax) == y)
                    {
                        todel.Add(AET[k]);
                    }
                }
                y--;
                foreach (var e in AET)
                {
                    e.xmin -= e.m;
                }
                foreach (var t in todel)
                {
                    AET.Remove(t);
                }
            }
        }
예제 #33
0
        void DrawInfluenceCone(Vector3D conePos)
        {
            Vector4     color          = Color.Cyan.ToVector4() * 10;
            Vector4     planeColor     = (Color.White * 0.1f).ToVector4();
            const float LINE_THICK     = 0.02f;
            const int   WIRE_DIV_RATIO = 16;

            var coneMatrix = block.WorldMatrix;

            coneMatrix.Translation = conePos;

            //MyTransparentGeometry.AddPointBillboard(Mod.MATERIAL_DOT, Color.Lime, collectPos, 0.05f, 0);

            float rangeOffset = Range + (offset * 2); // because range check starts from collectPos but cone starts from conePos
            float baseRadius  = rangeOffset * (float)Math.Tan(coneAngle);

            //MySimpleObjectDraw.DrawTransparentCone(ref coneMatrix, baseRadius, rangeWithOffset, ref color, 16, Mod.MATERIAL_SQUARE);

            var apexPosition    = coneMatrix.Translation;
            var directionVector = coneMatrix.Forward * rangeOffset;
            var maxPosCenter    = conePos + coneMatrix.Forward * rangeOffset;
            var baseVector      = coneMatrix.Up * baseRadius;

            Vector3 axis = directionVector;

            axis.Normalize();

            float stepAngle = (float)(Math.PI * 2.0 / (double)WIRE_DIV_RATIO);

            var prevConePoint = apexPosition + directionVector + Vector3.Transform(baseVector, Matrix.CreateFromAxisAngle(axis, (-1 * stepAngle)));

            prevConePoint = (apexPosition + Vector3D.Normalize((prevConePoint - apexPosition)) * rangeOffset);

            var quad = default(MyQuadD);

            for (int step = 0; step < WIRE_DIV_RATIO; step++)
            {
                var conePoint = apexPosition + directionVector + Vector3.Transform(baseVector, Matrix.CreateFromAxisAngle(axis, (step * stepAngle)));
                var lineDir   = (conePoint - apexPosition);
                lineDir.Normalize();
                conePoint = (apexPosition + lineDir * rangeOffset);

                MyTransparentGeometry.AddLineBillboard(Mod.MATERIAL_SQUARE, color, conePoint, (prevConePoint - conePoint), 1f, LINE_THICK);

                MyTransparentGeometry.AddLineBillboard(Mod.MATERIAL_SQUARE, color, apexPosition, lineDir, rangeOffset, LINE_THICK);

                MyTransparentGeometry.AddLineBillboard(Mod.MATERIAL_SQUARE, color, conePoint, (maxPosCenter - conePoint), 1f, LINE_THICK);

                // Unusable because SQUARE has reflectivity and this method uses materials' reflectivity... making it unable to be made transparent, also reflective xD
                //var normal = Vector3.Up;
                //MyTransparentGeometry.AddTriangleBillboard(
                //    apexPosition, prevConePoint, conePoint,
                //    normal, normal, normal,
                //    new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1),
                //    Mod.MATERIAL_SQUARE, uint.MaxValue, conePoint, planeColor);
                // also NOTE: if triangle is used, color needs .ToLinearRGB().

                quad.Point0 = prevConePoint;
                quad.Point1 = conePoint;
                quad.Point2 = apexPosition;
                quad.Point3 = apexPosition;
                MyTransparentGeometry.AddQuad(Mod.MATERIAL_SQUARE, ref quad, planeColor, ref Vector3D.Zero);

                quad.Point0 = prevConePoint;
                quad.Point1 = conePoint;
                quad.Point2 = maxPosCenter;
                quad.Point3 = maxPosCenter;
                MyTransparentGeometry.AddQuad(Mod.MATERIAL_SQUARE, ref quad, planeColor, ref Vector3D.Zero);

                prevConePoint = conePoint;
            }
        }
예제 #34
0
 private void OnLModeClick(object sender, RoutedEventArgs e)
 {
     LVector = new Vector3D(-0.3, 0, 0.91);
     LVector.Normalize();
 }
        private void KeepTextInsideClientRectangle()
        {
            this.CoordinateSystem = CoordinateSystem.Destination;

            PointF startPoint, endPoint;
            float  lengthOfLineThroughTextBox;

            if (!GetTextBoxAdjustmentParameters(out startPoint, out endPoint, out lengthOfLineThroughTextBox))
            {
                _line.Point1   = Point1;
                _line.Point2   = Point2;
                _text.Location = Point1;

                this.ResetCoordinateSystem();
                return;
            }

            Vector3D lineDirection = new Vector3D(endPoint.X - startPoint.X, endPoint.Y - startPoint.Y, 0F);

            float ratioLengthOfLineThroughTextBox = lengthOfLineThroughTextBox / lineDirection.Magnitude;

            SizeF textEdgeOffset = new SizeF(ratioLengthOfLineThroughTextBox * lineDirection.X, ratioLengthOfLineThroughTextBox * lineDirection.Y);

            SizeF textAnchorPointOffset = new SizeF(textEdgeOffset.Width / 2F, textEdgeOffset.Height / 2F);

            Vector3D lineUnit = lineDirection.Normalize();

            // extend the endpoint of the line by the distance to the outside text edge.
            endPoint = PointF.Add(endPoint, textEdgeOffset);
            // add an additional 5 pixel offset so we don't push back as far as the start point.
            endPoint = PointF.Add(endPoint, new SizeF(5F * lineUnit.X, 5F * lineUnit.Y));

            SizeF clientEdgeOffset = Size.Empty;

            // find the intersection of the extended line segment and either of the left or bottom client edge.
            PointF?intersectionPoint = GetClientRightOrBottomEdgeIntersectionPoint(startPoint, endPoint);

            if (intersectionPoint != null)
            {
                Vector3D clientEdgeOffsetVector = new Vector3D(endPoint.X - intersectionPoint.Value.X, endPoint.Y - intersectionPoint.Value.Y, 0);
                //don't allow the text to be pushed back past the start point.
                if (clientEdgeOffsetVector.Magnitude > lineDirection.Magnitude)
                {
                    clientEdgeOffsetVector = lineDirection;
                }

                clientEdgeOffset = new SizeF(clientEdgeOffsetVector.X, clientEdgeOffsetVector.Y);
            }

            _line.Point1 = startPoint;

            // offset by the distance from the extended endpoint to the client rectangle edge.
            endPoint = PointF.Subtract(endPoint, clientEdgeOffset);
            // offset again by half the distance necessary to keep the text box inside the client rectangle
            endPoint = PointF.Subtract(endPoint, textAnchorPointOffset);

            // this aligns the text edge with the client edge in the case where the line intersects the client edge.
            _text.Location = endPoint;

            // offset the line by half again the distance necessary to keep the text box inside the client rectangle.
            _line.Point2 = PointF.Subtract(endPoint, textAnchorPointOffset);

            this.ResetCoordinateSystem();
        }
예제 #36
0
 protected Vector3D GetSpawnPositionSphere()
 {
     var insideSphere =
         new Vector3D(
             EmitterData.StartPosition.Start.X.Lerp(EmitterData.StartPosition.End.X,
                 Randomizer.Current.Get()),
             EmitterData.StartPosition.Start.Y.Lerp(EmitterData.StartPosition.End.Y,
                 Randomizer.Current.Get()),
             EmitterData.StartPosition.Start.Z.Lerp(EmitterData.StartPosition.End.Z,
                 Randomizer.Current.Get()));
     insideSphere.Normalize();
     insideSphere *=
         0.0f.Lerp(EmitterData.StartPosition.Start.Distance(EmitterData.StartPosition.End) * 0.5f,
             Randomizer.Current.Get());
     return Position + insideSphere;
 }
예제 #37
0
        /// <summary>
        /// Draw all entities stored in buffer
        /// </summary>
        public void Flush()
        {
            // initialize
            Vector3D vLight = _vCameraPos - _vTarget; vLight.Normalize();

            _boxDrawingCounter = 0;
            _currentTransf     = null;
            System.Drawing.Graphics g = Graphics;
            g.Clear(_backgroundColor);

            if (EnableFaceSorting)
            {
                // sort face list
                FaceComparison faceComparer = new FaceComparison(GetWorldToEyeTransformation());
                _faces.Sort(faceComparer);
            }
            // draw background segments
            foreach (Segment s in _segmentsBackground)
            {
                Draw(s);
            }
            // draw background faces
            foreach (Face face in _facesBackground)
            {
                Draw(face, FaceDir.FRONT);
            }
            // draw all faces using solid / transparency depending on
            foreach (Face face in _faces)
            {
                Draw(face, FaceDir.BACK);
            }

            // sort box list
            if (_useBoxelOrderer)
            {
                BoxelOrderer boxelOrderer = new BoxelOrderer(_boxes);
                boxelOrderer.Direction = _vTarget - _vCameraPos;
                _boxes = boxelOrderer.GetSortedList();
            }
            else
            {
                _boxes.Sort(new BoxComparerSimplifiedPainterAlgo(GetWorldToEyeTransformation()));
            }

            // sort cylinder list
            _cylinders.Sort(new CylinderComparerSimplifiedPainterAlgo(GetWorldToEyeTransformation()));

            if (_cylinders.Count > 0)
            {
                // sort by Z
                List <Drawable> drawableList = new List <Drawable>();
                drawableList.AddRange(_boxes);
                drawableList.AddRange(_cylinders);
                drawableList.Sort(new DrawableComparerSimplifiedPainterAlgo());

                List <Box>      boxes         = new List <Box>();
                List <Cylinder> cylinders     = new List <Cylinder>();
                bool            processingBox = drawableList[0] is Box;
                foreach (Drawable drawable in drawableList)
                {
                    Box      b = drawable as Box;
                    Cylinder c = drawable as Cylinder;

                    if ((null != b) && processingBox)
                    {
                        boxes.Add(b);
                    }
                    else if ((null == b) && !processingBox)
                    {
                        cylinders.Add(c);
                    }
                    else
                    {
                        if (boxes.Count > 0)
                        {
                            BoxelOrderer boxelOrderer = new BoxelOrderer(boxes);
                            boxelOrderer.Direction = _vTarget - _vCameraPos;
                            boxes = boxelOrderer.GetSortedList();
                            // draw boxes
                            foreach (Box bb in boxes)
                            {
                                Draw(bb);
                            }
                            // clear
                            boxes.Clear();
                        }
                        if (cylinders.Count > 0)
                        {
                            cylinders.Sort(new CylinderComparerSimplifiedPainterAlgo(GetWorldToEyeTransformation()));
                            // draw cylinders
                            foreach (Cylinder cc in cylinders)
                            {
                                Draw(cc);
                            }
                            // clear
                            cylinders.Clear();
                        }
                        if (null != b)
                        {
                            boxes.Add(b);
                            processingBox = true;
                        }
                        else
                        {
                            cylinders.Add(c);
                            processingBox = false;
                        }
                    }
                }

                // remaining boxes
                BoxelOrderer boxelOrdererRem = new BoxelOrderer(boxes);
                boxelOrdererRem.Direction = _vTarget - _vCameraPos;
                boxes = boxelOrdererRem.GetSortedList();
                // draw boxes
                foreach (Box bb in boxes)
                {
                    Draw(bb);
                }

                // remaining cylinders
                cylinders.Sort(new CylinderComparerSimplifiedPainterAlgo(GetWorldToEyeTransformation()));
                // draw cylinders
                foreach (Cylinder cc in cylinders)
                {
                    Draw(cc);
                }
                // clear
                boxes.Clear();
            }
            else
            {
                // draw all boxes
                foreach (Box box in _boxes)
                {
                    Draw(box);
                }
            }
            // images inst
            if (_listImageInst.Count > 0)
            {
                // --- sort image inst
                Analysis   analysis   = _listImageInst[0].Analysis;
                BBox3D     bbox       = analysis.Solution.BBoxGlobal;
                List <Box> boxesImage = new List <Box>();
                foreach (ImageInst imageInst in _listImageInst)
                {
                    boxesImage.Add(imageInst.ToBox());
                }

                if (_useBoxelOrderer && false) // NOT WORKING ?
                {
                    BoxelOrderer boxelOrderer = new BoxelOrderer(boxesImage);
                    boxelOrderer.TuneParam = 10.0;
                    boxelOrderer.Direction = _vTarget - _vCameraPos;
                    boxesImage             = boxelOrderer.GetSortedList();
                }
                else
                {
                    boxesImage.Sort(new BoxComparerSimplifiedPainterAlgo(GetWorldToEyeTransformation()));
                }
                // ---

                List <ImageInst> listImageInstSorted = new List <ImageInst>();
                foreach (Box b in boxesImage)
                {
                    listImageInstSorted.Add(new ImageInst(analysis, new Vector3D(b.Length, b.Width, b.Height), b.BPosition));
                }

                // draw image inst
                foreach (ImageInst im in listImageInstSorted)
                {
                    Draw(im);
                }
            }
            // draw faces : end
            foreach (Face face in _faces)
            {
                Draw(face, FaceDir.FRONT);
            }

            // draw segment list (e.g. hatching)
            foreach (Segment seg in _segments)
            {
                Draw(seg);
            }

            // draw cotation cubes
            if (ShowDimensions)
            {
                foreach (DimensionCube qc in _dimensions)
                {
                    qc.Draw(this);
                }
            }
        }
예제 #38
0
 private Vector3D GetSpawnPositionCircleOutline()
 {
     var startPosition = EmitterData.StartPosition;
     var onCircleOutline = new Vector3D(
         startPosition.Start.X + Randomizer.Current.Get(-1.0f) * startPosition.End.X,
         startPosition.Start.Y + Randomizer.Current.Get(-1.0f) * startPosition.End.Y, 0.0f);
     onCircleOutline.Normalize();
     var diameter = Math.Max(startPosition.Start.Length, startPosition.End.Length);
     onCircleOutline *= diameter * 0.5f;
     return (Rotation.Equals(Quaternion.Identity))
         ? Position + onCircleOutline : Position + onCircleOutline.Transform(Rotation);
 }
예제 #39
0
		//--------------------------------------------------------------------------------

		/// <summary>
		/// Get an orthogonal basis for the plane
		/// </summary>
		/// <param name="u"></param>
		/// <param name="v"></param>
		public void		GetBasis( out Vector3D u, out Vector3D v ) {
			Vector3D pt = this.ProjectOntoPlane( Vector3D.Origin );

			u = this.ProjectOntoPlane( pt + Vector3D.XAxis ) - pt;
			u = Vector3D.Max( u, this.ProjectOntoPlane( pt + Vector3D.YAxis ) - pt );
			u = Vector3D.Max( u, this.ProjectOntoPlane( pt + Vector3D.ZAxis ) - pt );

			v = Vector3D.Cross( u, this.Normal );

			u.Normalize();
			v.Normalize();
		}
예제 #40
0
파일: S3.cs 프로젝트: roice3/Honeycombs
        private static Vector3D[] OneHopfCircle( Vector3D s2Point )
        {
            int circleDivisions = 125;

            // Get the hopf circle.
            // http://en.wikipedia.org/wiki/Hopf_fibration#Explicit_formulae
            double a = s2Point.X;
            double b = s2Point.Y;
            double c = s2Point.Z;
            double factor = 1 / ( Math.Sqrt( 1 + c ) );
            if( Tolerance.Equal( c, -1 ) )
                return new Vector3D[] {};

            List<Vector3D> circlePoints = new List<Vector3D>();
            double angleInc = 2 * Math.PI / circleDivisions;
            double angle = 0;
            for( int i = 0; i <= circleDivisions; i++ )
            {
                double sinTheta = Math.Sin( angle );
                double cosTheta = Math.Cos( angle );
                Vector3D point = new Vector3D(
                    ( 1 + c ) * cosTheta,
                    a * sinTheta - b * cosTheta,
                    a * cosTheta + b * sinTheta,
                    ( 1 + c ) * sinTheta );
                point.Normalize();
                circlePoints.Add( point );

                angle += angleInc;
            }

            return circlePoints.ToArray();
        }
예제 #41
0
        private void SetPatientOrientation(Vector3D rowDirectionPatient, Vector3D columnDirectionPatient)
        {
            if (!CanRotate())
            {
                return;
            }

            if (rowDirectionPatient == null || columnDirectionPatient == null || !rowDirectionPatient.IsOrthogonalTo(columnDirectionPatient, (float)(5 / 180d * Math.PI)))
            {
                return;
            }

            var patientPresentation = SelectedPresentationImage as IPatientPresentationProvider;

            if (patientPresentation == null || !patientPresentation.PatientPresentation.IsValid)
            {
                return;
            }

            // Note the inverted column orientation vectors in both matrices - this is due to implicit Y axis inversion in the 3D transform
            columnDirectionPatient = -columnDirectionPatient;

            var currentRowOrientation    = patientPresentation.PatientPresentation.OrientationX;
            var currentColumnOrientation = -patientPresentation.PatientPresentation.OrientationY;
            var currentOrientation       = Matrix3D.FromRows(currentRowOrientation.Normalize(), currentColumnOrientation.Normalize(), currentRowOrientation.Cross(currentColumnOrientation).Normalize());
            var requestedOrientation     = Matrix3D.FromRows(rowDirectionPatient.Normalize(), columnDirectionPatient.Normalize(), rowDirectionPatient.Cross(columnDirectionPatient).Normalize());

            var transform = _operation.GetOriginator(SelectedPresentationImage);

            // (because we're dealing with rotation matrices (i.e. orthogonal!), the Inverse is just Transpose)
            var rotation = requestedOrientation * currentOrientation.Transpose();

            transform.Rotation = rotation * transform.Rotation;           // this rotation is cumulative upon current rotation, since IPatientPresentationProvider is based on *current* view

            SelectedPresentationImage.Draw();
        }
 public void GetSurfaceNormalForPoint(ref Vector3D point, out Vector3D normal)
 {
     normal = point - PlanetTranslation;
     normal.Normalize();
 }
예제 #43
0
 public void Normalize()
 {
     Vector3D v = new Vector3D(3.0, -1.0, 23.0);
       v.Normalize();
       Assert.IsTrue(v.IsNumericallyNormalized);
 }
예제 #44
0
 public UnitVector3D Normalize()
 {
     return(V1.Normalize());
 }
예제 #45
0
        /**
         * <summary>
         * Sphere must be the first, not moving object in center
         * just the second object can move
         * </summary>
         */
        public CollisionResponse CheckSimplified(CollisionSimplifiedScenario scenario)
        {
            CollisionResponse test = null;


            // 1. first escape scenario -point is too far to collide with sphere
            //      it may happen if (|point center| - R) ^2 <= movement ^2

            double R = scenario.ColliderShape1.CalculateMaximumRadius;

            Vector3D totalDisplacement;

            totalDisplacement = scenario.Linear.Velocity * scenario.Linear.DeltaTime;

            Vector3D minimumDistanceToSphere         = new Point3D(0, 0, 0) - scenario.Linear.StartingPosition;
            Vector3D absoluteminimumDistanceToSphere = minimumDistanceToSphere.Abs();

            absoluteminimumDistanceToSphere.X = Math.Max(0, absoluteminimumDistanceToSphere.X - R);
            absoluteminimumDistanceToSphere.Y = Math.Max(0, absoluteminimumDistanceToSphere.Y - R);
            absoluteminimumDistanceToSphere.Z = Math.Max(0, absoluteminimumDistanceToSphere.Z - R);

            if (absoluteminimumDistanceToSphere.LengthSquared > totalDisplacement.LengthSquared)
            {
                return(test);
            }

            // 2. check direction of displacement. If point does not move towards the center
            //      escape, as can never collide with sphere
            Vector3D PointTowardsSphereCenter = minimumDistanceToSphere;
            double   displacementDirection    = Vector3D.DotProduct(PointTowardsSphereCenter, totalDisplacement);

            if (displacementDirection < 0)
            {
                return(test);
            }

            // 3. Check calculation
            Vector3D VelocityDirectionNormalized = new Vector3D(totalDisplacement.X, totalDisplacement.Y, totalDisplacement.Z);

            VelocityDirectionNormalized.Normalize();

            double   lo = Vector3D.DotProduct(VelocityDirectionNormalized, PointTowardsSphereCenter);
            Vector3D TowardCenterAbsolute = PointTowardsSphereCenter.Abs();
            double   sqareRootValue       = lo * lo - TowardCenterAbsolute.LengthSquared + R * R;

            // 3a. escape condition
            if (sqareRootValue < 0)
            {
                return(test);
            }

            double squareCalculatedValue = Math.Sqrt(sqareRootValue);
            double d1 = Math.Abs(-lo + squareCalculatedValue);
            double d2 = Math.Abs(-lo - squareCalculatedValue);
            double d  = Math.Min(d1, d2);

            Vector3D FastestCollisionLength = d * VelocityDirectionNormalized;

            // the last escape, collision would happen, but in next frames
            if (FastestCollisionLength.LengthSquared > totalDisplacement.LengthSquared)
            {
                return(test);
            }

            test = new CollisionResponse(
                (float)d,
                scenario.Linear.StartingPosition + FastestCollisionLength
                );

            return(test);
        }
예제 #46
0
        private Vector3D getViewUp(Viewpoint oVP)
        {
            double units = GetGunits();

            Rotation3D oRot = oVP.Rotation;
            // calculate view direction
            Rotation3D oNegtiveZ = new Rotation3D(0, 1, 0, 0);
            Rotation3D otempRot = MultiplyRotation3D(oNegtiveZ, oRot.Invert());
            Rotation3D oViewDirRot = MultiplyRotation3D(oRot, otempRot);
            // get view direction
            Vector3D oViewDir = new Vector3D(oViewDirRot.A, oViewDirRot.B, oViewDirRot.C);

            return oViewDir.Normalize();
        }
예제 #47
0
		public void NormalizeOfAnyVector()
		{
			var v = new Vector3D(1.0f, 2.0f, -3.0f);
			Assert.AreNotEqual(1.0f, v.Length);
			v.Normalize();
			Assert.AreEqual(1.0f, v.LengthSquared, MathExtensions.Epsilon);
			v = Vector3D.UnitX;
			v.Normalize();
			Assert.AreEqual(1.0f, v.Length, MathExtensions.Epsilon);
		}
예제 #48
0
            public bool Perform()
            {
                switch (State)
                {
                case "Initial":
                    State = "Requesting Clearance";
                    break;

                case "Requesting Clearance":
                    SendRequest();
                    State = "Waiting for Clearance";
                    break;

                case "Waiting for Clearance":
                    Drone.Log("Waiting for clearance");
                    break;

                case "Approaching Dock":
                    if (Move == null)
                    {
                        Move = new Move(Drone, new Queue <Vector3D>(new[] { ApproachPath[0] }), Drone.Remote, true);
                    }

                    if (Move.Perform())
                    {
                        Move  = null;
                        State = "Docking";
                    }

                    break;

                case "Docking":
                    DockingPort.Enabled = true;

                    Vector3D nearDock = ApproachPath[1] + Vector3D.Normalize(ApproachPath[0] - ApproachPath[1]) * 2.5;
                    if (Move == null)
                    {
                        Move = new Move(Drone, new Queue <Vector3D>(new[] { nearDock }), DockingPort, true);
                    }

                    if (Move.Perform())
                    {
                        Move = null;
                        Drone.AllStop();
                        State = "Final Approach";
                    }

                    break;

                case "Final Approach":
                    if (Move == null)
                    {
                        Move = new Move(Drone, new Queue <Vector3D>(new[] { ApproachPath[1] }), DockingPort, true, 0.25);
                    }

                    if (Move.Perform() || DockingPort.Status == MyShipConnectorStatus.Connected)
                    {
                        Move = null;
                        Drone.AllStop();
                        State = "Connecting";
                    }
                    DockingPort.Connect();
                    break;

                case "Connecting":
                    if (DockingPort.Status == MyShipConnectorStatus.Connected)
                    {
                        Drone.AllStop();
                        State = "Final";
                    }
                    DockingPort.Connect();
                    break;

                case "Final":
                    return(true);
                }

                return(false);
            }
예제 #49
0
        private void UpdateGyro(Vector3D deltaPos, Vector3D perpDeltaPos, out bool rotating, out bool isLabile)
        {
            isLabile = false; // Whether the rotation is currently near a value, where there is discontinuity in the desired rotation
            rotating = true;  // Whether the gyros are currently performing a rotation

            var gyros = CubeGrid.GridSystems.GyroSystem;
            gyros.ControlTorque = Vector3.Zero;
            Vector3D angularVelocity = CubeGrid.Physics.AngularVelocity;
            var orientation = GetOrientation();
            Matrix invWorldRot = CubeGrid.PositionComp.WorldMatrixNormalizedInv.GetOrientation();

            Vector3D gravity = m_currentInfo.GravityWorld;
            QuaternionD current = QuaternionD.CreateFromRotationMatrix(orientation);

            Vector3D targetDirection;
            QuaternionD target;
            if (m_currentInfo.IsValid())
            {
                targetDirection = perpDeltaPos;
                targetDirection.Normalize();
                target = QuaternionD.CreateFromForwardUp(targetDirection, -gravity);

                // If directly above or below the target, the target orientation changes very quickly
                isLabile = Math.Abs(Vector3D.Dot(targetDirection, gravity)) < 0.001;
            }
            else
            {
                targetDirection = deltaPos;
                targetDirection.Normalize();
                target = QuaternionD.CreateFromForwardUp(targetDirection, orientation.Up);
            }

            // Rotate to enemy player when strafing
            if (m_automaticBehaviour != null && m_automaticBehaviour.IsActive && m_automaticBehaviour.RotateToPlayer)
            {
                isLabile = false;
                var forwardOrientation = MatrixD.CreateWorld(Vector3D.Zero, (Vector3D)Base6Directions.GetVector(Base6Directions.Direction.Forward), m_upVectors[Base6Directions.Direction.Forward]);
                orientation = forwardOrientation * WorldMatrix.GetOrientation();
                current = QuaternionD.CreateFromRotationMatrix(orientation);

                MatrixD playerWorldTransform;
                if (GetNearestPlayer(out playerWorldTransform, new Vector3(0f, m_automaticBehaviour.PlayerYAxisOffset, 0f)))
                {
                    targetDirection = playerWorldTransform.Translation - WorldMatrix.Translation;
                    targetDirection.Normalize();

                    Vector3D up = playerWorldTransform.Up;
                    up.Normalize();

                    if (Math.Abs(Vector3D.Dot(targetDirection, up)) >= 0.98)
                    {
                        up = Vector3D.CalculatePerpendicularVector(targetDirection);
                    }
                    else
                    {
                        Vector3D right = Vector3D.Cross(targetDirection, up);
                        up = Vector3D.Cross(right, targetDirection);
                    }

                    target = QuaternionD.CreateFromForwardUp(targetDirection, up);
                }

                rotating = false;
            }

            Vector3D velocity = GetAngleVelocity(current, target);
            Vector3D velocityToTarget = velocity * angularVelocity.Dot(ref velocity);

            velocity = Vector3D.Transform(velocity, invWorldRot);
            double angle = System.Math.Acos(MathHelper.Clamp(Vector3D.Dot(targetDirection, orientation.Forward),-1,1));

            TargettingAimDelta = angle;
            if (angle < 0.01)
            {
                rotating = false;
                return;
            }

            rotating = rotating && !RotateBetweenWaypoints;

            Vector3D deceleration = angularVelocity - gyros.GetAngularVelocity(-velocity);
            double timeToStop = (angularVelocity / deceleration).Max();
            double timeToReachTarget = (angle / velocityToTarget.Length()) * angle;
            // TODO: this should be rewritten (no IsNan, IsInfinity)
            if (double.IsNaN(timeToStop) || double.IsInfinity(timeToReachTarget) || timeToReachTarget > timeToStop)
            {
                if (m_dockingModeEnabled)
                {
                    velocity /= 4.0;
                }
                gyros.ControlTorque = velocity;
                gyros.MarkDirty();
            }

            if (m_dockingModeEnabled)
            {
                if (angle > 0.05) return;
            }
            else
            {
                if (angle > 0.25) return;
            }
        }
예제 #50
0
        /// <summary>
        /// 生成曲面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonXBuild_Click(object sender, EventArgs e)
        {
            double attitudeL = this.doubleInputAttitudeLength.Value;
            double shapeR    = this.doubleInputShapeRadium.Value;

            // 生成产状数据集
            double       nx = 0.0, ny = 0.0, nz = 0.0;
            List <Point> sourceAttitudePoints = new List <Point>(this.targetMarkersList.Count * 4);

            foreach (var marker in this.targetMarkersList)
            {
                nx += Math.Sin(marker.MyDip * Math.PI / 180) * Math.Sin(marker.MyAngle * Math.PI / 180)
                      / this.targetMarkersList.Count;
                ny += Math.Cos(marker.MyDip * Math.PI / 180) * Math.Sin(marker.MyAngle * Math.PI / 180)
                      / this.targetMarkersList.Count;
                nz += Math.Cos(marker.MyAngle * Math.PI / 180) / this.targetMarkersList.Count;


                double dx         = -Math.Tan(marker.MyAngle * Math.PI / 180) * Math.Cos(marker.MyDip * Math.PI / 180);
                double dy         = -Math.Tan(marker.MyAngle * Math.PI / 180) * Math.Sin(marker.MyDip * Math.PI / 180);
                Point  northPoint = new Point(
                    marker.X,
                    marker.Y + attitudeL,
                    marker.Z + dy * attitudeL);
                Point southPoint = new Point(
                    marker.X,
                    marker.Y - attitudeL,
                    marker.Z - dy * attitudeL);
                Point eastPoint = new Point(
                    marker.X + attitudeL,
                    marker.Y,
                    marker.Z + dx * attitudeL);
                Point westPoint = new Point(
                    marker.X - attitudeL,
                    marker.Y,
                    marker.Z - dx * attitudeL);

                sourceAttitudePoints.AddRange(new[] { northPoint, southPoint, eastPoint, westPoint });
            }

            Point middlePoint = CurveAlgorithm.MiddlePointOfPoints(this.targetMarkersList);

            // 平均产状平面
            Vector3D n     = new Vector3D(nx, ny, nz);
            var      plane = new MathNet.Spatial.Euclidean.Plane(
                new Point3D(middlePoint.X, middlePoint.Y, middlePoint.Z),
                n.Normalize());

            double a0 = -plane.D / plane.C;
            double a1 = -plane.A / plane.C;
            double a2 = -plane.B / plane.C;

            // 插值点数据集
            List <Point> sourcePoints = new List <Point>(this.targetMarkersList);

            sourcePoints.AddRange(sourceAttitudePoints);

            SurfaceEquation surfaceEquation = new SurfaceEquation(a0, a1, a2, sourcePoints, shapeR);

            // 确定曲面区域
            List <Point> edgePoints = CurveAlgorithm.GetEdgePoints(sourcePoints, this.GridEdgeLength);

            // 区域内插加密点 GeoHelper.InsertPointsInPolygon
            List <Point> pointsList = GeoHelper.InsertPointsInPolygon(edgePoints, this.GridEdgeLength);

            // 生成网格 Triangulations
            Triangulations tris = new Triangulations(pointsList, new List <Point>());

            // 计算插值 SurfaceMesh
            tris.MeshSurface(surfaceEquation);

            // 绘制曲面
            IColor66 fillColor = this.sgworld.Creator.CreateColor(128, 128, 128, 128);
            IColor66 lineColor = this.sgworld.Creator.CreateColor(255, 255, 255, 0);

            var parentGid = GeoHelper.CreateGroup("产状地质曲面", ref this.sgworld);



            Facet facet = new Facet(ref this.sgworld, tris.TsData, "Test", parentGid, lineColor, fillColor);

            // facet.DrawFacet();

            // 保存三角网结果
            TsFile ts = new TsFile(
                tris.TsData,
                "TSurf",
                "M",
                "JGM",
                "Name",
                new List <string>());

            ts.WriteTsFile();
            ts.UpdateTsFile(ref this.db);

            ToastNotification.Show(this, "曲面模型已保存为模型部件", 2500, eToastPosition.MiddleCenter);
        }
예제 #51
0
 protected Vector3D GetSpawnPositionSphereBorder()
 {
     var onSphereOutline =
         new Vector3D(
             EmitterData.StartPosition.Start.X.Lerp(EmitterData.StartPosition.End.X,
                 Randomizer.Current.Get()),
             EmitterData.StartPosition.Start.Y.Lerp(EmitterData.StartPosition.End.Y,
                 Randomizer.Current.Get()),
             EmitterData.StartPosition.Start.Z.Lerp(EmitterData.StartPosition.End.Z,
                 Randomizer.Current.Get()));
     onSphereOutline.Normalize();
     onSphereOutline *= EmitterData.StartPosition.Start.Distance(EmitterData.StartPosition.End) *
         0.5f;
     return Position + onSphereOutline;
 }
예제 #52
0
        private void PlaceAreaMarker()
        {
            Vector3D cameraPos, cameraDir;

            if (MySession.GetCameraControllerEnum() == Common.ObjectBuilders.MyCameraControllerEnum.ThirdPersonSpectator || MySession.GetCameraControllerEnum() == Common.ObjectBuilders.MyCameraControllerEnum.Entity)
            {
                var headMatrix = MySession.ControlledEntity.GetHeadMatrix(true, true);
                cameraPos = headMatrix.Translation;
                cameraDir = headMatrix.Forward;
            }
            else
            {
                cameraPos = MySector.MainCamera.Position;
                cameraDir = MySector.MainCamera.WorldMatrix.Forward;
            }

            List <MyPhysics.HitInfo> hitInfos = new List <MyPhysics.HitInfo>();

            MyPhysics.CastRay(cameraPos, cameraPos + cameraDir * 100, hitInfos, MyPhysics.ObjectDetectionCollisionLayer);
            if (hitInfos.Count == 0)
            {
                return;
            }

            MyPhysics.HitInfo?closestValidHit = null;
            foreach (var hitInfo in hitInfos)
            {
                var ent = hitInfo.HkHitInfo.Body.GetEntity();
                if (ent is MyCubeGrid)
                {
                    closestValidHit = hitInfo;
                    break;
                }
                else if (ent is MyVoxelMap)
                {
                    closestValidHit = hitInfo;
                    break;
                }
            }

            if (closestValidHit.HasValue)
            {
                Vector3D position = closestValidHit.Value.Position;
                MyAreaMarkerDefinition definition = AreaMarkerDefinition;
                //MyDefinitionManager.Static.TryGetDefinition(new MyDefinitionId(typeof(MyObjectBuilder_AreaMarkerDefinition), "ForestingArea"), out definition);

                m_tmpAreas.Clear();
                MyPlaceAreas.GetAllAreas(m_tmpAreas);

                foreach (var area in m_tmpAreas)
                {
                    if (area.AreaType == AreaMarkerDefinition.Id.SubtypeId)
                    {
                        area.Entity.Close();
                    }
                }
                m_tmpAreas.Clear();

                Debug.Assert(definition != null, "Area marker definition cannot be null!");
                if (definition == null)
                {
                    return;
                }

                var forward = Vector3D.Reject(cameraDir, Vector3D.Up);

                if (Vector3D.IsZero(forward))
                {
                    forward = Vector3D.Forward;
                }

                var flag = new MyAreaMarker(new MyPositionAndOrientation(position, Vector3D.Normalize(forward), Vector3D.Up), definition);

                MyEntities.Add(flag);
            }
        }
예제 #53
0
 bool IMyPrefabManager.IsPathClear(Vector3D from, Vector3D to, double halfSize)
 {
     Vector3D other=new Vector3D();
     other.X=1;
     Vector3D forward=to-from;
     forward.Normalize();
     if (Vector3D.Dot(forward,other)>0.9f || Vector3D.Dot(forward,other)<-0.9f)
     {
         other.X = 0;
         other.Y = 1;
     }
     other=Vector3D.Cross(forward,other);
     other.Normalize();
     other = other * halfSize;
     //first
     MyPhysics.CastRay(from+other, to+other, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
     if (m_raycastHits.Count > 0)
     {
         m_raycastHits.Clear();
         return false;
     }
     //second
     other *= -1;
     MyPhysics.CastRay(from + other, to + other, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
     if (m_raycastHits.Count > 0)
     {
         m_raycastHits.Clear();
         return false;
     }
     //third
     other = Vector3D.Cross(forward, other);
     MyPhysics.CastRay(from + other, to + other, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
     if (m_raycastHits.Count > 0)
     {
         m_raycastHits.Clear();
         return false;
     }
     //fourth
     other *= -1;
     MyPhysics.CastRay(from + other, to + other, m_raycastHits, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
     if (m_raycastHits.Count > 0)
     {
         m_raycastHits.Clear();
         return false;
     }
     return true;
 }
예제 #54
0
        internal void Start()
        {
            PrevVelocity = Vector3D.Zero;
            OffsetDir    = Vector3D.Zero;
            Position     = Info.Origin;
            AccelDir     = Info.Direction;
            var cameraStart = Info.System.Session.CameraPos;

            Vector3D.DistanceSquared(ref cameraStart, ref Info.Origin, out DistanceFromCameraSqr);
            GenerateShrapnel = Info.AmmoDef.Const.ShrapnelId > -1;
            var probability = Info.AmmoDef.AmmoGraphics.VisualProbability;

            EnableAv                  = !Info.AmmoDef.Const.VirtualBeams && !Info.System.Session.DedicatedServer && DistanceFromCameraSqr <= Info.System.Session.SyncDistSqr && (probability >= 1 || probability >= MyUtils.GetRandomDouble(0.0f, 1f));
            ModelState                = EntityState.None;
            LastEntityPos             = Position;
            LastHitEntVel             = null;
            Info.AvShot               = null;
            Info.Age                  = -1;
            ChaseAge                  = 0;
            NewTargets                = 0;
            ZombieLifeTime            = 0;
            LastOffsetTime            = 0;
            PruningProxyId            = -1;
            EntitiesNear              = false;
            CachedPlanetHit           = false;
            PositionChecked           = false;
            MineSeeking               = false;
            MineActivated             = false;
            MineTriggered             = false;
            LinePlanetCheck           = false;
            AtMaxRange                = false;
            FakeGravityNear           = false;
            HadTarget                 = false;
            WasTracking               = false;
            Intersecting              = false;
            ASleep                    = false;
            EndStep                   = 0;
            Info.PrevDistanceTraveled = 0;
            Info.DistanceTraveled     = 0;
            PrevEndPointToCenterSqr   = double.MaxValue;


            CachedId        = Info.MuzzleId == -1 ? Info.WeaponCache.VirutalId : Info.MuzzleId;
            DynamicGuidance = Info.AmmoDef.Trajectory.Guidance != GuidanceType.None && Info.AmmoDef.Trajectory.Guidance != GuidanceType.TravelTo && !Info.AmmoDef.Const.IsBeamWeapon && Info.EnableGuidance;
            if (DynamicGuidance)
            {
                DynTrees.RegisterProjectile(this);
            }
            FeelsGravity = Info.AmmoDef.Const.FeelsGravity;

            Info.MyPlanet = Info.Ai.MyPlanet;
            if (!Info.System.Session.VoxelCaches.TryGetValue(Info.UniqueMuzzleId, out Info.VoxelCache))
            {
                Log.Line($"ProjectileStart VoxelCache Failure with Id:{Info.UniqueMuzzleId} BlockMarked:{Info.Target.FiringCube?.MarkedForClose}, setting to default cache:");
                Info.VoxelCache = Info.System.Session.VoxelCaches[ulong.MaxValue];
            }
            if (Info.MyPlanet != null)
            {
                Info.VoxelCache.PlanetSphere.Center = Info.Ai.ClosestPlanetCenter;
            }

            Info.MyShield            = Info.Ai.MyShield;
            Info.InPlanetGravity     = Info.Ai.InPlanetGravity;
            Info.AiVersion           = Info.Ai.Version;
            Info.Ai.ProjectileTicker = Info.Ai.Session.Tick;

            if (Info.AmmoDef.Trajectory.Guidance == GuidanceType.Smart && DynamicGuidance)
            {
                SmartsOn     = true;
                MaxChaseTime = Info.AmmoDef.Const.MaxChaseTime;
                SmartSlot    = Info.WeaponRng.ClientProjectileRandom.Next(10);
                Info.WeaponRng.ClientProjectileCurrentCounter++;
            }
            else
            {
                MaxChaseTime = int.MaxValue;
                SmartsOn     = false;
                SmartSlot    = 0;
            }

            if (Info.Target.IsProjectile)
            {
                OriginTargetPos = Info.Target.Projectile.Position;
                Info.Target.Projectile.Seekers.Add(this);
            }
            else if (Info.Target.Entity != null)
            {
                OriginTargetPos = Info.Target.Entity.PositionComp.WorldAABB.Center;
            }
            else
            {
                OriginTargetPos = Vector3D.Zero;
            }
            LockedTarget = !Vector3D.IsZero(OriginTargetPos);

            if (SmartsOn && Info.AmmoDef.Const.TargetOffSet && (LockedTarget || Info.Target.IsFakeTarget))
            {
                OffSetTarget();
                OffsetSqr = Info.AmmoDef.Trajectory.Smarts.Inaccuracy * Info.AmmoDef.Trajectory.Smarts.Inaccuracy;
            }
            else
            {
                TargetOffSet = Vector3D.Zero;
                OffsetSqr    = 0;
            }
            PrevTargetOffset = Vector3D.Zero;

            var targetSpeed = (float)(!Info.AmmoDef.Const.IsBeamWeapon ? Info.AmmoDef.Trajectory.DesiredSpeed : Info.MaxTrajectory * MyEngineConstants.UPDATE_STEPS_PER_SECOND);

            if (Info.AmmoDef.Const.SpeedVariance && !Info.AmmoDef.Const.IsBeamWeapon)
            {
                var min           = Info.AmmoDef.Trajectory.SpeedVariance.Start;
                var max           = Info.AmmoDef.Trajectory.SpeedVariance.End;
                var speedVariance = (float)Info.WeaponRng.ClientProjectileRandom.NextDouble() * (max - min) + min;
                Info.WeaponRng.ClientProjectileCurrentCounter++;
                DesiredSpeed = targetSpeed + speedVariance;
            }
            else
            {
                DesiredSpeed = targetSpeed;
            }

            float variance = 0;

            if (Info.AmmoDef.Const.RangeVariance)
            {
                var min = Info.AmmoDef.Trajectory.RangeVariance.Start;
                var max = Info.AmmoDef.Trajectory.RangeVariance.End;
                variance            = (float)Info.WeaponRng.ClientProjectileRandom.NextDouble() * (max - min) + min;
                Info.MaxTrajectory -= variance;
                Info.WeaponRng.ClientProjectileCurrentCounter++;
            }

            if (Vector3D.IsZero(PredictedTargetPos))
            {
                PredictedTargetPos = Position + (AccelDir * Info.MaxTrajectory);
            }
            PrevTargetPos       = PredictedTargetPos;
            PrevTargetVel       = Vector3D.Zero;
            Info.ObjectsHit     = 0;
            Info.BaseHealthPool = Info.AmmoDef.Health;
            Info.BaseEwarPool   = Info.AmmoDef.Health;
            Info.TracerLength   = Info.AmmoDef.Const.TracerLength <= Info.MaxTrajectory ? Info.AmmoDef.Const.TracerLength : Info.MaxTrajectory;

            MaxTrajectorySqr = Info.MaxTrajectory * Info.MaxTrajectory;

            if (!Info.IsShrapnel)
            {
                StartSpeed = Info.ShooterVel;
            }

            MoveToAndActivate = LockedTarget && !Info.AmmoDef.Const.IsBeamWeapon && Info.AmmoDef.Trajectory.Guidance == GuidanceType.TravelTo;

            if (MoveToAndActivate)
            {
                var distancePos = !Vector3D.IsZero(PredictedTargetPos) ? PredictedTargetPos : OriginTargetPos;
                if (!MyUtils.IsZero(variance))
                {
                    distancePos -= (AccelDir * variance);
                }
                Vector3D.DistanceSquared(ref Info.Origin, ref distancePos, out DistanceToTravelSqr);
            }
            else
            {
                DistanceToTravelSqr = MaxTrajectorySqr;
            }

            PickTarget = Info.AmmoDef.Trajectory.Smarts.OverideTarget && !Info.Target.IsFakeTarget && !Info.LockOnFireState;
            if (PickTarget || LockedTarget)
            {
                NewTargets++;
            }

            var staticIsInRange  = Info.Ai.ClosestStaticSqr * 0.5 < MaxTrajectorySqr;
            var pruneStaticCheck = Info.Ai.ClosestPlanetSqr * 0.5 < MaxTrajectorySqr || Info.Ai.StaticGridInRange;

            PruneQuery = (DynamicGuidance && pruneStaticCheck) || FeelsGravity && staticIsInRange || !DynamicGuidance && !FeelsGravity && staticIsInRange ? MyEntityQueryType.Both : MyEntityQueryType.Dynamic;

            if (Info.Ai.PlanetSurfaceInRange && Info.Ai.ClosestPlanetSqr <= MaxTrajectorySqr)
            {
                LinePlanetCheck = true;
                PruneQuery      = MyEntityQueryType.Both;
            }

            if (DynamicGuidance && PruneQuery == MyEntityQueryType.Dynamic && staticIsInRange)
            {
                CheckForNearVoxel(60);
            }

            var accelPerSec = Info.AmmoDef.Trajectory.AccelPerSec;

            ConstantSpeed       = accelPerSec <= 0;
            AccelInMetersPerSec = accelPerSec > 0 ? accelPerSec : DesiredSpeed;
            var desiredSpeed     = (AccelDir * DesiredSpeed);
            var relativeSpeedCap = StartSpeed + desiredSpeed;

            MaxVelocity          = relativeSpeedCap;
            MaxSpeed             = MaxVelocity.Length();
            MaxSpeedSqr          = MaxSpeed * MaxSpeed;
            DeltaVelocityPerTick = accelPerSec * StepConst;
            AccelVelocity        = (AccelDir * DeltaVelocityPerTick);

            if (ConstantSpeed)
            {
                Velocity          = MaxVelocity;
                VelocityLengthSqr = MaxSpeed * MaxSpeed;
            }
            else
            {
                Velocity = StartSpeed + AccelVelocity;
            }

            if (Info.IsShrapnel)
            {
                Vector3D.Normalize(ref Velocity, out Info.Direction);
            }

            InitalStep = !Info.IsShrapnel && ConstantSpeed ? desiredSpeed * StepConst : Velocity * StepConst;

            TravelMagnitude = Velocity * StepConst;
            FieldTime       = Info.AmmoDef.Const.Ewar || Info.AmmoDef.Const.IsMine ? Info.AmmoDef.Trajectory.FieldTime : 0;
            State           = !Info.AmmoDef.Const.IsBeamWeapon ? ProjectileState.Alive : ProjectileState.OneAndDone;

            if (EnableAv)
            {
                var originDir = !Info.IsShrapnel ? AccelDir : Info.Direction;
                Info.AvShot = Info.System.Session.Av.AvShotPool.Get();
                Info.AvShot.Init(Info, SmartsOn, AccelInMetersPerSec * StepConst, MaxSpeed, ref originDir);
                Info.AvShot.SetupSounds(DistanceFromCameraSqr); //Pool initted sounds per Projectile type... this is expensive
                if (Info.AmmoDef.Const.HitParticle && !Info.AmmoDef.Const.IsBeamWeapon || Info.AmmoDef.Const.AreaEffect == AreaEffectType.Explosive && !Info.AmmoDef.AreaEffect.Explosions.NoVisuals && Info.AmmoDef.Const.AreaEffectSize > 0 && Info.AmmoDef.Const.AreaEffectDamage > 0)
                {
                    var hitPlayChance = Info.AmmoDef.AmmoGraphics.Particles.Hit.Extras.HitPlayChance;
                    Info.AvShot.HitParticleActive = hitPlayChance >= 1 || hitPlayChance >= MyUtils.GetRandomDouble(0.0f, 1f);
                }
                Info.AvShot.FakeExplosion = Info.AvShot.HitParticleActive && Info.AmmoDef.Const.AreaEffect == AreaEffectType.Explosive && Info.AmmoDef.AmmoGraphics.Particles.Hit.Name == string.Empty;
            }

            if (!Info.AmmoDef.Const.PrimeModel && !Info.AmmoDef.Const.TriggerModel)
            {
                ModelState = EntityState.None;
            }
            else
            {
                if (EnableAv)
                {
                    ModelState = EntityState.Exists;

                    double triggerModelSize = 0;
                    double primeModelSize   = 0;
                    if (Info.AmmoDef.Const.TriggerModel)
                    {
                        triggerModelSize = Info.AvShot.TriggerEntity.PositionComp.WorldVolume.Radius;
                    }
                    if (Info.AmmoDef.Const.PrimeModel)
                    {
                        primeModelSize = Info.AvShot.PrimeEntity.PositionComp.WorldVolume.Radius;
                    }
                    var largestSize = triggerModelSize > primeModelSize ? triggerModelSize : primeModelSize;

                    Info.AvShot.ModelSphereCurrent.Radius = largestSize * 2;
                }
            }

            if (EnableAv)
            {
                LineOrNotModel        = Info.AmmoDef.Const.DrawLine || ModelState == EntityState.None && Info.AmmoDef.Const.AmmoParticle;
                Info.AvShot.ModelOnly = !LineOrNotModel && ModelState == EntityState.Exists;
            }
        }
예제 #55
0
		private static Matrix CalcRotateMatrixFromOrthogonalBasis(Vector3D xAxis, Vector3D yAxis, Vector3D zAxis)
		{
			const float zeroTolerance = 1e-4f;
			Platform.CheckForNullReference(xAxis, "xAxis");
			Platform.CheckForNullReference(yAxis, "yAxis");
			Platform.CheckForNullReference(zAxis, "zAxis");
			Platform.CheckFalse(xAxis.IsNull || yAxis.IsNull || zAxis.IsNull, "Input must be an orthogonal set of basis vectors (i.e. non-trivial vectors).");
			Platform.CheckTrue(FloatComparer.AreEqual(xAxis.Dot(yAxis), 0, zeroTolerance)
			                   && FloatComparer.AreEqual(xAxis.Dot(zAxis), 0, zeroTolerance)
			                   && FloatComparer.AreEqual(yAxis.Dot(zAxis), 0, zeroTolerance), "Input must be an orthogonal set of basis vectors (i.e. mutually perpendicular).");

			xAxis = xAxis.Normalize();
			yAxis = yAxis.Normalize();
			zAxis = zAxis.Normalize();

			//TODO (CR Sept 2010): is this a rotation matrix, or the definition of a coordinate system?
			var basis = new Matrix(4, 4);
			basis.SetRow(0, xAxis.X, xAxis.Y, xAxis.Z, 0);
			basis.SetRow(1, yAxis.X, yAxis.Y, yAxis.Z, 0);
			basis.SetRow(2, zAxis.X, zAxis.Y, zAxis.Z, 0);
			basis.SetRow(3, 0, 0, 0, 1);
			return basis;
		}
예제 #56
0
        internal void ActivateMine()
        {
            var ent = Info.Target.Entity;

            MineActivated = true;
            AtMaxRange    = false;
            var targetPos       = ent.PositionComp.WorldAABB.Center;
            var deltaPos        = targetPos - Position;
            var targetVel       = ent.Physics?.LinearVelocity ?? Vector3.Zero;
            var deltaVel        = targetVel - Vector3.Zero;
            var timeToIntercept = MathFuncs.Intercept(deltaPos, deltaVel, DesiredSpeed);
            var predictedPos    = targetPos + (float)timeToIntercept * deltaVel;

            PredictedTargetPos = predictedPos;
            PrevTargetPos      = predictedPos;
            PrevTargetVel      = targetVel;
            LockedTarget       = true;

            if (Info.AmmoDef.Trajectory.Guidance == GuidanceType.DetectFixed)
            {
                return;
            }
            Vector3D.DistanceSquared(ref Info.Origin, ref predictedPos, out DistanceToTravelSqr);
            Info.DistanceTraveled     = 0;
            Info.PrevDistanceTraveled = 0;

            Info.Direction    = Vector3D.Normalize(predictedPos - Position);
            AccelDir          = Info.Direction;
            VelocityLengthSqr = 0;

            MaxVelocity   = (Info.Direction * DesiredSpeed);
            MaxSpeed      = MaxVelocity.Length();
            MaxSpeedSqr   = MaxSpeed * MaxSpeed;
            AccelVelocity = (Info.Direction * DeltaVelocityPerTick);

            if (ConstantSpeed)
            {
                Velocity          = MaxVelocity;
                VelocityLengthSqr = MaxSpeed * MaxSpeed;
            }
            else
            {
                Velocity = AccelVelocity;
            }

            if (Info.AmmoDef.Trajectory.Guidance == GuidanceType.DetectSmart)
            {
                SmartsOn     = true;
                MaxChaseTime = Info.AmmoDef.Const.MaxChaseTime;

                if (SmartsOn && Info.AmmoDef.Const.TargetOffSet && LockedTarget)
                {
                    OffSetTarget();
                    OffsetSqr = Info.AmmoDef.Trajectory.Smarts.Inaccuracy * Info.AmmoDef.Trajectory.Smarts.Inaccuracy;
                }
                else
                {
                    TargetOffSet = Vector3D.Zero;
                    OffsetSqr    = 0;
                }
            }

            TravelMagnitude = Velocity * StepConst;
        }
예제 #57
0
 public void CentricSurfaceNormal()
 {
     Vector3D v = new Vector3D(1, 2, 3);
     Assert.AreEqual(v.Normalize(), Ellipsoid.CentricSurfaceNormal(v));
 }
예제 #58
0
        internal void RunSmart()
        {
            Vector3D newVel;

            if (DeltaVelocityPerTick <= 0 || Vector3D.DistanceSquared(Info.Origin, Position) >= Info.AmmoDef.Const.SmartsDelayDistSqr)
            {
                var fake            = Info.Target.IsFakeTarget;
                var gaveUpChase     = !fake && Info.Age - ChaseAge > MaxChaseTime && HadTarget;
                var validTarget     = fake || Info.Target.IsProjectile || Info.Target.Entity != null && !Info.Target.Entity.MarkedForClose;
                var isZombie        = Info.AmmoDef.Const.CanZombie && HadTarget && !fake && !validTarget && ZombieLifeTime > 0 && (ZombieLifeTime + SmartSlot) % 30 == 0;
                var seekFirstTarget = !HadTarget && !validTarget && Info.Age > 120 && (Info.Age + SmartSlot) % 30 == 0;

                if ((PickTarget && (Info.Age + SmartSlot) % 30 == 0 || gaveUpChase && validTarget || isZombie || seekFirstTarget) && NewTarget() || validTarget)
                {
                    HadTarget = true;
                    if (ZombieLifeTime > 0)
                    {
                        ZombieLifeTime = 0;
                        OffSetTarget();
                    }
                    var targetPos = Vector3D.Zero;

                    FakeWorldTargetInfo fakeTargetInfo = null;
                    if (fake && Info.DummyTargets != null)
                    {
                        var fakeTarget = Info.DummyTargets.PaintedTarget.EntityId != 0 && !Info.DummyTargets.PaintedTarget.Dirty ? Info.DummyTargets.PaintedTarget : Info.DummyTargets.ManualTarget;
                        fakeTargetInfo = fakeTarget.LastInfoTick != Info.System.Session.Tick ? fakeTarget.GetFakeTargetInfo(Info.Ai) : fakeTarget.FakeInfo;
                        targetPos      = fakeTargetInfo.WorldPosition;
                    }
                    else if (Info.Target.IsProjectile)
                    {
                        targetPos = Info.Target.Projectile.Position;
                    }
                    else if (Info.Target.Entity != null)
                    {
                        targetPos = Info.Target.Entity.PositionComp.WorldAABB.Center;
                    }

                    if (Info.AmmoDef.Const.TargetOffSet && WasTracking)
                    {
                        if (Info.Age - LastOffsetTime > 300)
                        {
                            double dist;
                            Vector3D.DistanceSquared(ref Position, ref targetPos, out dist);
                            if (dist < OffsetSqr + VelocityLengthSqr && Vector3.Dot(Info.Direction, Position - targetPos) > 0)
                            {
                                OffSetTarget();
                            }
                        }
                        targetPos += TargetOffSet;
                    }

                    PredictedTargetPos = targetPos;

                    var physics = Info.Target.Entity?.Physics ?? Info.Target.Entity?.Parent?.Physics;
                    if (!(Info.Target.IsProjectile || fake) && (physics == null || Vector3D.IsZero(targetPos)))
                    {
                        PrevTargetPos = PredictedTargetPos;
                    }
                    else
                    {
                        PrevTargetPos = targetPos;
                    }

                    var tVel = Vector3.Zero;
                    if (fake && fakeTargetInfo != null)
                    {
                        tVel = fakeTargetInfo.LinearVelocity;
                    }
                    else if (Info.Target.IsProjectile)
                    {
                        tVel = Info.Target.Projectile.Velocity;
                    }
                    else if (physics != null)
                    {
                        tVel = physics.LinearVelocity;
                    }
                    if (Info.AmmoDef.Const.TargetLossDegree > 0 && Vector3D.DistanceSquared(Info.Origin, Position) >= Info.AmmoDef.Const.SmartsDelayDistSqr)
                    {
                        if (WasTracking && (Info.System.Session.Tick20 || Vector3.Dot(Info.Direction, Position - targetPos) > 0) || !WasTracking)
                        {
                            var targetDir = -Info.Direction;
                            var refDir    = Vector3D.Normalize(Position - targetPos);
                            if (!MathFuncs.IsDotProductWithinTolerance(ref targetDir, ref refDir, Info.AmmoDef.Const.TargetLossDegree))
                            {
                                if (WasTracking)
                                {
                                    PickTarget = true;
                                }
                            }
                            else if (!WasTracking)
                            {
                                WasTracking = true;
                            }
                        }
                    }

                    PrevTargetVel = tVel;
                }
                else
                {
                    var roam = Info.AmmoDef.Trajectory.Smarts.Roam;
                    PrevTargetPos = roam ? PredictedTargetPos : Position + (Info.Direction * Info.MaxTrajectory);

                    if (ZombieLifeTime++ > Info.AmmoDef.Const.TargetLossTime && !Info.AmmoDef.Trajectory.Smarts.KeepAliveAfterTargetLoss && (Info.AmmoDef.Trajectory.Smarts.NoTargetExpire || HadTarget))
                    {
                        DistanceToTravelSqr = Info.DistanceTraveled * Info.DistanceTraveled;
                        EarlyEnd            = true;
                    }

                    if (roam && Info.Age - LastOffsetTime > 300 && HadTarget)
                    {
                        double dist;
                        Vector3D.DistanceSquared(ref Position, ref PrevTargetPos, out dist);
                        if (dist < OffsetSqr + VelocityLengthSqr && Vector3.Dot(Info.Direction, Position - PrevTargetPos) > 0)
                        {
                            OffSetTarget(true);
                            PrevTargetPos     += TargetOffSet;
                            PredictedTargetPos = PrevTargetPos;
                        }
                    }
                    else if (MineSeeking)
                    {
                        ResetMine();
                        return;
                    }
                }

                var missileToTarget           = Vector3D.Normalize(PrevTargetPos - Position);
                var relativeVelocity          = PrevTargetVel - Velocity;
                var normalMissileAcceleration = (relativeVelocity - (relativeVelocity.Dot(missileToTarget) * missileToTarget)) * Info.AmmoDef.Trajectory.Smarts.Aggressiveness;

                Vector3D commandedAccel;
                if (Vector3D.IsZero(normalMissileAcceleration))
                {
                    commandedAccel = (missileToTarget * AccelInMetersPerSec);
                }
                else
                {
                    var maxLateralThrust = AccelInMetersPerSec * Math.Min(1, Math.Max(0, Info.AmmoDef.Const.MaxLateralThrust));
                    if (normalMissileAcceleration.LengthSquared() > maxLateralThrust * maxLateralThrust)
                    {
                        Vector3D.Normalize(ref normalMissileAcceleration, out normalMissileAcceleration);
                        normalMissileAcceleration *= maxLateralThrust;
                    }
                    commandedAccel = Math.Sqrt(Math.Max(0, AccelInMetersPerSec * AccelInMetersPerSec - normalMissileAcceleration.LengthSquared())) * missileToTarget + normalMissileAcceleration;
                }

                var offsetTime = Info.AmmoDef.Trajectory.Smarts.OffsetTime;
                if (offsetTime > 0)
                {
                    if ((Info.Age % offsetTime == 0))
                    {
                        double angle = Info.WeaponRng.ClientProjectileRandom.NextDouble() * MathHelper.TwoPi;
                        Info.WeaponRng.ClientProjectileCurrentCounter += 1;
                        var up    = Vector3D.CalculatePerpendicularVector(Info.Direction);
                        var right = Vector3D.Cross(Info.Direction, up);
                        OffsetDir  = Math.Sin(angle) * up + Math.Cos(angle) * right;
                        OffsetDir *= Info.AmmoDef.Trajectory.Smarts.OffsetRatio;
                    }

                    commandedAccel += AccelInMetersPerSec * OffsetDir;
                    commandedAccel  = Vector3D.Normalize(commandedAccel) * AccelInMetersPerSec;
                }

                newVel = Velocity + (commandedAccel * StepConst);
                var accelDir = commandedAccel / AccelInMetersPerSec;

                AccelDir = accelDir;

                Vector3D.Normalize(ref newVel, out Info.Direction);
            }
            else
            {
                newVel = Velocity += (Info.Direction * DeltaVelocityPerTick);
            }
            VelocityLengthSqr = newVel.LengthSquared();

            if (VelocityLengthSqr > MaxSpeedSqr)
            {
                newVel = Info.Direction * MaxSpeed;
            }
            Velocity = newVel;
        }
예제 #59
0
 /// <summary>
 /// Return the normal of the great circle defined by the two vectors. 
 /// Return false if we fail to get the normal (happens if p1 = p2).
 /// </summary>
 static bool GetGCNormal( Vector3D p1, Vector3D p2, out Vector3D normal )
 {
     normal = p1.Cross( p2 );
     if( !normal.Normalize() )
     {
         normal = Vector3D.DneVector();
         return false;
     }
     return true;
 }
예제 #60
0
        private void ComputeGravityAlignedOrientation(out MatrixD resultOrientationStorage)
        {
            // Y axis
            bool     inGravityField = true;
            Vector3D upVector       = -MyGravityProviderSystem.CalculateTotalGravityInPoint(Position);

            if (upVector.LengthSquared() < MyMathConstants.EPSILON)
            {
                upVector = m_lastUpVec;
                m_lastOrientationWeight = 1;
                inGravityField          = false;
            }
            else
            {
                m_lastUpVec = upVector;
            }
            upVector.Normalize();
            // X axis
            Vector3D rightVector = m_lastRightVec - Vector3D.Dot(m_lastRightVec, upVector) * upVector;

            if (rightVector.LengthSquared() < MyMathConstants.EPSILON)
            {
                rightVector = m_orientation.Right - Vector3D.Dot(m_orientation.Right, upVector) * upVector;
                // backup behavior if singularity happens
                if (rightVector.LengthSquared() < MyMathConstants.EPSILON)
                {
                    rightVector = m_orientation.Forward - Vector3D.Dot(m_orientation.Forward, upVector) * upVector;
                }
                // backup behavior if singularity happens
            }
            rightVector.Normalize();
            m_lastRightVec = rightVector;
            // Z axis
            Vector3D forwardVector;

            Vector3D.Cross(ref upVector, ref rightVector, out forwardVector);

            resultOrientationStorage         = MatrixD.Identity;
            resultOrientationStorage.Right   = rightVector;
            resultOrientationStorage.Up      = upVector;
            resultOrientationStorage.Forward = forwardVector;
            resultOrientationStorage         = MatrixD.CreateFromAxisAngle(Vector3D.Right, m_pitch) * resultOrientationStorage *
                                               MatrixD.CreateFromAxisAngle(upVector, m_yaw);
            upVector    = resultOrientationStorage.Up;
            rightVector = resultOrientationStorage.Right;
            resultOrientationStorage.Right = Math.Cos(m_roll) * rightVector + Math.Sin(m_roll) * upVector;
            resultOrientationStorage.Up    = -Math.Sin(m_roll) * rightVector + Math.Cos(m_roll) * upVector;

            if (inGravityField && m_lastOrientationWeight > 0)
            {
                m_lastOrientationWeight = Math.Max(0, m_lastOrientationWeight - MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS);

                resultOrientationStorage = MatrixD.Slerp(resultOrientationStorage, m_lastOrientation,
                                                         MathHelper.SmoothStepStable(m_lastOrientationWeight));
                resultOrientationStorage         = MatrixD.Orthogonalize(resultOrientationStorage);
                resultOrientationStorage.Forward = Vector3D.Cross(resultOrientationStorage.Up, resultOrientationStorage.Right);
            }
            if (!inGravityField)
            {
                m_lastOrientation = resultOrientationStorage;
            }
        }