public void Vector2_CalculatesLengthSquaredCorrectly() { var vector = new Vector2(123.4f, 567.8f); TheResultingValue(vector.LengthSquared()).WithinDelta(0.1f) .ShouldBe((123.4f * 123.4f) + (567.8f * 567.8f)); }
public static void ReduceVector(ref Vector2 vector, float limit, float epsilon = 0.1f) { while (vector.LengthSquared() > (limit + epsilon) * (limit + epsilon)) { vector.X *= 0.9f; vector.Y *= 0.9f; } }
public Decoy(Player player, int duration, float tps) : base(0x0715, duration, true, true, true) { this.player = player; this.duration = duration; speed = tps; var history = player.TryGetHistory(100); if (history == null) direction = GetRandDirection(); else { direction = new Vector2(player.X - history.Value.X, player.Y - history.Value.Y); if (direction.LengthSquared() == 0) direction = GetRandDirection(); else direction.Normalize(); } }
/// <summary> /// Gets the intersection between the convex shape and the ray. /// </summary> /// <param name="ray">Ray to test.</param> /// <param name="transform">Transform of the convex shape.</param> /// <param name="maximumLength">Maximum distance to travel in units of the ray direction's length.</param> /// <param name="hit">Ray hit data, if any.</param> /// <returns>Whether or not the ray hit the target.</returns> public override bool RayTest(ref Ray ray, ref RigidTransform transform, float maximumLength, out RayHit hit) { //Put the ray into local space. Quaternion conjugate; Quaternion.Conjugate(ref transform.Orientation, out conjugate); Ray localRay; Vector3.Subtract(ref ray.Position, ref transform.Position, out localRay.Position); Quaternion.Transform(ref localRay.Position, ref conjugate, out localRay.Position); Quaternion.Transform(ref ray.Direction, ref conjugate, out localRay.Direction); //Check for containment. if (localRay.Position.Y >= -halfHeight && localRay.Position.Y <= halfHeight && localRay.Position.X * localRay.Position.X + localRay.Position.Z * localRay.Position.Z <= radius * radius) { //It's inside! hit.T = 0; hit.Location = localRay.Position; hit.Normal = new Vector3(hit.Location.X, 0, hit.Location.Z); float normalLengthSquared = hit.Normal.LengthSquared(); if (normalLengthSquared > 1e-9f) Vector3.Divide(ref hit.Normal, (float)Math.Sqrt(normalLengthSquared), out hit.Normal); else hit.Normal = new Vector3(); //Pull the hit into world space. Quaternion.Transform(ref hit.Normal, ref transform.Orientation, out hit.Normal); RigidTransform.Transform(ref hit.Location, ref transform, out hit.Location); return true; } //Project the ray direction onto the plane where the cylinder is a circle. //The projected ray is then tested against the circle to compute the time of impact. //That time of impact is used to compute the 3d hit location. Vector2 planeDirection = new Vector2(localRay.Direction.X, localRay.Direction.Z); float planeDirectionLengthSquared = planeDirection.LengthSquared(); if (planeDirectionLengthSquared < Toolbox.Epsilon) { //The ray is nearly parallel with the axis. //Skip the cylinder-sides test. We're either inside the cylinder and won't hit the sides, or we're outside //and won't hit the sides. if (localRay.Position.Y > halfHeight) goto upperTest; if (localRay.Position.Y < -halfHeight) goto lowerTest; hit = new RayHit(); return false; } Vector2 planeOrigin = new Vector2(localRay.Position.X, localRay.Position.Z); float dot; Vector2.Dot(ref planeDirection, ref planeOrigin, out dot); float closestToCenterT = -dot / planeDirectionLengthSquared; Vector2 closestPoint; Vector2.Multiply(ref planeDirection, closestToCenterT, out closestPoint); Vector2.Add(ref planeOrigin, ref closestPoint, out closestPoint); //How close does the ray come to the circle? float squaredDistance = closestPoint.LengthSquared(); if (squaredDistance > radius * radius) { //It's too far! The ray cannot possibly hit the capsule. hit = new RayHit(); return false; } //With the squared distance, compute the distance backward along the ray from the closest point on the ray to the axis. float backwardsDistance = radius * (float)Math.Sqrt(1 - squaredDistance / (radius * radius)); float tOffset = backwardsDistance / (float)Math.Sqrt(planeDirectionLengthSquared); hit.T = closestToCenterT - tOffset; //Compute the impact point on the infinite cylinder in 3d local space. Vector3.Multiply(ref localRay.Direction, hit.T, out hit.Location); Vector3.Add(ref hit.Location, ref localRay.Position, out hit.Location); //Is it intersecting the cylindrical portion of the capsule? if (hit.Location.Y <= halfHeight && hit.Location.Y >= -halfHeight && hit.T < maximumLength) { //Yup! hit.Normal = new Vector3(hit.Location.X, 0, hit.Location.Z); float normalLengthSquared = hit.Normal.LengthSquared(); if (normalLengthSquared > 1e-9f) Vector3.Divide(ref hit.Normal, (float)Math.Sqrt(normalLengthSquared), out hit.Normal); else hit.Normal = new Vector3(); //Pull the hit into world space. Quaternion.Transform(ref hit.Normal, ref transform.Orientation, out hit.Normal); RigidTransform.Transform(ref hit.Location, ref transform, out hit.Location); return true; } if (hit.Location.Y < halfHeight) goto lowerTest; upperTest: //Nope! It may be intersecting the ends of the cylinder though. //We're above the cylinder, so cast a ray against the upper cap. if (localRay.Direction.Y > -1e-9) { //Can't hit the upper cap if the ray isn't pointing down. hit = new RayHit(); return false; } float t = (halfHeight - localRay.Position.Y) / localRay.Direction.Y; Vector3 planeIntersection; Vector3.Multiply(ref localRay.Direction, t, out planeIntersection); Vector3.Add(ref localRay.Position, ref planeIntersection, out planeIntersection); if(planeIntersection.X * planeIntersection.X + planeIntersection.Z * planeIntersection.Z < radius * radius + 1e-9 && t < maximumLength) { //Pull the hit into world space. Quaternion.Transform(ref Toolbox.UpVector, ref transform.Orientation, out hit.Normal); RigidTransform.Transform(ref planeIntersection, ref transform, out hit.Location); hit.T = t; return true; } //No intersection! We can't be hitting the other sphere, so it's over! hit = new RayHit(); return false; lowerTest: //Is it intersecting the bottom cap? if (localRay.Direction.Y < 1e-9) { //Can't hit the bottom cap if the ray isn't pointing up. hit = new RayHit(); return false; } t = (-halfHeight - localRay.Position.Y) / localRay.Direction.Y; Vector3.Multiply(ref localRay.Direction, t, out planeIntersection); Vector3.Add(ref localRay.Position, ref planeIntersection, out planeIntersection); if (planeIntersection.X * planeIntersection.X + planeIntersection.Z * planeIntersection.Z < radius * radius + 1e-9 && t < maximumLength) { //Pull the hit into world space. Quaternion.Transform(ref Toolbox.DownVector, ref transform.Orientation, out hit.Normal); RigidTransform.Transform(ref planeIntersection, ref transform, out hit.Location); hit.T = t; return true; } //No intersection! We can't be hitting the other sphere, so it's over! hit = new RayHit(); return false; }
public void TestStaticFn_LengthSquared_i () { Vector2 a = new Vector2(3, -4); Double expected = 25; Double result = a.LengthSquared(); Assert.That(result, Is.EqualTo(expected)); }
/// <summary> /// /// </summary> /// <param name="znear"></param> /// <param name="a"></param> /// <param name="z"></param> /// <param name="r"></param> /// <param name="min"></param> /// <param name="max"></param> /// <returns></returns> bool GetSphereExtentAxis( float znear, float a, float z, float r, out float min, out float max ) { min = max = 0; if (z>r-znear) { return false; } var c = new Vector2( a, z ); var t = sqrt( c.LengthSquared() - r * r ); var cLen = c.Length(); var cosT = t / cLen; var sinT = r / cLen; c.X /= cLen; c.Y /= cLen; var T = new Vector2( cosT * c.X - sinT * c.Y, +sinT * c.X + cosT * c.Y ) * t; var B = new Vector2( cosT * c.X + sinT * c.Y, -sinT * c.X + cosT * c.Y ) * t; var tau = new Vector2( a + sqrt( r*r - square(znear-z) ), znear ); var beta = new Vector2( a - sqrt( r*r - square(znear-z) ), znear ); var U = T.Y < znear ? T : tau; var L = B.Y < znear ? B : beta; max = U.X / U.Y * znear; min = L.X / L.Y * znear; return true; }
public void Render(FormContext formContext, View3D view) { if (NeedsResize() == true) { UnloadResources(); LoadResources(); } m_Composite.Update(); float width = (float)ArtworkStaticObjects.CompositeFieldImage.Width; float height = (float)ArtworkStaticObjects.CompositeFieldImage.Height; float scaleX = (2f / width); float scaleY = (2f / height); float scale = (2f / width); float offsetY = (height * scale) / 2f; m_Particles.ParticleScaleX = 1f; m_Particles.ParticleScaleY = view.WindowSize.X / view.WindowSize.Y; // (width / height);// *(1 - scale); //; * m_HeightScale; if (ArtworkStaticObjects.CompositeFieldImage.Update()) { } m_WarpGrid.Update(ArtworkStaticObjects.CompositeFieldImage, ArtworkStaticObjects.CompositeFieldImage.Width, ArtworkStaticObjects.CompositeFieldImage.Height); //m_WarpGrid.Propogate(GameConfiguration.WindowWidth, GameConfiguration.WindowHeight); ArtworkStaticObjects.Ensemble.ResetParticleCollisions(); for (int j = 0; j < m_DrawFrequency; j++) { ArtworkStaticObjects.Ensemble.VelocityVerletPropagation(ArtworkStaticObjects.ExternalField); } #region Do FFT if (ArtworkStaticObjects.Options.FFT.FFTEnabled == true) { m_ParticleCorrelationFunctionTime++; m_FFTFrequencyTime++; if (m_ParticleCorrelationFunctionTime >= ArtworkStaticObjects.Options.FFT.CorrelationFunctionUpdateFrequency) { ArtworkStaticObjects.Ensemble.UpdateVelocityAutoCorrelationFunction(); m_ParticleCorrelationFunctionTime = 0; } if (m_FFTFrequencyTime >= ArtworkStaticObjects.Options.FFT.FFTFrequency) { ArtworkStaticObjects.Ensemble.FFTVelocityAutoCorrelationFunction(); m_FFTFrequencyTime = 0; ArtworkStaticObjects.FFTScanner.ShouldScan = true; } } #endregion m_RenderContext.RenderBegin(); //m_Composite.Rectangle = new RectangleF(-1, -offsetY, 2, height * scale); m_Composite.Rectangle = new RectangleF(-1, -1, 2, 2); //m_WarpGrid.Render(m_Composite.TextureView); OscOutput output = ArtworkStaticObjects.OscControler; bool shouldSendParticleEvents = ArtworkStaticObjects.Options.FFT.ParticleEventsEnabled; for (int i = 0, ie = ArtworkStaticObjects.Ensemble.NumberOfParticles; i < ie; i++) { DSParticles3.Particle part = ArtworkStaticObjects.Ensemble.Particles[i]; float partSpeed = 1f; if ((part.Velocity.X < 10f && part.Velocity.X > -10f) && (part.Velocity.Y < 10f && part.Velocity.Y > -10f)) { SlimDX.Vector2 length = new Vector2((float)part.Velocity.X, (float)part.Velocity.Y); float speedSquared = length.LengthSquared(); if (speedSquared == float.NegativeInfinity || speedSquared <= 0) { partSpeed = 0; } else if (speedSquared < 100f) { partSpeed = speedSquared * 0.01f; } } SlimDX.Vector4 color; if (part.DidParticleCollideWithParticle() == true) { color = part.ParticleType.ParticleCollisionColor; if (shouldSendParticleEvents == true && part.ParticleType.IsSoundOn == true) { output.SendPacket((float)part.Position.X, (float)part.Position.Y, (float)part.ParticleType.ID, (float)part.VInCollisionFrame); } } else if (part.DidParticleCollideWithWall() == true) { color = part.ParticleType.WallCollisionColor; if (shouldSendParticleEvents == true && part.ParticleType.IsSoundOn == true) { output.SendPacket((float)part.Position.X, (float)part.Position.Y, (float)part.ParticleType.ID, (float)part.VInCollisionFrame); } } else { color = part.ParticleType.RenderColor; } m_Points[i].Color = color; //m_Points[i].Position = new SlimDX.Vector3(-1 + ((float)part.Position.X * scale), -offsetY + ((height - (float)part.Position.Y) * scale), 1f); m_Points[i].Position = new SlimDX.Vector3(-1 + ((float)part.Position.X * scaleX), -1 + ((height - (float)part.Position.Y) * scaleY), partSpeed); } DataBox box = GameEnvironment.Device.ImmediateContext.MapSubresource(m_Particles.Instances, SlimDX.Direct3D11.MapMode.WriteDiscard, SlimDX.Direct3D11.MapFlags.None); DataStream stream = box.Data; stream.WriteRange<StarInstanceVertex>(m_Points, 0, ArtworkStaticObjects.Ensemble.NumberOfParticles); m_Particles.InstanceCount = ArtworkStaticObjects.Ensemble.NumberOfParticles; GameEnvironment.Device.ImmediateContext.UnmapSubresource(m_Particles.Instances, 0); m_Particles.Update(view); m_Particles.ColorScale = ArtworkStaticObjects.Options.Visual.ParticleFeedbackLevel; m_Particles.ScaleDistance = 0f; m_WarpGrid.WarpVariance = ArtworkStaticObjects.Options.Visual.WarpVariance; m_WarpGrid.WarpPropagation = ArtworkStaticObjects.Options.Visual.WarpPropagation; m_WarpGrid.WarpPersistence = ArtworkStaticObjects.Options.Visual.WarpPersistence; m_WarpGrid.FeedbackLevel = ArtworkStaticObjects.Options.Visual.FeedbackLevel; m_FeedbackScene.CurrentFeedbackTexture = m_FeedbackImposters[m_ActiveImposter].TextureView; m_ActiveImposter++; if (m_ActiveImposter > 1) { m_ActiveImposter = 0; } m_FeedbackImposters[m_ActiveImposter].RenderToImposter(m_FeedbackScene, view); m_FeedbackImposters[m_ActiveImposter].Render(); m_Composite.Render(view, ArtworkStaticObjects.Options.Visual.SelfImage, ArtworkStaticObjects.Options.Visual.SelfColor); m_Particles.ScaleDistance = 1f; m_Particles.ColorScale = 1f - ArtworkStaticObjects.Options.Visual.ParticleFeedbackLevel; m_Particles.Render(view); m_RenderContext.RenderEnd(); m_TargetBox.TextureView = m_RenderContext.TextureView; formContext.RenderBegin(); //m_TargetBox.Rectangle = new RectangleF(-1, -offsetY * m_HeightScale, 2, height * scale * m_HeightScale); m_TargetBox.Rectangle = new RectangleF(-1, -1, 2, 2); //m_TargetBox.FlipHorizontal = true; m_TargetBox.Render(); }
/// <summary> /// Returns this vector projected onto another vector. /// </summary> public static Vector2 Project(this Vector2 v, Vector2 vector) { Vector2 proj; float dot = Vector2.Dot(v, vector); float invLenB = 1f / vector.LengthSquared(); proj.X = (dot * invLenB) * vector.X; proj.Y = (dot * invLenB) * vector.Y; return proj; }
public override bool ParseBytesAndExecute(byte[] data) { if (data.Length != 8 + 2 + 4 + 4 + 4 + 4 + 24 + 24 + 4) { return false; } long tid = Utilities.BytesToLong(Utilities.BytesPartial(data, 0, 8)); KeysPacketData val = (KeysPacketData)Utilities.BytesToUshort(Utilities.BytesPartial(data, 8, 2)); bool upw = val.HasFlag(KeysPacketData.UPWARD); bool downw = val.HasFlag(KeysPacketData.DOWNWARD); bool click = val.HasFlag(KeysPacketData.CLICK); bool aclick = val.HasFlag(KeysPacketData.ALTCLICK); bool use = val.HasFlag(KeysPacketData.USE); bool ileft = val.HasFlag(KeysPacketData.ITEMLEFT); bool iright = val.HasFlag(KeysPacketData.ITEMRIGHT); bool iup = val.HasFlag(KeysPacketData.ITEMUP); bool idown = val.HasFlag(KeysPacketData.ITEMDOWN); double yaw = Utilities.BytesToFloat(Utilities.BytesPartial(data, 8 + 2, 4)); double pitch = Utilities.BytesToFloat(Utilities.BytesPartial(data, 8 + 2 + 4, 4)); double x = Utilities.BytesToFloat(Utilities.BytesPartial(data, 8 + 2 + 4 + 4, 4)); double y = Utilities.BytesToFloat(Utilities.BytesPartial(data, 8 + 2 + 4 + 4 + 4, 4)); int s = 8 + 2 + 4 + 4 + 4 + 4; Location pos = Location.FromDoubleBytes(data, s); Location vel = Location.FromDoubleBytes(data, s + 24); double sow = Utilities.BytesToFloat(Utilities.BytesPartial(data, s + 24 + 24, 4)); Vector2 tmove = new Vector2(x, y); if (tmove.LengthSquared() > 1f) { tmove.Normalize(); } if (Player.Upward != upw || Player.Downward != downw || Player.Click != click || Player.AltClick != aclick || Player.Use != use || Math.Abs(Player.Direction.Yaw - yaw) > 0.05 || Math.Abs(Player.Direction.Pitch - pitch) > 0.05 || Math.Abs(tmove.X - x) > 0.05 || Math.Abs(tmove.Y - y) > 0.05) { Player.NoteDidAction(); } Player.Upward = upw; Player.Downward = downw; Player.Click = click; Player.AltClick = aclick; Player.Use = use; Player.ItemLeft = ileft; Player.ItemRight = iright; Player.ItemUp = iup; Player.ItemDown = idown; Player.LastKPI = Player.TheRegion.GlobalTickTime; Player.SprintOrWalk = sow; if (Player.Flags.HasFlag(YourStatusFlags.NO_ROTATE)) { Player.AttemptedDirectionChange.Yaw += yaw; Player.AttemptedDirectionChange.Pitch += pitch; } else { Player.Direction.Yaw = yaw; Player.Direction.Pitch = pitch; } Player.XMove = tmove.X; Player.YMove = tmove.Y; if (!Player.SecureMovement) { if (pos.IsNaN() || vel.IsNaN() || pos.IsInfinite() || vel.IsInfinite()) { return false; } Location up = new Location(0, 0, Player.CBHHeight); Location start = Player.GetPosition(); Location rel = pos - start; double len = rel.Length(); if (len > 50) // TODO: better sanity cap? { return false; } rel /= len; RayCastResult rcr; if (Player.TheRegion.SpecialCaseConvexTrace(new BoxShape(1.1f, 1.1f, 1.1f), start + up, rel, (double)len, MaterialSolidity.FULLSOLID, Player.IgnoreThis, out rcr)) { Player.Teleport(start); } else { Player.SetPosition(pos); } Player.SetVelocity(vel); // TODO: Validate velocity at all? } Player.Network.SendPacket(new YourPositionPacketOut(Player.TheRegion.GlobalTickTime, tid, Player.GetPosition(), Player.GetVelocity(), new Location(0, 0, 0), Player.CBody.StanceManager.CurrentStance, Player.pup)); return true; }
private void HandleInput(TimeSpan time) { _keyboard.Poll(); var keyboardState = _keyboard.GetCurrentState(); var multipler = keyboardState.IsPressed(Key.LeftShift) ? 10 : 1; foreach (var kv in KeyMap) { if (keyboardState.IsPressed(kv.Key)) { _camera = _camera.MoveLocal(multipler*kv.Value*50*(float) time.TotalSeconds); } } _mouse.Poll(); var state = _mouse.GetCurrentState(); if (state.Buttons[1]) { var current = new Vector2(state.X, state.Y); if (current.LengthSquared() > 0) { _camera = _camera.RotateYawPitch(new YawPitchRoll { Pitch = new Radian(current.Y/1000.0f), Yaw = new Radian(current.X/1000.0f) }); } } }
//////////////////// // Vector Functions. public static Vector2 Projection(Vector2 pBaseVector, Vector2 pProjectedVector) { return (Vector2.Dot(pBaseVector, pProjectedVector) / pBaseVector.LengthSquared()) * pBaseVector; }
void MoveToPlayer() { var vecToPlayer = new Vector2( Player.Transform.Translation.X - Transform.Translation.X, Player.Transform.Translation.Z - Transform.Translation.Z); if (vecToPlayer.LengthSquared() > Distance * Distance) { vecToPlayer.Normalize(); var position = Transform.Translation; position.X += vecToPlayer.X * ScaledSpeed; position.Z += vecToPlayer.Y * ScaledSpeed; Transform.Translation = position; } }
public override void Tick() { if (TheRegion.Delta <= 0) { return; } if (!IsSpawned) { return; } PathUpdate -= TheRegion.Delta; if (PathUpdate <= 0) { UpdatePath(); } if (Path != null) { PathMovement = true; Location spos = GetPosition(); while (Path.Length > 0 && ((Path.Peek() - spos).LengthSquared() < PathFindCloseEnough || (Path.Peek() - spos + new Location(0, 0, -1.5)).LengthSquared() < PathFindCloseEnough)) { Path.Pop(); } if (Path.Length <= 0) { Path = null; } else { Location targetdir = (Path.Peek() - spos).Normalize(); Location movegoal = Utilities.RotateVector(targetdir, (270 + Direction.Yaw) * Utilities.PI180); Vector2 movegoal2 = new Vector2((double)movegoal.X, (double)movegoal.Y); if (movegoal2.LengthSquared() > 0) { movegoal2.Normalize(); } XMove = movegoal2.X; YMove = movegoal2.Y; if (movegoal.Z > 0.4) { CBody.Jump(); } } } if (Path == null && PathMovement) { XMove = 0; YMove = 0; PathMovement = false; } while (Direction.Yaw < 0) { Direction.Yaw += 360; } while (Direction.Yaw > 360) { Direction.Yaw -= 360; } if (Direction.Pitch > 89.9f) { Direction.Pitch = 89.9f; } if (Direction.Pitch < -89.9f) { Direction.Pitch = -89.9f; } CBody.ViewDirection = Utilities.ForwardVector_Deg(Direction.Yaw, Direction.Pitch).ToBVector(); if (Upward && !IsFlying && !pup && CBody.SupportFinder.HasSupport) { CBody.Jump(); pup = true; } else if (!Upward) { pup = false; } double speedmod = new Vector2(XMove, YMove).Length() * 2; speedmod *= (1f + SprintOrWalk * 0.5f); if (ItemDoSpeedMod) { speedmod *= ItemSpeedMod; } Material mat = TheRegion.GetBlockMaterial(GetPosition() + new Location(0, 0, -0.05f)); speedmod *= mat.GetSpeedMod(); CBody.StandingSpeed = CBStandSpeed * speedmod; CBody.CrouchingSpeed = CBCrouchSpeed * speedmod; double frictionmod = 1f; frictionmod *= mat.GetFrictionMod(); CBody.SlidingForce = CBSlideForce * frictionmod * Mass; CBody.AirForce = CBAirForce * frictionmod * Mass; CBody.TractionForce = CBTractionForce * frictionmod * Mass; CBody.VerticalMotionConstraint.MaximumGlueForce = CBGlueForce * Mass; if (CurrentSeat == null) { Vector3 movement = new Vector3(XMove, YMove, 0); if (Upward && IsFlying) { movement.Z = 1; } else if (Downward && IsFlying) { movement.Z = -1; } if (movement.LengthSquared() > 0) { movement.Normalize(); } if (Downward) { CBody.StanceManager.DesiredStance = Stance.Crouching; } else { CBody.StanceManager.DesiredStance = DesiredStance; } CBody.HorizontalMotionConstraint.MovementDirection = new Vector2(movement.X, movement.Y); if (IsFlying) { Location forw = Utilities.RotateVector(new Location(-movement.Y, movement.X, movement.Z), Direction.Yaw * Utilities.PI180, Direction.Pitch * Utilities.PI180); SetPosition(GetPosition() + forw * TheRegion.Delta * CBStandSpeed * 2 * speedmod); CBody.HorizontalMotionConstraint.MovementDirection = Vector2.Zero; Body.LinearVelocity = new Vector3(0, 0, 0); } } else { CurrentSeat.HandleInput(this); } base.Tick(); RigidTransform transf = new RigidTransform(Vector3.Zero, Body.Orientation); BoundingBox box; Body.CollisionInformation.Shape.GetBoundingBox(ref transf, out box); MinZ = box.Min.Z; }