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); }
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; } }
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"); }
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; }
// 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(); }
/// <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; }
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)); }
public IfcDirection(DatabaseIfc db, Vector3D v) : base(db) { UnitVector3D unit = v.Normalize(); mDirectionRatioX = unit.X; mDirectionRatioY = unit.Y; mDirectionRatioZ = unit.Z; }
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; }
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; }
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; }
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); }
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; }
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); } }
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; } } } }
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(); }
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; } }
} // 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()
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); } }
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(); }
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); } }
/// <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); } }
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); }
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); }
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]); } }
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; } }
/// <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); } } } }
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; } } }
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; } }
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); }
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); } } }
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; } }
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(); }
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; }
/// <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); } } }
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); }
//-------------------------------------------------------------------------------- /// <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(); }
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(); }
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(); }
public void Normalize() { Vector3D v = new Vector3D(3.0, -1.0, 23.0); v.Normalize(); Assert.IsTrue(v.IsNumericallyNormalized); }
public UnitVector3D Normalize() { return(V1.Normalize()); }
/** * <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); }
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(); }
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); }
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); }
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; } }
/// <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); }
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; }
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); } }
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; }
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; } }
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; }
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; }
public void CentricSurfaceNormal() { Vector3D v = new Vector3D(1, 2, 3); Assert.AreEqual(v.Normalize(), Ellipsoid.CentricSurfaceNormal(v)); }
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; }
/// <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; }
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; } }