public MyIntersectionResultLineTriangleEx? Intersect() { float maxDist = 200; MyLine line = new MyLine(MyCamera.Position, MyCamera.Position + MyCamera.ForwardVector * maxDist); var result = MyEntities.GetIntersectionWithLine(ref line, MySession.PlayerShip, null, true, true, false, false, true); return result; }
public MyCuboidSide() { Lines[0] = new MyLine(); Lines[1] = new MyLine(); Lines[2] = new MyLine(); Lines[3] = new MyLine(); }
public void Start(MyModel model, MyLine line, IntersectionFlags flags = IntersectionFlags.DIRECT_TRIANGLES) { result = null; m_model = model; m_line = line; m_flags = flags; }
public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, ref MyLine line, ref Matrix customInvMatrix, IntersectionFlags flags) { MyLine lineInModelSpace = new MyLine(MyUtils.GetTransform(line.From, ref customInvMatrix), MyUtils.GetTransform(line.To, ref customInvMatrix), true); MyIntersectionResultLineTriangleEx? ret = m_rootNode.GetIntersectionWithLine(physObject, m_model, ref lineInModelSpace, null, flags); return ret; }
public void DoWork() { var glare = m_glare; // we copy variable because other thread can null it if (glare == null) return; if (Vector3.DistanceSquared(glare.Position, m_cameraPosition) < MyMwcMathConstants.EPSILON) return; var directLine = new MyLine(glare.Position, m_cameraPosition); m_helperCollection.Clear(); using (MyEntities.EntityCloseLock.AcquireSharedUsing()) { var intersectionResult = MyEntities.GetIntersectionWithLine(ref directLine, m_ignoreEntity1, m_ignoreEntity2, false, false, false, false, true); //var intersectionResult = MyRender.GetAnyIntersectionWithLine(ref directLine, m_ignoreEntity1, m_ignoreEntity2, true); if (intersectionResult == null) { if (MySession.PlayerShip == null || MySession.PlayerShip.Weapons == null) { IsDone = true; m_helperCollection.Clear(); return; } MyIntersectionResultLineTriangleEx? cockpitIntersection = GetIntersectionInNearSpace(MySession.PlayerShip.GetShipCockpit(), ref directLine, true); Visible = !cockpitIntersection.HasValue; Debug.Assert(m_helperCollection.Count == 0); m_helperCollection.AddRange(MySession.PlayerShip.Weapons.GetMountedWeaponsWithHarvesterAndDrill()); foreach (var weapon in m_helperCollection) { MyIntersectionResultLineTriangleEx? intersection = GetIntersectionInNearSpace(weapon, ref directLine, true); if (intersection.HasValue) { Visible = false; IsDone = true; m_helperCollection.Clear(); return; } } } else { Visible = false; } IsDone = true; m_ignoreEntity1 = null; m_ignoreEntity2 = null; m_glare = null; } }
// IMPORTANT: Bounding box you are trying to change need to have positive/negative infinite values, so initialize it with InitialBox (static member) static public void AddLine(ref MyLine line, ref BoundingBox bb) { //AddPoint(ref line.From, ref bb); //AddPoint(ref line.To, ref bb); Vector3.Min(ref bb.Min, ref line.From, out bb.Min); Vector3.Max(ref bb.Max, ref line.From, out bb.Max); Vector3.Min(ref bb.Min, ref line.To, out bb.Min); Vector3.Max(ref bb.Max, ref line.To, out bb.Max); }
public void DoWork() { try { MyEntities.EntityCloseLock.AcquireShared(); if (m_entity == null) return; //if (m_entity.EntityId.HasValue && m_entity.EntityId.Value.NumericValue == 119150) // { // } // if (m_entity == MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip) // { // } Vector3 directionToSunNormalized = MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized(); VisibleFromSun = false; MyLine line2 = new MyLine(m_entity.WorldAABB.GetCenter(), m_entity.WorldAABB.GetCenter() + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f, true); var result2 = MyEntities.GetIntersectionWithLine(ref line2, m_entity, null, true, true, true); VisibleFromSun |= IsVisibleFromSun(result2); if (m_entity.RenderObjects != null && m_entity.RenderObjects[0].FastCastShadowResolve) return; Vector3[] corners = new Vector3[8]; m_entity.LocalAABB.GetCorners(corners); for (int i = 0; i < 8; i++) { corners[i] = Vector3.Transform(corners[i], m_entity.WorldMatrix); } for (int i = 0; i < 8; i++) { MyLine line = new MyLine(corners[i], corners[i] + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f, true); var result = MyEntities.GetIntersectionWithLine(ref line, m_entity, null, true, true, true); VisibleFromSun |= IsVisibleFromSun(result); if (VisibleFromSun) break; } } finally { if (m_entity != null) { m_entity.OnClose -= m_entity_OnMarkForClose; } MyEntities.EntityCloseLock.ReleaseShared(); } }
private static bool IsLookAtTarget(MySmallShip smallShip, MyEntity otherEntity) { if (!MUST_LOOK_AT_TARGET || MySession.Is25DSector) { return true; } float length = Vector3.Distance(smallShip.WorldVolume.Center, otherEntity.WorldVolume.Center); MyLine line = new MyLine(smallShip.WorldVolume.Center, smallShip.WorldVolume.Center + smallShip.WorldMatrix.Forward * length * 1.5f, true); MyIntersectionResultLineTriangleEx? result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true); return result != null && result.Value.Entity.GetBaseEntity() == otherEntity; }
public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, ref MyLine line, IntersectionFlags flags) { BoundingSphere vol = physObject.WorldVolume; // Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection' if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol) == false) return null; // Transform line into 'model instance' local/object space. Bounding box of a line is needed!! Matrix worldInv = physObject.GetWorldMatrixInverted(); return GetIntersectionWithLine(physObject, ref line, ref worldInv, flags); }
public static async ValueTask Exec(ITerminal terminal, string fileName, CancellationToken token) { foreach (var MyLine in File.ReadLines(fileName)) { if (MyLine == "" || MyLine.StartsWith("#")) { continue; } await TerminalParser.InternalExecute(terminal, MyLine, token); } }
/// <summary> /// Paints on a WriteableBitmap with a stylized airbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="color">The color of the stroke</param> /// <param name="size">The size of the stroke</param> public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size) { Random r = new Random(); if (bmp == null) return; bmp.Lock(); // Create a line segment representation MyLine line = new MyLine(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox linebounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); linebounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushRadiu); linebounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadiu); linebounds.Clip(bitmapbounds); UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval for (int i = 0; i < AirbrushDots; i++) { int x, y; line.Interpolate(i, AirbrushDots, out x, out y); int dist = r.Next() % size; double angle = r.NextDouble() * 2 * Math.PI; double dx = Math.Cos(angle) * dist; double dy = Math.Sqrt(dist * dist - dx * dx); if (angle > Math.PI) dy = -dy; int bx = x + (int)dx; int by = y + (int)dy; BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushRadiu); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) AlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B)); } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }
public void Move(MyLine lineGridSelectedItem, int movedistance) { Action a = new Move(lineGridSelectedItem, movedistance); a.Step(model); double[] costs = CostCalculationService.CalculateCost(model); actualCost = costs[0]; actualAreaCost = costs[1]; actualLayoutCost = costs[2]; HandleModelChangeUpdate(); }
public override void Load(MyMissionBase sender) { base.Load(sender); m_ship = m_shipId.HasValue ? MyScriptWrapper.GetEntity(m_shipId.Value) : MyScriptWrapper.GetEntity(m_shipName); m_trajectory = new MyLine(m_ship.GetPosition(), MyScriptWrapper.GetEntity(m_targetId).GetPosition()); if (m_isShip) { MyScriptWrapper.PrepareMotherShipForMove(m_ship); } m_shipMoving = true; }
public void Split(int splitPercentage, MyLine lineGridSelectedItem) { Action a = new Split(splitPercentage, lineGridSelectedItem); a.Step(model); double[] costs = CostCalculationService.CalculateCost(model); actualCost = costs[0]; actualAreaCost = costs[1]; actualLayoutCost = costs[2]; HandleModelChangeUpdate(); }
/// <summary> /// Erases paint on a pbgra32 WriteableBitmap /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="size">The stroke size</param> public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) { return; } bmp.Lock(); // Intermediate storage of the square of the size int sizesize = size * size; // Create a line segment representation to compare distance to MyLine linesegment = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size); segmentbounds.AddPoint((int)to.X, (int)to.Y, size); segmentbounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += segmentbounds.Left; // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { Int32 *pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { *pixel = 0; } // Move to the next pixel pixel++; } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
// Difference between GetIntersectionWithLine and GetIntersectionWithLineRecursive is that the later doesn't calculate // final result, but is better suited for recursive nature of octree. Don't call GetIntersectionWithLineRecursive() from // the outisde of this class, it's private method. public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, MyModel model, ref MyLine line, float? minDistanceUntilNow, IntersectionFlags flags) { MyIntersectionResultLineTriangle? foundTriangle = GetIntersectionWithLineRecursive(model, ref line, minDistanceUntilNow); if (foundTriangle != null) { return new MyIntersectionResultLineTriangleEx(foundTriangle.Value, physObject, ref line); } else { return null; } }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; Ray ray = new Ray(line.From, line.Direction); float?ds = ray.Intersects(new BoundingSphere(WorldMatrix.Translation, RadiusMax)); if (ds == null) { return(false); } v = line.From + line.Direction * ds; return(true); }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; Ray ray = new Ray(line.From, line.Direction); float?ds = ray.Intersects(this.WorldAABB); if (ds == null) { return(false); } v = line.From + line.Direction * ds; return(true); }
private bool IsPossibleTarget(MySmallShip smallShip, params object[] args) { if (!IsPotentialTarget(smallShip, args)) { return(false); } MyLine testRay = new MyLine(m_gun.GetBarell().GetPosition(), smallShip.GetPosition(), false); Vector3?result = MyEntities.GetAnyIntersectionWithLine(ref testRay, this, smallShip, true, true, false, true); //smallShip.GetIntersectionWithLine(ref testRay, out result); return(result == null); }
public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; foreach (MyPrefabBase prefab in m_prefabs) { MyEntity entity = prefab as MyEntity; MyIntersectionResultLineTriangleEx?prefabIntersectionResult; entity.GetIntersectionWithLine(ref line, out prefabIntersectionResult); t = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref t, ref prefabIntersectionResult); } return(t != null); }
private static void ComputeMaxDistance(MySunWindBillboardSmall billboard) { Vector3 sunWindVector = m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_HALF; var offset = (-m_directionFromSunNormalized * MySunWindConstants.RAY_CAST_DISTANCE); // This line start where billboard starts and end at place that is farest possible place billboard can reach // If intersection found, we will mark that place as small billboard's destination. It can't go further. MyLine line = new MyLine((sunWindVector + billboard.InitialAbsolutePosition) + offset, billboard.InitialAbsolutePosition + m_directionFromSunNormalized * MySunWindConstants.SUN_WIND_LENGTH_TOTAL, true); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, DoNotIgnoreTheseTypes); billboard.MaxDistance = (intersection != null) ? (intersection.Value.Triangle.Distance - billboard.Radius) : MySunWindConstants.SUN_WIND_LENGTH_TOTAL; }
private void UpdateTargetVisibility(MySmallShipBot bot) { if (locationVisibleCheckTimer <= 0) { MyLine line = new MyLine(bot.GetPosition(), location, true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true); locationVisible = !result.HasValue; locationVisibleCheckTimer = 0.25f; } else { locationVisibleCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } }
/// <summary> /// Returns interstection with line /// </summary> /// <param name="line">Line</param> /// <returns></returns> public MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(ref MyLine line) { MyIntersectionResultLineTriangleEx?result = null; // Test against childs of this phys object (in this case guns) foreach (MyGunBase gun in GetMountedWeaponsWithHarvesterAndDrill()) { MyIntersectionResultLineTriangleEx?intersectionGun; gun.GetIntersectionWithLine(ref line, out intersectionGun); result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref intersectionGun); } return(result); }
public MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(ref MyLine line) { MyIntersectionResultLineTriangleEx?result = null; // Test against childs of this phys object (in this case guns) foreach (MyGunBase gun in m_guns) { MyIntersectionResultLineTriangleEx?intersectionGun = gun.GetIntersectionWithLine(ref line); result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref intersectionGun); } return(result); }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; BoundingBox box = BoundingBox.CreateFromSphere(new BoundingSphere(GetPosition(), m_selectionBox.Size().X)); float? dt = MyUtils.GetLineBoundingBoxIntersection(ref line, ref box); if (dt == null) { return(false); } v = line.From + line.Direction * dt; return(true); }
public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(ref MyLine line) { MyIntersectionResultLineTriangleEx? result = null; // Test against childs of this phys object (in this case guns) foreach (MyGunBase gun in m_guns) { MyIntersectionResultLineTriangleEx? intersectionGun = gun.GetIntersectionWithLine(ref line); result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref intersectionGun); } return result; }
/// <summary> /// Check if the missile does not collide too close to ship /// after shooting and correct its starting position if it does. /// </summary> private Vector3 CorrectPosition(Vector3 position, Vector3 direction, MyEntity viewerEntity) { var predictedTrajectory = new MyLine( position - MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction, position + MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction, false); var intersection = MyEntities.GetIntersectionWithLine(ref predictedTrajectory, this, viewerEntity); if (intersection != null) { position = viewerEntity.GetPosition(); } return(position); }
public void Notify(MyLine line, MyEntity source) { System.Diagnostics.Debug.Assert(source == null || !source.Closed); lineResults.Clear(); m_dangerZoneStructure.OverlapAllLineSegment<MyDangerZoneElement>(ref line, lineResults); foreach (var resultItem in lineResults) { if (source == null || (resultItem.Element.Bot != source && MyFactions.GetFactionsRelation(resultItem.Element.Bot, source) == MyFactionRelationEnum.Enemy)) { resultItem.Element.Bot.AddCuriousLocation(source != null ? source.GetPosition() : line.From, source); } } }
public void IgnorePropertyTest() { MyLine line = new MyLine(); line.Start = new MyImmutablePoint(1, 5); line.End = new MyImmutablePoint(2, 12); Serializer s = new Serializer(typeof(MyLine), "TestIgnoreProperties"); string result = s.Serialize(line); MyLine actual = (MyLine)s.Deserialize(result); Assert.IsNull(actual.Start, "Line start should be ignored"); Assert.IsNull(actual.End, "Line end should be ignored"); // converters should not be called on ignored properties Assert.AreEqual(0, MyLinePointConverter.ConvertFromCount, "Property ConvertFrom not called correct amount of times"); Assert.AreEqual(0, MyLinePointConverter.ConvertToCount, "Property ConvertTo not called correct amount of times"); }
public void Notify(MyLine line, MyEntity source) { System.Diagnostics.Debug.Assert(source == null || !source.Closed); lineResults.Clear(); m_dangerZoneStructure.OverlapAllLineSegment <MyDangerZoneElement>(ref line, lineResults); foreach (var resultItem in lineResults) { if (source == null || (resultItem.Element.Bot != source && MyFactions.GetFactionsRelation(resultItem.Element.Bot, source) == MyFactionRelationEnum.Enemy)) { resultItem.Element.Bot.AddCuriousLocation(source != null ? source.GetPosition() : line.From, source); } } }
public void drawConnections() { MyLine draw = new MyLine(); for (int i = 0; i < nodes.Length - 1; i++) { for (int j = i; j < nodes.Length; j++) { if (adjacency[i][j] == 1) { draw.drawLine(nodes[i].area.center3D, nodes[j].area.center3D, Color.red); } } } }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (m_elapsedMiliseconds > MyIlluminatingShellsConstants.MAX_LIVING_TIME + MyIlluminatingShellsConstants.DIYNG_TIME) { if (m_particleEffect != null) { m_particleEffect.Stop(); m_particleEffect = null; } // Free the light if (m_light != null) { MyLights.RemoveLight(m_light); m_light = null; } MarkForClose(); } // Update light position if (m_light != null) { // Aggro near bots if (m_light.LightOn) { if (this.WorldMatrix.Translation != m_previousPosition) { MyLine line = new MyLine(m_previousPosition, WorldMatrix.Translation); MyDangerZones.Instance.Notify(line, OwnerEntity); } } if ((m_elapsedMiliseconds > MyIlluminatingShellsConstants.MAX_LIVING_TIME) && (m_elapsedMiliseconds < MyIlluminatingShellsConstants.MAX_LIVING_TIME + MyIlluminatingShellsConstants.DIYNG_TIME)) { m_light.LightOn = MyMwcUtils.GetRandomBool(2); m_particleEffect.UserScale = m_light.LightOn ? 1.0f : 0.001f; } m_light.SetPosition(GetPosition()); m_light.Color = MyIlluminatingShellsConstants.LIGHT_COLOR; m_light.Range = MyIlluminatingShellsConstants.LIGHT_RADIUS; } }
public static MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(ref MyLine line) { MyIntersectionResultLineTriangleEx?result = null; // Check all voxel maps for (int value = 0; value < m_voxelMaps.Count; value++) { MyIntersectionResultLineTriangleEx?testResultEx; m_voxelMaps[value].GetIntersectionWithLine(ref line, out testResultEx); // If intersection occured and distance to intersection is closer to origin than any previous intersection) result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref result, ref testResultEx); } return(result); }
private void UpdateTargetVisibility(MySmallShipBot bot) { if (m_target != null && m_visibilityCheckTimer <= 0) { Debug.Assert(!m_target.Closed); MyLine line = new MyLine(bot.GetPosition(), m_target.GetPosition(), true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, m_target, true, ignoreChilds: true); m_targetVisible = !result.HasValue; m_visibilityCheckTimer = 0.25f; } else { m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } }
public MyIntersectionResultLineTriangleEx?GetIntersectionInNearSpace(MyEntity entity, ref MyLine worldLine, bool convertLine) { if (!entity.IsVisible()) { return(null); } MyLine line = worldLine; if (convertLine) { ConvertLineToNearWorldCoordinates(ref line); } Matrix drawMatrix = entity.GetWorldMatrixForDraw(); drawMatrix.Translation += MyCamera.Position; Matrix worldInv = Matrix.Invert(drawMatrix); MyIntersectionResultLineTriangleEx?ret = entity.ModelLod0.GetTrianglePruningStructure().GetIntersectionWithLine(entity, ref line, ref worldInv, IntersectionFlags.ALL_TRIANGLES); if (ret == null) { foreach (MyEntity child in entity.Children) { if (!child.IsVisible()) { continue; } drawMatrix = child.GetWorldMatrixForDraw(); drawMatrix.Translation += MyCamera.Position; worldInv = Matrix.Invert(drawMatrix); System.Diagnostics.Debug.Assert(!float.IsNaN(worldInv.M11)); ret = child.ModelLod0.GetTrianglePruningStructure().GetIntersectionWithLine(child, ref line, ref worldInv, IntersectionFlags.ALL_TRIANGLES); if (ret != null) { return(ret); } } } return(ret); }
public void IgnorePropertyTest() { MyLine line = new MyLine(); line.Start = new MyImmutablePoint(1, 5); line.End = new MyImmutablePoint(2, 12); Serializer s = new Serializer("TestIgnoreProperties"); string result = s.Serialize(line); MyLine actual = s.Deserialize <MyLine>(result); Assert.IsNull(actual.Start, "Line start should be ignored"); Assert.IsNull(actual.End, "Line end should be ignored"); // converters should not be called on ignored properties Assert.AreEqual(0, MyLinePointConverter.ConvertFromCount, "Property ConvertFrom not called correct amount of times"); Assert.AreEqual(0, MyLinePointConverter.ConvertToCount, "Property ConvertTo not called correct amount of times"); }
/// <summary> /// Оновлює модель фігури, при зміні її координат /// </summary> /// <param name="childrens"></param> public void UpdateLines(UIElementCollection childrens) { var index = 0; var element = 0; MyLine line = null; for (int i = 1; i < childrens.Count; i += 2) { var box = childrens[i] as TextBox; if (WorkPanel.Figure.BaseLines.Count >= index && box.IsValid()) { if (element % 2 == 0) { line = WorkPanel.Figure.BaseLines[index]; } if (line != null) { if (box.Name == "X1" && !string.IsNullOrWhiteSpace(box.Text) && decimal.TryParse(box.Text, out decimal value)) { line.X1 = box.Text.Trim(); } else if (box.Name == "X2" && !string.IsNullOrWhiteSpace(box.Text) && decimal.TryParse(box.Text, out value)) { line.X2 = box.Text.Trim(); } else if (box.Name == "Y1" && !string.IsNullOrWhiteSpace(box.Text) && decimal.TryParse(box.Text, out value)) { line.Y1 = box.Text.Trim(); } else if (box.Name == "Y2" && !string.IsNullOrWhiteSpace(box.Text) && decimal.TryParse(box.Text, out value)) { line.Y2 = box.Text.Trim(); } } if (element % 2 != 0) { index++; } element++; } } }
/// <summary> /// Chceck if ship can see target /// </summary> /// <param name="position">Target position</param> /// <param name="target">Target entity.</param> /// <returns>True, if bot can see position.</returns> public static MyEntity CanSee(MyEntity source, Vector3 position, MyEntity ignoreEntity) { MyIntersectionResultLineTriangleEx?result = null; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MySmallShip CanSee"); //There is 100 multiplier because Epsilon can get lost during transformation inside GetAllIntersectionWithLine //and normalization assert then appears if ((source.GetPosition() - position).Length() > MyMwcMathConstants.EPSILON * 100.0f) { var line = new MyLine(source.GetPosition(), position, true); result = MyEntities.GetIntersectionWithLine(ref line, source, ignoreEntity, ignoreChilds: true); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); return(result.HasValue ? result.Value.Entity : null); }
private void CalculateMoveCosts() { //Parallel.For(0, model.modelLines.Count, // index => { for (int index = 0; index < model.modelLines.Count; index++) { MyLine myLine = model.modelLines.ElementAt(index); MyLine newMyLine = null; Model tempModel = model.DeepCopy(myLine, out newMyLine); tempModel.MoveLine(moveDistance, newMyLine); if (tempModel.IsInInvalidState) { continue; } double[] costs = CostCalculationService.CalculateCost(tempModel); double summary = costs[0]; double areacost = costs[1]; double layoutcost = costs[2]; lock (locker) { Actions.Add(new Move(myLine, summary, areacost, layoutcost, moveDistance)); } } //}); //Parallel.For(0, model.modelLines.Count, // index => { for (int index = 0; index < model.modelLines.Count; index++) { MyLine myLine = model.modelLines.ElementAt(index); MyLine newMyLine = null; Model tempModel = model.DeepCopy(myLine, out newMyLine); tempModel.MoveLine(-moveDistance, newMyLine); if (tempModel.IsInInvalidState) { continue; } double[] costs = CostCalculationService.CalculateCost(tempModel); double summary = costs[0]; double areacost = costs[1]; double layoutcost = costs[2]; lock (locker) { Actions.Add(new Move(myLine, summary, areacost, layoutcost, -moveDistance)); } } //}); }
// If explosion was with voxels, crease dirt decals in player's cockpit glass // We don't throw random number of debris lines from explosion (because it will be waste). Instead we get intersection line from explosion center to player head, // which should intersect the cockpit glass. Plus we move player head by random vector. void CreateDirtDecalOnCockpitGlass(ref BoundingSphere explosionSphere) { MySmallShip player = MySession.PlayerShip; float maxDistance = m_explosionSphere.Radius * MyExplosionsConstants.EXPLOSION_RADIUS_MULTPLIER_FOR_DIRT_GLASS_DECALS; float distance = Vector3.Distance(player.GetPosition(), explosionSphere.Center) - player.ModelLod0.BoundingSphere.Radius; // Decal interpolator - based on distance to explosion, range <0..1> // But then increased because we aren't able to reach max distance so we need to help it little bit float interpolator = 1 - MathHelper.Clamp(distance / maxDistance, 0, 1); interpolator = (float)Math.Pow(interpolator, 3f); // Don't create dirt decal if we are too far if (interpolator <= 0.0f) { return; } // Chech intersection between explosion and player's head. BUT move the line in player's head direction, because we don't want to make intersection with object which caused the explosion //MyLine line = new MyLine(intersection.IntersectionPointInWorldSpace, player.GetPosition(), true); //MyLine line = new MyLine(intersection.IntersectionPointInWorldSpace, MyCamera.m_initialSunWindPosition, true); //Vector3 playerHeadPositionWorld = MyUtils.GetTransform(MyFakes.PLAYER_HEAD_FOR_COCKPIT_INTERIOR_FAKE_TRANSLATION * -1, ref player.WorldMatrix); Vector3 playerHeadPositionWorld = player.GetPlayerHeadForCockpitInterior(); MyLine line = new MyLine(explosionSphere.Center, playerHeadPositionWorld, true); line.From += line.Direction * MyExplosionsConstants.OFFSET_LINE_FOR_DIRT_DECAL; MyIntersectionResultLineTriangleEx?glassIntersection = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new Type[] { typeof(MySmallShip) }); if ((glassIntersection != null) && (glassIntersection.Value.Entity is MyCockpitGlassEntity)) { // Decal alpha (never is 1.0f, because we want to see through the dirt) float alpha = MathHelper.Clamp(MathHelper.Lerp(0.2f, 1.0f, interpolator) - 0.1f, 0, 1); //const float ALPHA_INCREASE = 0.4f; //float alpha = 1 - (float)Math.Pow(MathHelper.Clamp(distance / maxDistance, 0, 1), 5); //float alpha = (float)MathHelper.SmoothStep(0, 1, 1 - MathHelper.Clamp(distance / maxDistance, 0, 1)); //float alpha = MathHelper.Clamp(1 - MathHelper.Clamp(distance / maxDistance, 0, 1) + ALPHA_INCREASE, ALPHA_INCREASE, 1); // Decal size float size = MathHelper.Lerp(2.5f, 4f, interpolator); MyIntersectionResultLineTriangleEx glassIntersection2 = glassIntersection.Value; MyCockpitGlassDecals.Add(MyCockpitGlassDecalTexturesEnum.DirtOnGlass, size, MyMwcUtils.GetRandomRadian(), alpha, ref glassIntersection2, true); } }
public void PropertyConversionTest() { MyLine line = new MyLine(); line.Start = new MyImmutablePoint(1, 5); line.End = new MyImmutablePoint(2, 12); Serializer s = new Serializer(); string result = s.Serialize(line); MyLine actual = s.Deserialize <MyLine>(result); Assert.AreEqual(line.Start, actual.Start, "Line start not equal"); Assert.AreEqual(line.End, actual.End, "Line end not equal"); // make sure the property converter overrode the converter declared on the type Assert.AreEqual(1, MyLinePointConverter.ConvertFromCount, "Property ConvertFrom not called correct amount of times"); Assert.AreEqual(1, MyLinePointConverter.ConvertToCount, "Property ConvertTo not called correct amount of times"); }
public static Entity ConverToCustomEntity(ObjectId CurrentEntityOI, int ProductCode, int ProductType) { Entity ent = Atend.Global.Acad.UAcad.GetEntityByObjectID(CurrentEntityOI); MyCircle c = ent as MyCircle; if (c != null) { #region Convert to mycircle c.AdditionalDictionary.Add("ProductType", ProductType); c.AdditionalDictionary.Add("ProductCode", ProductCode); ent = c; #endregion } else { MyPolyline p = ent as MyPolyline; if (p != null) { #region convert to polyline p.AdditionalDictionary.Add("ProductType", ProductType); p.AdditionalDictionary.Add("ProductCode", ProductCode); ent = p; #endregion } else { MyLine l = ent as MyLine; if (l != null) { #region convert to line l.AdditionalDictionary.Add("ProductType", ProductType); l.AdditionalDictionary.Add("ProductCode", ProductCode); ent = l; #endregion } else { // it was nothing } } } return(ent); }
public void SerializationUsesAliases() { Serializer s = new Serializer(); s.Settings.Types.PropertyNamingStrategy = new DelegateNamingStrategy(delegate(string old) { return("__" + old.ToLower() + "__"); }); MyLine source = new MyLine(); source.Start = new MyImmutablePoint(0, 0); source.End = new MyImmutablePoint(5, -5); s.Settings.IsCompact = true; string result = s.Serialize(source); string expected = "{\"__start__\":\"(0:0)\", \"__end__\":\"5,-5\"}"; Assert.AreEqual(expected, result, "serialization"); MyLine target = s.Deserialize <MyLine>(result); Assert.AreEqual(source, target, "Deserialization"); }
private static bool IsCustomLookAtTarget(MySmallShip smallShip, MyEntity otherEntity, float radius) { if (!MUST_LOOK_AT_TARGET) { return true; } BoundingSphere sphere = new BoundingSphere(otherEntity.WorldVolume.Center, radius); Ray ray = new Ray(smallShip.GetPosition(), smallShip.WorldMatrix.Forward); float? rayIntersection = ray.Intersects(sphere); if (rayIntersection.HasValue) { MyLine line = new MyLine(smallShip.WorldVolume.Center, otherEntity.WorldVolume.Center, true); MyIntersectionResultLineTriangleEx? result = MyEntities.GetIntersectionWithLine(ref line, smallShip, null, ignoreChilds: true); return !result.HasValue || !result.HasValue || result.Value.Entity == otherEntity; } return false; }
public static void CreateDoc(string value, Stream destStream) { var pdfDoc = new PdfDocument(new PdfWriter(destStream)); var document = new Document(pdfDoc); var pageSize = pdfDoc.GetDefaultPageSize(); float width = pageSize.GetWidth() - document.GetLeftMargin() - document.GetRightMargin(); SolidLine line = new SolidLine(); AddParagraphWithTabs(document, value, line, width); // Draw a custom line to fill both sides, as it is described in iText5 example MyLine customLine = new MyLine(); AddParagraphWithTabs(document, value, customLine, width); document.Close(); }
public void DoWork() { try { MyEntities.EntityCloseLock.AcquireShared(); if (m_bot == null) { return; } BoundingSphere boundingSphere = new BoundingSphere(m_position, m_bot.WorldVolume.Radius * 2.0f); if (MyEntities.GetIntersectionWithSphere(ref boundingSphere) != null) { return; } Matrix transform = Matrix.CreateWorld(m_position, MyMwcUtils.Normalize(m_targetPosition - m_position), m_up); float distanceToRoutePoint = Vector3.Dot(m_targetPosition - m_position, transform.Forward); for (int i = 0; i < m_points.Length; i++) { Vector3 transformedPoint = Vector3.Transform(m_points[i], transform); MyLine line = new MyLine(transformedPoint, transformedPoint + transform.Forward * distanceToRoutePoint, true); var result = MyEntities.GetIntersectionWithLine(ref line, m_bot, null, true); if (result.HasValue) { // Collision detected return; } } Result = m_position; } finally { if (m_bot != null) { m_bot.OnClose -= m_bot_OnClose; } MyEntities.EntityCloseLock.ReleaseShared(); } }
public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, ref MyLine line, ref Matrix customInvMatrix, IntersectionFlags flags) { MyLine lineInModelSpace = new MyLine(MyUtils.GetTransform(line.From, ref customInvMatrix), MyUtils.GetTransform(line.To, ref customInvMatrix), true); //MyIntersectionResultLineTriangle? result = null; m_result.Start(m_model, lineInModelSpace, flags); var dir = new IndexedVector3(lineInModelSpace.Direction); var from = new IndexedVector3(lineInModelSpace.From); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()"); m_bvh.RayQueryClosest(ref dir, ref from, m_result.ProcessTriangleHandler); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); if (m_result.Result.HasValue) { return new MyIntersectionResultLineTriangleEx(m_result.Result.Value, physObject, ref lineInModelSpace); } else { return null; } }
public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, MyEntity physObject, ref MyLine line) { Triangle = triangle; Entity = physObject; InputLineInObjectSpace = line; NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle); IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance; if (Entity is MyVoxelMap) { IntersectionPointInWorldSpace = IntersectionPointInObjectSpace; NormalInWorldSpace = NormalInObjectSpace; // This will move intersection point from world space into voxel map's object space IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((MyVoxelMap)Entity).PositionLeftBottomCorner; } else { Matrix worldMatrix = Entity.WorldMatrix; NormalInWorldSpace = MyUtils.GetTransformNormalNormalized(NormalInObjectSpace, ref worldMatrix); IntersectionPointInWorldSpace = MyUtils.GetTransform(IntersectionPointInObjectSpace, ref worldMatrix); } }
// Returns temporary in/out values for voxels int[, ,] GetVoxelContentSum(MyVoxelMap voxelMap, int gridX, int gridZ) { int gridStartPointX = gridX * MAX_GRID_SIZE_IN_ONE_DIRECTION; int gridStartPointZ = gridZ * MAX_GRID_SIZE_IN_ONE_DIRECTION; // Here we store intersections with line and triangles and specified grid point List<MyImportIntersection> intersections = new List<MyImportIntersection>(INITIAL_COUNT_OF_INTERSECTIONS); // Here we store temporary in/out values for voxels. After that, we convert it to common voxel content values (0..255) int[, ,] voxelContentSum = null; for (int gridPointX = 0; gridPointX < MAX_GRID_SIZE_IN_ONE_DIRECTION; gridPointX++) { for (int gridPointZ = 0; gridPointZ < MAX_GRID_SIZE_IN_ONE_DIRECTION; gridPointZ++) { Vector3 gridCoord = GetGridCoord(voxelMap, gridStartPointX + gridPointX, 0, gridStartPointZ + gridPointZ); if (gridCoord.X < m_minCoord.X || gridCoord.Z < m_minCoord.Z || gridCoord.X > m_maxCoord.X || gridCoord.Z > m_maxCoord.Z) { continue; } if (voxelContentSum == null) voxelContentSum = new int[VOXELS_IN_GRID_IN_ONE_DIRECTION, voxelMap.Size.Y, VOXELS_IN_GRID_IN_ONE_DIRECTION]; MyMwcVector2Int triangleLookupCoord = GetTriangleLookupCoord(voxelMap, gridCoord); // We need to clear list of intersections intersections.Clear(); // Get triangles that lie on this grid point/line List<MyImportTriangle> triangles = m_trianglesLookup[triangleLookupCoord.X, triangleLookupCoord.Y]; for (int i = 0; i < triangles.Count; i++) { // Ray is always in Y-axis direction //MyLine line = new MyLine(gridCoord, gridCoord + Vector3.Up * 100000, false); MyLine line = new MyLine(new Vector3(gridCoord.X, m_minCoord.Y, gridCoord.Z) + Vector3.Down * 10, new Vector3(gridCoord.X, m_maxCoord.Y, gridCoord.Z) + Vector3.Up * 10, false); MyTriangle_Vertexes triangle; triangle.Vertex0 = triangles[i].Vertex0; triangle.Vertex1 = triangles[i].Vertex1; triangle.Vertex2 = triangles[i].Vertex2; float? distance = MyUtils.GetLineTriangleIntersection(ref line, ref triangle); if (distance.HasValue == true) { intersections.Add(new MyImportIntersection(line.From + line.Direction * distance.Value, triangles[i].Normal, distance.Value)); } } // SortForSAP intersections by their distance from the origin (from the grid point) intersections.Sort(delegate(MyImportIntersection p1, MyImportIntersection p2) { return p1.Distance.CompareTo(p2.Distance); }); int lastY = 0; bool contentSwitch = false; // This tells us if we will add empty or full voxels. False = until now it's empty. True = it full. for (int i = 0; i < intersections.Count; i++) { Vector3 tempGridCoord = GetGridCoord(voxelMap, gridStartPointX + gridPointX, lastY, gridStartPointZ + gridPointZ); int length = (int)((intersections[i].Intersection.Y - tempGridCoord.Y) / m_gridPointsSize); // this is here, because we must find intersection with triangle out of borders of voxel map, because we can use voxel hand at the borders if (length < 0) { contentSwitch = !contentSwitch; continue; } for (int y = lastY; y < (lastY + length); y++) { MyMwcVector3Int voxelCoord = voxelMap.GetVoxelCoordinateFromMeters(GetGridCoord(voxelMap, gridPointX, y, gridPointZ)); if (voxelCoord.Y < voxelContentSum.GetLength(1) && voxelCoord.Y >= 0) { voxelContentSum[voxelCoord.X, voxelCoord.Y, voxelCoord.Z] += (contentSwitch == false) ? 0 : 1; } } contentSwitch = !contentSwitch; lastY = lastY + length; } } } return voxelContentSum; }
/// <summary> /// Updates resource. /// </summary> public override void UpdateBeforeSimulation() { try { MyRender.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation"); //Large ship weapons wont make bots curious if ((!(OwnerEntity is MyLargeShipMissileLauncherBarrel)) && MyMwcUtils.HasValidLength(this.WorldMatrix.Translation - m_previousPosition)) { MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition); MyDangerZones.Instance.Notify(line, OwnerEntity); } if (m_isExploded) { // Create explosion MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { float radius = m_ammoProperties.ExplosionRadius; // Explicitly on Marek's request (ticket 4740) bool amplifyRadius = m_collidedEntity != null ? MyFactions.GetFactionsRelation(m_collidedEntity.Faction, Faction) != MyFactionRelationEnum.Friend : false; if (amplifyRadius) { radius *= 2; } BoundingSphere explosionSphere = new BoundingSphere(m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition(), radius); // Call main explosion starter MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = m_ammoProperties.HealthDamage, Damage = m_ammoProperties.ShipDamage, EmpDamage = m_ammoProperties.EMPDamage, ExplosionType = m_explosionType, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, ExplosionForceDirection = MyExplosionForceDirection.EXPLOSION, GroupMask = Physics.GroupMask, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, ParticleScale = 1.5f, OwnerEntity = this.OwnerEntity, Direction = WorldMatrix.Forward, VoxelExplosionCenter = explosionSphere.Center + m_ammoProperties.ExplosionRadius * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT, VoxelCutoutScale = amplifyRadius ? 0.5f : 1.0f, PlaySound = true, }; newExplosion.Start(ref info); } if (m_collidedEntity != null && !m_collidedEntity.IsExploded()) { m_collidedEntity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE, GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2, MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized()); m_collidedEntity.OnClose -= m_collidedEntity_OnClose; } MarkForClose(); return; } bool firstTargetting = m_elapsedMiliseconds == 0; base.UpdateBeforeSimulation(); m_missileTargetUpdate += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; if (m_missileTargetUpdate >= MyGuidedMissileConstants.MISSILE_TARGET_UPDATE_INTERVAL_IN_MS || firstTargetting) { m_missileTargetUpdate = 0; switch (m_missileType) { case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection: { MySmallShip targetShip = m_targetEntity as MySmallShip; if (targetShip != null && targetShip.IsRadarJammed()) { m_targetEntity = null; } } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection: { m_targetEntities.Clear(); Matrix proj = Matrix.CreateOrthographic(MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, 0, 1000); Matrix view = Matrix.CreateLookAt(GetPosition(), GetPosition() + WorldMatrix.Forward, WorldMatrix.Up); m_visualFrustum.Matrix = view * proj; MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); if (m_targetEntities.Contains(m_targetEntity)) break; MyEntity target = null; float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (CanTarget(entity)) { MySmallShip targetShip = entity as MySmallShip; if (targetShip != null) { if ((targetShip.IsEngineTurnedOff())) continue; } Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection: { Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_FOV), 1, 10, MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_RANGE); m_visualFrustum.Matrix = Matrix.Invert(WorldMatrix) * projectionMatrix; m_targetEntities.Clear(); MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); int testsLimit = 8; if (m_targetEntities.Contains(m_targetEntity)) break; MyEntity target = null; //looks better if missile gets "lost" float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (!CanTarget(entity)) continue; if (testsLimit-- == 0) break; if (MyEnemyTargeting.CanSee(this, entity) == null) { Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; } } if ((m_initTime - m_elapsedMiliseconds) > 0) { //simulating missile launch and engine ignition MyEntity owner = OwnerEntity; if (owner != null) { Vector3 transformedInitDir = Vector3.TransformNormal(m_initDir, owner.WorldMatrix); // Vector3 initialVelocity = Vector3.Zero; if (owner.Physics != null) { initialVelocity = owner.Physics.LinearVelocity; } Physics.LinearVelocity = transformedInitDir * m_ammoProperties.InitialSpeed + initialVelocity; } } else { // This will help blend "initial velocity" and "thrust velocity" so at the beginning missile is powered by initiatal velocity only, but later float velocityBlend = MathHelper.Clamp((float)(m_elapsedMiliseconds - m_initTime) / m_blendVelocities, 0, 1); if (velocityBlend == 1.0f) { m_actualSpeed = m_ammoProperties.DesiredSpeed; } else { float initialSpeed = 0.0f; MyEntity owner = OwnerEntity; if (owner != null) { if (owner.Physics != null) { initialSpeed = owner.Physics.LinearVelocity.Length(); } } m_actualSpeed = velocityBlend * m_ammoProperties.DesiredSpeed + ((1.0f - velocityBlend) * (m_ammoProperties.InitialSpeed + initialSpeed)); if (m_missileType != MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic && m_smokeEffect == null) { // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { /* MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_MissileStart); startEffect.WorldMatrix = WorldMatrix; */ m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile); m_smokeEffect.WorldMatrix = WorldMatrix; m_smokeEffect.AutoDelete = false; } } } m_desiredVelocity = GetDesiredVelocity(m_targetEntity); Physics.LinearVelocity = m_desiredVelocity * m_actualSpeed * 1.0f; } Physics.AngularVelocity = Vector3.Zero; if ((m_elapsedMiliseconds > m_missileTimeout) || (Vector3.Distance(GetPosition(), m_origin) >= m_maxTrajectory)) { Explode(); return; } if (m_smokeEffect != null) { Matrix smokeMatrix = Matrix.CreateWorld(WorldMatrix.Translation - 0.5f * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up); m_smokeEffect.WorldMatrix = smokeMatrix; } if (m_targetEntity != null) { if (m_targetEntity.Physics != null) m_targetVelocity = m_targetEntity.Physics.LinearVelocity; else m_targetVelocity = Vector3.Zero; } } finally { MyRender.GetRenderProfiler().EndProfilingBlock(); } }
protected override void Drill() { // Sphere which is used to make tunnel to voxel and sphere for testing collision with voxel m_fakeCollisionSphere = new BoundingSphere(m_fakeSpherePositionTransformed, m_radius); // Check for collision with drill and world //MyEntity collisionResult = MyEntities.GetIntersectionWithSphere(ref m_fakeCollisionSphere, this, Parent, false, true); // bSphere collision doesn't work - the sphere is tested against LOD0 model, but it is hidden inside the COL model and the bSphere is too small to reach it - so I use line instead MyEntity collisionResult = null; MyLine line; if (MySession.Is25DSector) { line = new MyLine(m_positionMuzzleInWorldSpace - 10 * WorldMatrix.Forward, m_positionMuzzleInWorldSpace + 20 * WorldMatrix.Forward, true); } else line = new MyLine(m_positionMuzzleInWorldSpace - 10 * WorldMatrix.Forward, m_positionMuzzleInWorldSpace + 5 * WorldMatrix.Forward, true); MyIntersectionResultLineTriangleEx? intersection = MyEntities.GetIntersectionWithLine(ref line, Parent, this, true, true); if (intersection != null && intersection.Value.Entity.Physics != null) { collisionResult = intersection.Value.Entity; } if (!(collisionResult is MyVoxelMap)) { m_lastTimeDrillNotCollidedWithVoxelMapInMiliseconds = MyMinerGame.TotalGamePlayTimeInMilliseconds; if (!MySession.Is25DSector) { ((MySmallShip)Parent).IncreaseHeadShake(MyDrillDeviceConstants.SHAKE_DURING_ROTATION); } StopDustEffect(); if (collisionResult != null) { var effect = MyParticlesManager.CreateParticleEffect((int) MyParticleEffectsIDEnum.MaterialHit_Autocannon_Metal); effect.WorldMatrix = Matrix.CreateTranslation(m_fakeCollisionSphere.Center); collisionResult.DoDamage(0, m_damage * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS, 0, MyDamageType.Drill, MyAmmoType.Basic, Parent); } } // Display particles when we are in contact with voxel else { if (m_dustEffect == null) { m_dustEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_DrillDust); } m_dustEffect.WorldMatrix = Matrix.CreateTranslation(m_fakeSpherePositionTransformed); m_dustEffect.UserScale = MySession.Is25DSector ? 3 : 1; ((MySmallShip)Parent).IncreaseHeadShake(MyDrillDeviceConstants.SHAKE_DURING_IN_VOXELS); } // Play sound if there is collision with voxel if (collisionResult != null) { if (collisionResult is MyStaticAsteroid) { if (!collisionResult.IsDestructible) { MinerWars.AppCode.Game.HUD.MyHud.ShowIndestructableAsteroidNotification(); } } StartDrillingCue(collisionResult is MyVoxelMap); StopMovingCue(); } else { StartMovingCue(); StopDrillingCue(); } // We found voxel so lets make tunel into it using (var voxelMapsFound = PoolList<MyVoxelMap>.Get()) { bool drilled = false; bool drilledSomeDestructibleContent = false; MyVoxelMaps.GetListOfVoxelMapsWhoseBoundingSphereIntersectsSphere(ref m_fakeCollisionSphere, voxelMapsFound, null); int drillInterval = MySession.Is25DSector ? 100 : (int)MyDrillDeviceConstants.DRILL_INTERVAL_IN_MILISECONDS; int timerToDrillInterval = MySession.Is25DSector ? 100 : (int)MyDrillDeviceConstants.TIME_TO_DRILL_VOXEL_IN_MILISECONDS; foreach (MyVoxelMap voxelMap in voxelMapsFound) { if ((collisionResult is MyVoxelMap) && ((MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeDrilled) > drillInterval) && (MyMinerGame.TotalGamePlayTimeInMilliseconds - m_lastTimeDrillNotCollidedWithVoxelMapInMiliseconds) > timerToDrillInterval) { drilled = true; float rangeStep = 0; float radius = GetRadiusNeededForTunel(); BoundingSphere bigSphereForTunnel = new BoundingSphere(m_fakeCollisionSphere.Center, radius); while (rangeStep < m_range) { MyMwcVector3Int exactCenterOfDrilling = voxelMap.GetVoxelCoordinateFromMeters(bigSphereForTunnel.Center); // we don't want to drill indestructible voxels or empty space if (voxelMap.IsVoxelInVoxelMap(ref exactCenterOfDrilling) && voxelMap.GetVoxelMaterialIndestructibleContent(ref exactCenterOfDrilling) == MyVoxelConstants.VOXEL_CONTENT_FULL) { break; } else { drilledSomeDestructibleContent = true; } CutOutFromVoxel(voxelMap, ref bigSphereForTunnel); bigSphereForTunnel.Center += 2 * WorldMatrix.Forward; rangeStep += 1; } } } if (drilled) { m_lastTimeDrilled = MyMinerGame.TotalGamePlayTimeInMilliseconds; if (!drilledSomeDestructibleContent) { HUD.MyHud.ShowIndestructableAsteroidNotification(); } } } }
private void UpdateVisibility(MySmallShipBot bot, Vector3 targetPosition) { if (m_visibilityCheckTimer <= 0) { if (bot.GetPosition() == targetPosition) { m_targetVisible = true; } else { MyLine line = new MyLine(bot.GetPosition(), targetPosition, true); var result = MyEntities.GetIntersectionWithLine(ref line, bot, null, true, ignoreChilds: true); m_targetVisible = !result.HasValue; } m_visibilityCheckTimer = 0.5f; } else { m_visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } }
// Finds intersection between line and model, using octree for speedup the lookup. // Another speedup is, that first we check triangles that are directly in the node and then start // checking node's childs. But only if child node instersection is less than last know min distance. MyIntersectionResultLineTriangle? GetIntersectionWithLineRecursive(MyModel model, ref MyLine line, float? minDistanceUntilNow) { // Check if line intersects bounding box of this node and if distance to bounding box is less then last know min distance float? distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref line, ref m_boundingBox); if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value))) return null; // Triangles that are directly in this node MyIntersectionResultLineTriangle? foundIntersection = null; // temporary variable for storing tirngle boundingbox info BoundingBox triangleBoundingBox = new BoundingBox(); MinerWars.AppCode.Game.Managers.MyPerformanceCounter.PerCameraDraw.RayCastTrianglesProcessed += m_triangleIndices.Count; for (int i = 0; i < m_triangleIndices.Count; i++) { int triangleIndex = m_triangleIndices[i]; model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox); // First test intersection of triangleVertexes's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests. if (MyUtils.IsBoxIntersectingBox(triangleBoundingBox, ref line.BoundingBox) == true) { // See that we swaped vertex indices!! MyTriangle_Vertexes triangle; MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex]; triangle.Vertex0 = model.GetVertex(triangleIndices.I0); triangle.Vertex1 = model.GetVertex(triangleIndices.I2); triangle.Vertex2 = model.GetVertex(triangleIndices.I1); float? distance = MyUtils.GetLineTriangleIntersection(ref line, ref triangle); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((foundIntersection == null) || (distance.Value < foundIntersection.Value.Distance))) { Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle); // We need to remember original triangleVertexes coordinates (not transformed by world matrix) foundIntersection = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value); } } } // Get intersection with childs of this node if (m_childs != null) { for (int i = 0; i < m_childs.Count; i++) { MyIntersectionResultLineTriangle? childIntersection = m_childs[i].GetIntersectionWithLineRecursive(model, ref line, (foundIntersection == null) ? (float?)null : foundIntersection.Value.Distance); // If intersection occured and if distance to intersection is closer to origin than any previous intersection foundIntersection = MyIntersectionResultLineTriangle.GetCloserIntersection(ref foundIntersection, ref childIntersection); } } return foundIntersection; }
internal override void Update(MySmallShipBot bot) { base.Update(bot); if (bot.Leader != null) { if (ShouldFallAsleep(bot)) { bot.IsSleeping = true; return; } Vector3 leaderToBot = bot.GetPosition() - bot.Leader.GetPosition(); Vector3 formationPositionActual = bot.Leader.GetFormationPosition(bot); Vector3 botToFormationPosition = formationPositionActual - bot.GetPosition(); float leaderDistance = leaderToBot.Length(); float formationPositionDistance = botToFormationPosition.Length(); Vector3 flyTo; if (formationPositionDistance > MyMwcMathConstants.EPSILON_SQUARED && leaderDistance > MyMwcMathConstants.EPSILON) { float leaderFactor = MathHelper.Clamp(leaderDistance - 5, 0, 25) / 20; flyTo = (1.0f - leaderFactor) * leaderToBot / leaderDistance + leaderFactor * botToFormationPosition / formationPositionDistance; flyTo = MyMwcUtils.Normalize(flyTo); flyTo = bot.GetPosition() + flyTo * formationPositionDistance; // Update leader visibility if (visibilityCheckTimer <= 0) { MyLine line = new MyLine(bot.GetPosition(), formationPositionActual, true); leaderVisible = !MyEntities.GetIntersectionWithLine(ref line, bot, bot.Leader, true, ignoreSmallShips: true).HasValue; visibilityCheckTimer = 0.5f; } else { visibilityCheckTimer -= MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } } else { // Bot is on formation position flyTo = bot.GetPosition() + bot.WorldMatrix.Forward; leaderVisible = true; } if (leaderVisible) { bool afterburner = /*bot.Leader.IsAfterburnerOn() || */formationPositionDistance > AFTERBURNER_DISTANCE; Vector3 lookTarget = formationPositionDistance < LOOK_DISTANCE ? formationPositionActual + bot.Leader.WorldMatrix.Forward * 5000 : formationPositionActual; float factor = MathHelper.Clamp(formationPositionDistance / 200, 0.5f, 1.0f); factor = factor * factor * factor; bot.Move(flyTo, lookTarget, bot.Leader.WorldMatrix.Up, afterburner, 1, 25, factor, slowRotation: true); checkTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; findSmallship.Init(bot); } else { if (leaderDistance > MIN_LEADER_DISTANCE) { findSmallship.Update(bot, bot.Leader); if (findSmallship.PathNotFound) { //We dont want our friends sleeping elsewhere // bot.IsSleeping = true; } } } } }
/// <summary> /// Check if the missile does not collide too close to ship /// after shooting and correct its starting position if it does. /// </summary> private Vector3 CorrectPosition(Vector3 position, Vector3 direction, MyEntity viewerEntity) { var predictedTrajectory = new MyLine( position - MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction, position + MyMissileConstants.DISTANCE_TO_CHECK_MISSILE_CORRECTION * direction, false); var intersection = MyEntities.GetIntersectionWithLine(ref predictedTrajectory, this, viewerEntity); if (intersection != null) { position = viewerEntity.GetPosition(); } return position; }
/// <summary> /// Paints on a WriteableBitmap like a paintbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="previous">The point prior to the 'from' point, or null</param> /// <param name="color">The color of the brush</param> /// <param name="size">The stroke size</param> public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point? previous, Color color, int size) { if (bmp == null) return; bmp.Lock(); // Intermediate storage of the square of the size int area = size * size; uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B; // Create a line segment representation to compare distance to MyLine line = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox linebounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); linebounds.AddPoint((int)from.X, (int)from.Y, size); linebounds.AddPoint((int)to.X, (int)to.Y, size); linebounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += linebounds.Left; if (previous.HasValue) { MyLine previoussegment = new MyLine(previous.Value, from); // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area && previoussegment.DistanceSquared(x, y) > area) { if (color.A == 255) *pixel = flatcolor; else AlphaBlended(pixel, color); } // Move to the next pixel pixel++; } } } else { // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area) { if (color.A == 255) *pixel = flatcolor; else AlphaBlended(pixel, color); } // Move to the next pixel pixel++; } } } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }
/// <summary> /// Erases paint on a WriteableBitmap /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="size">The stroke size</param> public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size) { if (bmp == null) return; bmp.Lock(); // Intermediate storage of the square of the size int area = size * size; // Create a line segment representation to compare distance to MyLine line = new MyLine(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox linebounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); linebounds.AddPoint((int)from.X, (int)from.Y, size); linebounds.AddPoint((int)to.X, (int)to.Y, size); linebounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) Int32* start = (Int32*)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += linebounds.Left; // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = linebounds.Top; y < linebounds.Bottom; y++) { Int32* pixel = start + bmp.BackBufferStride / sizeof(Int32) * y; for (int x = linebounds.Left; x < linebounds.Right; x++) { if (line.DistanceSquared(x, y) <= area) *pixel = 0; // Move to the next pixel pixel++; } } bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height)); bmp.Unlock(); }