protected override void Update() { emitTimer -= Time.SecScaled; if (emitTimer <= 0) { emitTimer = Rand.Float(EmitRateMin, EmitRateMax); int count = Rand.Int(SprayCountMin, SprayCountMax); for (int i = 0; i < count; i++) { var particle = Particle.Get(); particle.Position = Object.WorldPosition; var adjSprayAngle = VectorOps.AddAngleDegrees(EmitDirection, Rand.Float(-SprayAngleVarianceDegrees / 2, SprayAngleVarianceDegrees / 2)); particle.Velocity = adjSprayAngle.Scale(Rand.Float(MinSpeed, MaxSpeed)); particle.Color = Color; particle.Lifespan = Rand.Float(MinLifespan, MaxLifespan); particle.DrawLayer = DrawLayer; Pigeon.World.ParticleRegistry.Register(particle); } } }
public void CanUse_ScalarTarget_ReturnFalse() { // arrange var target = new DataAndLayout <int>(new int[1], new FastAccess(new Layout(new int[] { }, 0, new int[] { }))); // action var canUse = VectorOps.CanUse(target); // assert Assert.IsFalse(canUse); }
public void CanUse_GoodTargetOnly_ReturnTrue() { // arrange var target = new DataAndLayout <int>(new int[10], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { 1 }))); // action var canUse = VectorOps.CanUse(target); // assert Assert.IsTrue(canUse); }
public void CanUseSrc_WithNullSrc_ReturnTrue() { // arrange const int DummyDimValue = 0; // action var canUse = VectorOps.CanUseSrc <int>(DummyDimValue, null); // assert Assert.IsTrue(canUse); }
public void CanUse_TargetIsNotContinuous_ReturnFalse() { // arrange const int NotContinuousStride = 2; var target = new DataAndLayout <int>(new int[20], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { NotContinuousStride }))); // action var canUse = VectorOps.CanUse(target); // assert Assert.IsFalse(canUse); }
public void CanUse_UnSupportedType_ReturnFalse() { // arrange var data = new UnSupportedTypeForUnitTestOnly[1]; var target = new DataAndLayout <UnSupportedTypeForUnitTestOnly>(data, new FastAccess(new Layout(new int[] { }, 0, new int[] { }))); // action var canUse = VectorOps.CanUse(target); // assert Assert.IsFalse(canUse); }
private static Arenadata.Collider create_collider_data(Vector3 pos, Quaternion rot, Vector3 scale, Collider collider) { { var box_c = collider as BoxCollider; if (box_c != null) { var s = box_c.size; var box_data = new Arenadata.BoxShape(); var local_pos = pos + VectorOps.Mul(box_c.center, scale); box_data.Center = to_arena_type(local_pos); box_data.Rotation = to_arena_type(rot); box_data.Length = s.z; box_data.Height = s.y; box_data.Width = s.x; var collider_data = new Arenadata.Collider(); collider_data.Box = box_data; return(collider_data); } } { var sphere_c = collider as SphereCollider; if (sphere_c != null) { var sphere_data = new Arenadata.SphereShape(); var local_pos = pos + VectorOps.Mul(sphere_c.center, scale); sphere_data.Rotation = to_arena_type(rot); sphere_data.Center = to_arena_type(local_pos); sphere_data.Radius = sphere_c.radius; var collider_data = new Arenadata.Collider(); collider_data.Sphere = sphere_data; return(collider_data); } } { var capsule_c = collider as CapsuleCollider; if (capsule_c != null) { var capsule_data = new Arenadata.CapsuleShape(); var local_pos = pos + VectorOps.Mul(capsule_c.center, scale); capsule_data.Rotation = to_arena_type(rot); capsule_data.Center = to_arena_type(local_pos); capsule_data.Radius = capsule_c.radius; var collider_data = new Arenadata.Collider(); collider_data.Capsule = capsule_data; return(collider_data); } } throw new Exception("Scene contains an unsupported collider."); }
public void CanUse_CanUseBothSrc1AndSrc2_ReturnTrue() { // arrange var target = new DataAndLayout <int>(new int[10], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { 1 }))); var src1 = new DataAndLayout <int>(new int[10], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { 1 }))); var src2 = new DataAndLayout <int>(new int[10], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { 1 }))); // action var canUse = VectorOps.CanUse(target, src1, src2); // assert Assert.IsTrue(canUse); }
public IEnumerable <Ray2D> CreateDetectionRays(Vector2 origin) { origin += offset; Vector3 lineStart = origin - .5f * spread * Vector2.right; Vector3 lineEnd = origin + .5f * spread * Vector2.right; for (int i = 0; i < numberOfRays; i++) { Vector2 rayOrigin = VectorOps.Lerp(lineStart, lineEnd, (float)i / numberOfRays); Vector2 rayDirection = -Vector2.up; yield return(new Ray2D(rayOrigin, rayDirection)); } }
public void CanUseSrc_NoStride_ReturnTrue() { // arrange const int BufferSize = 1; const int NumDim = 1; var data = new int[BufferSize]; var src = new DataAndLayout <int>(data, new FastAccess(new Layout(new int[] { 1 }, 0, new int[] { 0 }))); // action var canUse = VectorOps.CanUseSrc(NumDim, src); // assert Assert.IsTrue(canUse); }
public void CanUseSrc_NotContinuousStride_ReturnFalse() { // arrange const int BufferSize = 6; const int NumDim = 3; var data = new int[BufferSize]; var src = new DataAndLayout <int>(data, new FastAccess(new Layout(new int[] { 1, 2, 3 }, 0, new int[] { 6, 3, 2 }))); // action var canUse = VectorOps.CanUseSrc(NumDim, src); // assert Assert.IsFalse(canUse); }
Vector3 ComputePosition(int segmentIndex) { Vector3 position; Vector3 offset = transform.position; Vector3 originalScale = transform.localScale; position = originalScale / NumberOfSegments; position *= (-.5f + segmentIndex); position += (-.5f * originalScale); position = VectorOps.Multiply(position, new Vector3(1f, 0f, 0f)); position += offset; return(position); }
public void CanUse_CanNotUseSrc1Only_ReturnFalse() { // arrange var target = new DataAndLayout <int>(new int[10], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { 1 }))); var src2 = new DataAndLayout <int>(new int[10], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { 1 }))); const int NotContinuousStride = 2; var src1 = new DataAndLayout <int>(new int[20], new FastAccess(new Layout(new int[] { 10 }, 0, new int[] { NotContinuousStride }))); // action var canUse = VectorOps.CanUse(target, src1, src2); // assert Assert.IsFalse(canUse); }
public void Sqrt() { // arrange const int NumElements = 3; var targetData = new double[NumElements]; var srcData = new[] { 1.0, 4.0, 16.0 }; var target = new DataAndLayout <double>(targetData, new FastAccess(new Layout(new int[] { NumElements }, 0, new int[] { 1 }))); var src = new DataAndLayout <double>(srcData, new FastAccess(new Layout(new int[] { NumElements }, 0, new int[] { 1 }))); // action VectorOps.Sqrt(target, src); // assert CollectionAssert.AreEqual(new[] { 1.0, 2.0, 4.0 }, targetData); }
public void Abs() { // arrange var bufferSize = 10; var targetData = new int[bufferSize]; var srcData = Enumerable.Range(-1 * bufferSize / 2, bufferSize).ToArray(); var target = new DataAndLayout <int>(targetData, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); var src = new DataAndLayout <int>(srcData, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); // action VectorOps.Abs(target, src); // assert var allPositive = target.Data.All(v => v >= 0); Assert.IsTrue(allPositive); }
public void Fill() { // arrange var vectorCount = Vector <int> .Count; // Itentionally break the alignment for the Vector operation to test more code. var bufferSize = 10 + (vectorCount / 2); var data = new int[bufferSize]; var target = new DataAndLayout <int>(data, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); const int FillPattern = 999; // action VectorOps.Fill(FillPattern, target); // assert Assert.IsTrue(data.All(d => d == FillPattern)); }
public void Burst(Point position) { for (int i = 0; i < SprayCount; i++) { var particle = Particle.Get(); particle.Position = position; var adjSprayAngle = VectorOps.AddAngleDegrees(SprayDir, Rand.Float(-SprayAngleVarianceDegrees, SprayAngleVarianceDegrees)); particle.Velocity = adjSprayAngle.Scale(Rand.Float(MinSpeed, MaxSpeed)); particle.Color = Color; particle.Lifespan = Rand.Float(MinLifespan, MaxLifespan); particle.DrawLayer = DrawLayer; Pigeon.World.ParticleRegistry.Register(particle); } }
public void SyncPlayersAsync() { foreach (var kv in objects) { var id = kv.Key; var data = kv.Value; var body = data.rb; var pos = body.Position; var vel = body.LinearVelocity; var ori = body.Orientation; var ang_vel = body.AngularVelocity; var pos_distance = VectorOps.Distance(data.last_pos, pos); var vel_distance = VectorOps.Distance(data.last_vel, vel); var ang_distance = VectorOps.Distance(data.last_ang_vel, vel); if (pos_distance > 0.1f || vel_distance > 0.1f || MatrixOps.CmpExact(data.last_ori, ori) || //TODO: Do some approximation ang_distance > 0.1f) { data.last_pos = body.Position; data.last_vel = body.LinearVelocity; data.last_ori = body.Orientation; data.last_ang_vel = body.AngularVelocity; var ev = new Event3D { ObjectTransformChanged = new Event3D_ObjectTransformChanged { Id = id, NewTransform = new Transform { Position = ArenaServiceConv.ToArenaData(pos), Velocity = ArenaServiceConv.ToArenaData(vel), Rotation = ArenaServiceConv.ToArenaData(ori), AngularVelocity = ArenaServiceConv.ToArenaData(ang_vel) } } }; send_to_all_players(ev); } } }
public void Copy() { // arrange var vectorCount = Vector <int> .Count; // Itentionally break the alignment for the Vector operation to test more code. var bufferSize = 10 + (vectorCount / 2); var targetData = new int[bufferSize]; var srcData = Enumerable.Range(0, bufferSize).ToArray(); var target = new DataAndLayout <int>(targetData, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); var src = new DataAndLayout <int>(srcData, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); // action VectorOps.Copy(target, src); // assert Assert.IsTrue(Enumerable.SequenceEqual(targetData, srcData)); }
public void Minimum() { // arrange var bufferSize = 10; var targetData = new int[bufferSize]; var src1Data = Enumerable.Range(0, bufferSize); var src2Data = src1Data.Reverse(); var target = new DataAndLayout <int>(targetData, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); var src1 = new DataAndLayout <int>(src1Data.ToArray(), new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); var src2 = new DataAndLayout <int>(src2Data.ToArray(), new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); // action VectorOps.Minimum(target, src1, src2); // assert var expectedData = src1Data.Zip(src2Data, (s1, s2) => Tuple.Create(s1, s2)).Select(t => Math.Min(t.Item1, t.Item2)); Assert.IsTrue(Enumerable.SequenceEqual(expectedData, targetData)); }
void OnDrawGizmosSelected() { Vector3 offset = transform.position; Vector3 originalScale = transform.localScale; Vector3 segmentScale = VectorOps.Multiply(originalScale, new Vector3(1f / NumberOfSegments, 1f, 1f)); Gizmos.color = Color.yellow; for (int i = 0; i < NumberOfSegments; i++) { Vector3 position; position = originalScale / NumberOfSegments; position *= (.5f + i); position += -(.5f * originalScale); position = VectorOps.Multiply(position, new Vector3(1f, 0f, 0f)); position += offset; Gizmos.DrawWireCube(position, segmentScale); } }
public void Multiply() { // arrange var vectorCount = Vector <int> .Count; // Itentionally break the alignment for the Vector operation to test more code. var bufferSize = 10 + (vectorCount / 2); var targetData = new int[bufferSize]; var src1Data = Enumerable.Range(0, bufferSize).ToArray(); var src2Data = Enumerable.Range(0, bufferSize).ToArray(); var target = new DataAndLayout <int>(targetData, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); var src1 = new DataAndLayout <int>(src1Data, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); var src2 = new DataAndLayout <int>(src2Data, new FastAccess(new Layout(new int[] { bufferSize }, 0, new int[] { 1 }))); // action VectorOps.Multiply(target, src1, src2); // assert var expectedData = src1Data.Select(x => x * x).ToArray(); Assert.IsTrue(Enumerable.SequenceEqual(expectedData, targetData)); }
public Vector AvoidCollisions(Vector IntendedVelocity) { //store the target that collides then, and other stuff //that we will need and can avoid recalculating //store the first collision time float ShortestTime = float.NegativeInfinity; Unit FirstTarget = null; float FirstMinSeperation = 0; float FirstDistance = 0; Vector FirstRelativePos = new Vector(); Vector FirstRelativeVel = new Vector(); var UnitsInRange = GetAllUnitsInAvoidanceRange(); float Distance = 0; Vector RelativePos = new Vector(); float CollisionRadiusToAvoid = 0F; foreach (var unit in UnitsInRange) { //calc min coll. range float CollisionRadius = (float)this.Radius + (float)unit.Radius; //Calculate time to collision RelativePos = unit.Location.ToVector().Subtract(this.Location.ToVector()); Distance = RelativePos.Len(); Vector RelativeVel = unit.Velocity.Subtract(this.Velocity); //Vector RelativeVel = unit.Velocity.Subtract(IntendedVelocity); float RelativeSpeed = RelativeVel.Mag(); float TimeToCollision = VectorOps.dot(RelativePos, RelativeVel) / (RelativeSpeed * RelativeSpeed); TimeToCollision = -TimeToCollision; if (TimeToCollision == double.NaN || TimeToCollision > 10 || TimeToCollision < 0) { continue; } if (ShortestTime < TimeToCollision) { ShortestTime = TimeToCollision; } //Check if it is going to be a collision at all //var MyPositionAtCollision = (this.Location.World.ToVector()).Add2(this.Velocity.Mult2(TimeToCollision)); var MyPositionAtCollision = (this.Location.World.ToVector()).Add2(IntendedVelocity.Mult2(TimeToCollision)); var HisPositionAtCollision = (unit.Location.World.ToVector()).Add2(unit.Velocity.Mult2(TimeToCollision)); float MinSeperation = (MyPositionAtCollision.Subtract(HisPositionAtCollision)).Len(); //float MinSeperation = Distance - RelativeSpeed * ShortestTime; if (MinSeperation > CollisionRadius) { continue; //skip to the next iteration } if (TimeToCollision > 0 && TimeToCollision <= ShortestTime) { ShortestTime = TimeToCollision; FirstTarget = unit; FirstMinSeperation = MinSeperation; FirstDistance = Distance; FirstRelativePos = RelativePos; FirstRelativeVel = RelativeVel; CollisionRadiusToAvoid = CollisionRadius; } } if (FirstTarget == null) { return(new Vector()); //if we have no target, exit } //if we're going to hit, or if we're hitting already, then do steering based on current pos if (FirstMinSeperation <= 0 || Distance < CollisionRadiusToAvoid) { RelativePos = FirstTarget.Location.ToVector().Subtract(this.Location.ToVector()); } else { Vector vMultipliedFirstRelativeVel = FirstRelativeVel.Mult2(ShortestTime); RelativePos = FirstRelativePos.Add2(vMultipliedFirstRelativeVel); } RelativePos.Normalize(); RelativePos.Mult(MaxSpeed); RelativePos.Y = -RelativePos.Y; RelativePos.X = -RelativePos.X; //float dot = VectorOps.dot(RelativePos.Normalize2(), Velocity.Normalize2()); //if (dot >= 0.01 || dot <= -0.01) //means our velocity is close to perpendicular to collision line ////if (true) //{ // //todo: consider the special case of midVector2 // //otherwise the target is to my right // RelativePos = this.Location.World.ToVector().Add2(GetNormal(Velocity.ToLine())); //} return(RelativePos); //apply steering }
public void RadianToDegree() { Assert.Equal(0, VectorOps.RadianToDegree(0)); Assert.Equal(180 / Math.PI, VectorOps.RadianToDegree(1), precision); Assert.Equal(180, VectorOps.RadianToDegree((float)Math.PI)); }
public void DegreeToRadian() { Assert.Equal(0, VectorOps.DegreeToRadian(0)); Assert.Equal(Math.PI, VectorOps.DegreeToRadian(180), precision); Assert.Equal(2 * Math.PI, VectorOps.DegreeToRadian(360), precision); }
public override void Init(int nGPU) { m_vecOps = new VectorOps(Owner, VectorOps.VectorOperation.Rotate, Owner.Temp); }
public static Vector2 AngledVector(float length = 1) { return(VectorOps.FromRadians(AngleInRadians(), length)); }
public override void Init(int nGPU) { m_vecOps = new VectorOps(Owner, VectorOps.VectorOperation.Angle | VectorOps.VectorOperation.DirectedAngle, Owner.Temp); }
Vector3 ComputeSegmentScale() { return(VectorOps.Multiply(transform.localScale, new Vector3(1f / NumberOfSegments, 1f, 1f))); }