public void Execute(int index) { var v = velocities[index]; var accel = accelerations[index]; Float3 velocity; velocity.X = v.X + accel.X * dt; velocity.Y = v.Y + accel.Y * dt; velocity.Z = v.Z + accel.Z * dt; var speed = Float3.Magnitude(ref velocity); velocity.Scale(1f / speed); var r = Quaternion.LookRotation(velocity, Vector3.up); speed = MathFast.Clamp(speed, minSpeed, maxSpeed); velocity.Scale(speed); var pos = positions[index]; pos.Add(velocity.X * dt, velocity.Y * dt, velocity.Z * dt); positions[index] = pos; accel.Set(0f, 0f, 0f); accelerations[index] = accel; velocities[index] = velocity; matrices[index] = Matrix4x4.TRS(pos, r, scale); }
private void ProcessArmor(GameEntity sourceEntity, GameEntity targetEntity, ref float inputDamageValue) { var targetArmor = targetEntity.characterCharacterStats.GetStat(CharacterStatId.Armor); if (targetArmor == null) { return; } //theo dota2 var damageMultiplier = 1 - ((0.052f * targetArmor.ActiveValue) / (0.9f + 0.048f * MathFast.Abs(targetArmor.ActiveValue))); inputDamageValue = (inputDamageValue * damageMultiplier); var targetHpValue = targetEntity.characterCharacterStats.GetStat(CharacterStatId.Hp); if (targetHpValue == null) { //lỗi return; } targetHpValue.ActiveValue -= inputDamageValue; //done }
public static Float2 Rotate(this Float2 v, float radians) { var ca = MathFast.Cos(radians); var sa = MathFast.Sin(radians); return(new Float2(ca * v.X - sa * v.Y, sa * v.X + ca * v.Y)); }
Float3 GetAccelAgainstWall(float dist, ref Float3 dir, float thresh, float weight) { if (dist < thresh) { return(Float3.Scale(ref dir, weight / MathFast.Abs(dist / thresh))); } return(Float3.Zero); }
public static int HexDistance(int x1, int y1, int x2, int y2) { int x = x2 - x1; int y = y2 - y1; int z = -x - y; return(MathFast.Max(MathFast.Abs(x), MathFast.Max(MathFast.Abs(y), MathFast.Abs(z)))); }
void LeoECS() { _world = new EcsWorld(); JobMoveSystem.MinSpeed = param.minSpeed; JobMoveSystem.MaxSpeed = param.maxSpeed; JobMoveSystem.BoidScale = boidScale; JobMoveSystem.WallScale = param.wallScale * 0.5f; JobMoveSystem.WallDistance = param.wallDistance; JobMoveSystem.WallWeight = param.wallWeight; JobMoveSystem.NeighborFov = MathFast.Cos(param.neighborFov * MathFast.Deg2Rad); JobMoveSystem.NeighborDistance = param.neighborDistance; JobMoveSystem.SeparationWeight = param.separationWeight; JobMoveSystem.AlignmentWeight = param.alignmentWeight; JobMoveSystem.CohesionWeight = param.cohesionWeight; JobMoveSystem.EntitiesCount = boidCount; JobMoveSystem.NumBoidsPerJob = boidCount / System.Environment.ProcessorCount; if (BoidsVisualisationSystem._nativeMatrices.IsCreated) { BoidsVisualisationSystem._nativeMatrices.Dispose(); } BoidsVisualisationSystem._nativeMatrices = new NativeArray <Matrix4x4> (boidCount, Allocator.Persistent); BoidsVisualisationSystem._matrices = new Matrix4x4[boidCount]; var timeSystem = new TimeSystem(); _systems = new EcsSystems(_world); _systems .Add(timeSystem) .Add(new BoidsSimulationSystem()) .Add(new JobMoveSystem()) .Add(new BoidsVisualisationSystem() { mesh = mesh, material = material, scale = boidScale }) .Inject(timeSystem) .Initialize(); var random = new RngXorShift(853); BoidEntityData.Create(boidCount); for (int i = 0; i < boidCount; ++i) { var initSpeed = param.initSpeed; //init them with these default values var boid = _world.CreateEntityWith <BoidEntityData> (); boid.id = i; boid.Position = new Float3(random.GetFloat(), random.GetFloat(), random.GetFloat()); var vel = new Float3(random.GetFloat(), random.GetFloat(), random.GetFloat()); vel.Normalize(); vel.Scale(initSpeed); boid.Velocity = vel; boid.Acceleration = Float3.Zero; } _world.ProcessDelayedUpdates(); }
//todo hexagonal public void Fill(int radius) { for (int i = -radius; i < radius; i++) { for (int j = -radius; j < radius; j++) { if (MathFast.Abs(HexMath.GetZ(i, j)) <= radius) { Add(i, j, new T()); } } } }
void LeoECS() { _world = new EcsWorld(); ThreadMoveSystem.MinSpeed = param.minSpeed; ThreadMoveSystem.MaxSpeed = param.maxSpeed; ThreadMoveSystem.BoidScale = boidScale; ThreadMoveSystem.WallScale = param.wallScale * 0.5f; ThreadMoveSystem.WallDistance = param.wallDistance; ThreadMoveSystem.WallWeight = param.wallWeight; ThreadMoveSystem.NeighborFov = MathFast.Cos(param.neighborFov * MathFast.Deg2Rad); ThreadMoveSystem.NeighborDistance = param.neighborDistance; ThreadMoveSystem.SeparationWeight = param.separationWeight; ThreadMoveSystem.AlignmentWeight = param.alignmentWeight; ThreadMoveSystem.CohesionWeight = param.cohesionWeight; ThreadMoveSystem.Neighbours = new BoidEntityData[boidCount][]; for (int i = 0; i < boidCount; i++) { ThreadMoveSystem.Neighbours[i] = new BoidEntityData[boidCount]; } BoidsVisualisationSystem2._matrices = new Matrix4x4[boidCount]; var timeSystem = new TimeSystem(); _systems = new EcsSystems(_world); _systems .Add(timeSystem) .Add(new BoidsSimulationSystem()) .Add(new ThreadMoveSystem()) .Add(new BoidsVisualisationSystem2() { mesh = mesh, material = material, scale = boidScale }) // .Add (new BoidsVisualisationSystem () { mesh = mesh, material = material, scale = boidScale }) .Inject(timeSystem) .Initialize(); var random = new RngXorShift(853); for (int i = 0; i < boidCount; ++i) { var initSpeed = param.initSpeed; //init them with these default values var boid = _world.CreateEntityWith <BoidEntityData> (); boid.position = new Float3(random.GetFloat(), random.GetFloat(), random.GetFloat()); boid.velocity = new Float3(random.GetFloat(), random.GetFloat(), random.GetFloat()); boid.velocity.Normalize(); boid.velocity.Scale(initSpeed); boid.acceleration = Float3.Zero; } _world.ProcessDelayedUpdates(); }
/// <summary> /// Our worker callback for processing entities. /// Important: always use static methods as workers - you cant touch any instance data except method parameters. /// </summary> void Worker(EcsFilter <BoidEntityData> filter, int from, int to) { // Important: you can't iterate over filter with foreach-loop // and should use for-loop with "from" / "to" bounds. var dt = _timeSystem.DeltaTime; var minSpeed = MinSpeed; var maxSpeed = MaxSpeed; var scale = BoidScale; var wallScale = WallScale; var thresh = WallDistance; var weight = WallWeight; var prodThresh = NeighborFov; var distThresh = NeighborDistance; var separationWeight = SeparationWeight; var alignmentWeight = AlignmentWeight; var cohesionWeight = CohesionWeight; Float3 velocity = Float3.Zero; Vector3 up = Vector3.up; for (var i = from; i < to; i++) { var c = filter.Components1[i]; Wall(c, wallScale, thresh, weight); var neighbours = Neighbours[i]; var currentCount = DetectNeighbour(c, distThresh, prodThresh, filter.Components1, filter.EntitiesCount, neighbours); if (currentCount > 0) { Separation(c, separationWeight, currentCount, neighbours); Alignment(c, alignmentWeight, currentCount, neighbours); Cohesion(c, cohesionWeight, currentCount, neighbours); } velocity.X = c.velocity.X + c.acceleration.X * dt; velocity.Y = c.velocity.Y + c.acceleration.Y * dt; velocity.Z = c.velocity.Z + c.acceleration.Z * dt; var speed = Float3.Magnitude(ref velocity); velocity.Scale(1f / speed); var r = Quaternion.LookRotation(velocity, up); speed = MathFast.Clamp(speed, minSpeed, maxSpeed); velocity.Scale(speed); c.position.Add(velocity.X * dt, velocity.Y * dt, velocity.Z * dt); c.acceleration.Set(0f, 0f, 0f); c.velocity = velocity; BoidsVisualisationSystem2._matrices[i] = Matrix4x4.TRS(c.position, r, scale); } }
private void ToSpeed(float toSpeedValue) { if (_toSpeedWork != null) { _toSpeedWork.Dispose(); } _toSpeedWork = Observable .EveryUpdate() .SkipWhile(_ => TimeManager.Instance.IsPaused) .TakeWhile(_ => _speed < toSpeedValue) .Subscribe(_ => { _speed = MathFast.Lerp(_speed, toSpeedValue, _toSpeedSmooth * Time.deltaTime); }); }
void SinTest() { Debug.Log(">>>>> sin tests >>>>>"); const int T = 10000; var sw = new System.Diagnostics.Stopwatch(); float f; float s = 1.345f; sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = Mathf.Sin(s); } sw.Stop(); Debug.LogFormat("mathf.sin time on {0} iterations: {1}", T, sw.ElapsedTicks); sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = (float)System.Math.Sin(s); } sw.Stop(); Debug.LogFormat("system.math.sin time on {0} iterations: {1}", T, sw.ElapsedTicks); // Warmup cache. f = MathFast.Sin(s); sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = MathFast.Sin(s); } sw.Stop(); Debug.LogFormat("mathfast.sin time on {0} iterations: {1}", T, sw.ElapsedTicks); var rng = Service <Rng> .Get(); for (int i = 0; i < 10; i++) { f = rng.GetFloat() * MathFast.PI_2; Debug.LogFormat("sin({0}) => {1} / {2}", f, Mathf.Sin(f), MathFast.Sin(f)); } }
void CosTest() { Debug.Log(">>>>> cos tests >>>>>"); const int T = 10000; var sw = new System.Diagnostics.Stopwatch(); float f; float s = 1.345f; sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = Mathf.Cos(s); } sw.Stop(); Debug.LogFormat("mathf.cos time on {0} iterations: {1}", T, sw.ElapsedTicks); sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = (float)System.Math.Cos(s); } sw.Stop(); Debug.LogFormat("system.math.cos time on {0} iterations: {1}", T, sw.ElapsedTicks); // Warmup cache. f = MathFast.Cos(s); sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = MathFast.Cos(s); } sw.Stop(); Debug.LogFormat("mathfast.cos time on {0} iterations: {1}", T, sw.ElapsedTicks); for (int i = 0; i < 10; i++) { f = Rng.GetFloatStatic() * MathFast.PI_2; Debug.LogFormat("cos({0}) error checking => {1} / {2}", f, Mathf.Cos(f), MathFast.Cos(f)); } }
void Atan2Test() { Debug.Log(">>>>> atan2 tests >>>>>"); const int T = 10000; var sw = new System.Diagnostics.Stopwatch(); #pragma warning disable 0219 float f; #pragma warning restore 0219 var sy = 1.234f; var sx = 2.345f; sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = Mathf.Atan2(sy, sx); } sw.Stop(); Debug.LogFormat("mathf.atan2 time on {0} iterations: {1}", T, sw.ElapsedTicks); // Warmup cache. f = MathFast.Atan2(sy, sx); sw.Reset(); sw.Start(); for (int i = 0; i < T; i++) { f = MathFast.Atan2(sy, sx); } sw.Stop(); Debug.LogFormat("mathfast.atan2 time on {0} iterations: {1}", T, sw.ElapsedTicks); var rng = Service <Rng> .Get(); for (int i = 0; i < 10; i++) { sy = rng.GetFloat() * MathFast.PI_2; sx = rng.GetFloat() * MathFast.PI_2; Debug.LogFormat("atan2({0}, {1}) error checking => {2} / {3}", sy, sx, Mathf.Atan2(sy, sx) * MathFast.Rad2Deg, MathFast.Atan2(sy, sx) * MathFast.Rad2Deg); } }
/// <summary> /// Create "ui" node. If children supported - GameObject container for them should be returned. /// </summary> /// <param name="widget">Ui widget.</param> /// <param name="node">Xml node.</param> /// <param name="container">Markup container.</param> public static RectTransform Create(RectTransform widget, XmlNode node, MarkupContainer container) { #if UNITY_EDITOR widget.name = "ui"; #endif var go = widget.gameObject; var canvas = go.AddComponent <Canvas> (); Camera uiCamera = null; if (Application.isPlaying) { canvas.renderMode = RenderMode.ScreenSpaceCamera; uiCamera = MarkupUtils.GetUiCamera(); canvas.worldCamera = uiCamera; } else { canvas.renderMode = RenderMode.ScreenSpaceOverlay; } canvas.planeDistance = 0f; canvas.pixelPerfect = false; var pixelSize = 1f; var dragTreshold = 5; var scaler = go.AddComponent <CanvasScaler> (); var attrValue = node.GetAttribute(HashedBase); if (attrValue != null) { var refWidth = 1024; var refHeight = 768; var refBalance = 1f; try { var parts = MarkupUtils.SplitAttrValue(attrValue); var w = int.Parse(parts[0]); var h = int.Parse(parts[1]); var b = Mathf.Clamp01(float.Parse(parts[2], NumberFormatInfo.InvariantInfo)); refWidth = w; refHeight = h; refBalance = b; } catch { } scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(refWidth, refHeight); scaler.matchWidthOrHeight = refBalance; if (Application.isPlaying) { if (refBalance < 1f) { Debug.LogWarning("Only height-based balance supported"); } uiCamera.orthographicSize = refHeight * 0.5f; pixelSize = MathFast.Lerp(Screen.width / (float)refWidth, Screen.height / (float)refHeight, refBalance); } else { pixelSize = 1f; } } attrValue = node.GetAttribute(HashedDragTreshold); if (attrValue != null) { if (int.TryParse(attrValue, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out dragTreshold)) { dragTreshold = Mathf.Max(1, dragTreshold); } } attrValue = node.GetAttribute(MarkupUtils.HashedNav); var disableNav = string.CompareOrdinal(attrValue, "false") == 0; container.PixelSize = pixelSize; container.DragTreshold = dragTreshold * pixelSize; container.UseNavigation = !disableNav; go.AddComponent <GraphicRaycaster> (); if (Application.isPlaying) { var es = Object.FindObjectOfType <EventSystem> (); if ((object)es == null) { es = new GameObject("EventSystem").AddComponent <EventSystem> (); es.gameObject.AddComponent <StandaloneInputModule> (); } } return(widget); }