예제 #1
0
파일: WMath.cs 프로젝트: Arekva/winecrash
        public static double DeltaAngle(double current, double target)
        {
            double delta = WMath.Repeat((target - current), 360.0F);

            if (delta > 180.0F)
            {
                delta -= 360.0F;
            }
            return(delta);
        }
예제 #2
0
        public Sweep SweepCollide(AABBCollider colliding, Vector3D collidingVelocity, AABBCollider collider)
        {
            AABB     box   = colliding.AABB;
            AABB     col   = collider.AABB;
            Vector3D delta = collidingVelocity;

            Sweep sweep = new Sweep();

            if (delta == Vector3D.Zero)
            {
                sweep.Position = box.Position;
                sweep.Hit      = this.Collide(colliding, collider);
                if (sweep.Hit.HasHit)
                {
                    sweep.Hit.Time = 0.0D;
                    sweep.Time     = 0.0D;
                }
                else
                {
                    sweep.Time = 1.0;
                }
                return(sweep);
            }

            sweep.Hit = new RayBoxCollisionProvider().Collide(new Ray(box.Position, delta, delta.Length), collider, box.Extents);

            if (sweep.Hit.HasHit)
            {
                sweep.Time     = WMath.Clamp(sweep.Hit.Time - Physics.Epsilon, 0, 1);
                sweep.Position = box.Position + delta * sweep.Time;

                Vector3D direction = delta.Normalized;

                sweep.Hit.Position = new Vector3D(
                    WMath.Clamp(sweep.Hit.Position.X + direction.X * box.Extents.X, col.Position.X - col.Extents.X,
                                col.Position.X + col.Extents.X),
                    WMath.Clamp(sweep.Hit.Position.Y + direction.Y * box.Extents.Y, col.Position.Y - col.Extents.Y,
                                col.Position.Y + col.Extents.Y),
                    WMath.Clamp(sweep.Hit.Position.Z + direction.Z * box.Extents.Z, col.Position.Z - col.Extents.Z,
                                col.Position.Z + col.Extents.Z)
                    );
            }
            else
            {
                sweep.Position = box.Position + delta;
                sweep.Time     = 1.0D;
            }


            return(sweep);
        }
예제 #3
0
        public Hit Collide(Ray colliding, AABBCollider collider, Vector3D padding)
        {
            Vector3D pos   = colliding.Origin;
            Vector3D delta = colliding.Direction * colliding.Length;

            AABB aabb = collider.AABB;


            Vector3D scale = new Vector3D(1.0D / delta.X, 1.0 / delta.Y, 1.0 / delta.Z);

            int signX = Math.Sign(scale.X);
            int signY = Math.Sign(scale.Y);
            int signZ = Math.Sign(scale.Z);

            double nearTimeX = (aabb.Position.X - signX * (aabb.Extents.X + padding.X) - pos.X) * scale.X;
            double nearTimeY = (aabb.Position.Y - signY * (aabb.Extents.Y + padding.Y) - pos.Y) * scale.Y;
            double nearTimeZ = (aabb.Position.Z - signZ * (aabb.Extents.Z + padding.Z) - pos.Z) * scale.Z;
            double farTimeX  = (aabb.Position.X + signX * (aabb.Extents.X + padding.X) - pos.X) * scale.X;
            double farTimeY  = (aabb.Position.Y + signY * (aabb.Extents.Y + padding.Y) - pos.Y) * scale.Y;
            double farTimeZ  = (aabb.Position.Z + signZ * (aabb.Extents.Z + padding.Z) - pos.Z) * scale.Z;

            if (nearTimeX > farTimeY || nearTimeX > farTimeZ ||
                nearTimeY > farTimeX || nearTimeY > farTimeZ ||
                nearTimeZ > farTimeX || nearTimeZ > farTimeY)
            {
                return(new Hit());
            }

            double nearTime = Math.Max(Math.Max(nearTimeX, nearTimeY), nearTimeZ);
            double farTime  = Math.Max(Math.Max(farTimeX, farTimeY), farTimeZ);

            if (nearTime >= 1 || farTime <= 0)
            {
                return(new Hit());
            }

            Hit hit = new Hit(collider)
            {
                Time = WMath.Clamp(nearTime, 0, 1)
            };

            Vector3D n = Vector3D.Zero;



            hit.Delta    = -delta * (1.0 - hit.Time);
            hit.Position = pos + delta * hit.Time;
            hit.Normal   = GetNormalFromPoint(collider, hit.Position);
            return(hit);
        }
예제 #4
0
파일: WRandom.cs 프로젝트: Arekva/winecrash
        public Vector2D NextDirection2D()
        {
            double rad = WMath.Remap(NextDouble(), 0, 1, -Math.PI, Math.PI);

            return(new Vector2D(Math.Cos(rad), Math.Sin(rad)).Normalized);
        }