Пример #1
0
        public void adjust_offset(AFrame offset, double quantum)
        {
            if (PhysicsObj == null || TargetID == 0 || !Initialized)
            {
                return;
            }

            var target         = PhysicsObj.GetObjectA(TargetID);
            var targetPosition = target == null ? TargetPosition : target.Position;

            offset.Origin   = PhysicsObj.Position.GetOffset(targetPosition);
            offset.Origin   = PhysicsObj.Position.GlobalToLocalVec(offset.Origin);
            offset.Origin.Z = 0.0f;

            var radius = PhysicsObj.GetRadius();
            var dist   = Position.CylinderDistanceNoZ(radius, PhysicsObj.Position, TargetRadius, targetPosition) - StickyRadius;

            if (Vec.NormalizeCheckSmall(ref offset.Origin))
            {
                offset.Origin = Vector3.Zero;
            }

            var speed   = 0.0f;
            var minterp = PhysicsObj.get_minterp();

            if (minterp != null)
            {
                speed = minterp.get_max_speed() * 5.0f;
            }

            if (speed < PhysicsGlobals.EPSILON)
            {
                speed = 15.0f;
            }

            var delta = speed * (float)quantum;

            if (delta >= Math.Abs(dist))
            {
                delta = dist;
            }

            offset.Origin *= delta;

            var curHeading    = PhysicsObj.Position.Frame.get_heading();
            var targetHeading = PhysicsObj.Position.heading(targetPosition);
            var heading       = targetHeading - curHeading;

            if (Math.Abs(heading) < PhysicsGlobals.EPSILON)
            {
                heading = 0.0f;
            }
            if (heading < -PhysicsGlobals.EPSILON)
            {
                heading += 360.0f;
            }

            //Console.WriteLine($"StickyManager.AdjustOffset(targetHeading={targetHeading}, curHeading={curHeading}, setHeading={heading})");
            offset.set_heading(heading);
        }
Пример #2
0
        public static AFrame Combine(AFrame a, AFrame b, Vector3 scale)
        {
            var frame = new AFrame();

            frame.Origin      = a.Origin + Vector3.Transform(b.Origin * scale, a.Orientation);
            frame.Orientation = Quaternion.Multiply(a.Orientation, b.Orientation);
            return(frame);
        }
Пример #3
0
        public static AFrame Combine(AFrame a, AFrame b)
        {
            var frame = new AFrame();

            frame.Origin      = a.Origin + b.Origin;
            frame.Orientation = Quaternion.Multiply(a.Orientation, b.Orientation);
            return(frame);
        }
Пример #4
0
        public bool close_rotation(AFrame a, AFrame b)
        {
            var ao = a.Orientation;
            var bo = b.Orientation;

            return(Math.Abs(ao.X - bo.X) < PhysicsGlobals.EPSILON &&
                   Math.Abs(ao.Y - bo.Y) < PhysicsGlobals.EPSILON &&
                   Math.Abs(ao.Z - bo.Z) < PhysicsGlobals.EPSILON &&
                   Math.Abs(ao.W - bo.W) < PhysicsGlobals.EPSILON);
        }
Пример #5
0
 public void Update(float quantum, ref AFrame offsetFrame)
 {
     if (AnimList.First != null)
     {
         update_internal(quantum, ref CurrAnim, ref FrameNumber, ref offsetFrame);
         apricot();
     }
     else if (offsetFrame != null)
     {
         apply_physics(offsetFrame, quantum, quantum);
     }
 }
Пример #6
0
 public void Update(float quantum, AFrame frame)
 {
     if (AnimList == null && AnimList.Count != 0)
     {
         update_internal(quantum, CurrAnim.Value, FrameNumber, frame);
         apricot();
     }
     else if (frame != null)
     {
         apply_physics(frame, quantum, quantum);
     }
 }
Пример #7
0
        /// <summary>
        /// Performs the translation and rotation on the frame
        /// </summary>
        public void apply_physics(AFrame frame, float quantum, float sign)
        {
            if (sign >= 0.0)
            {
                quantum = Math.Abs(quantum);
            }
            else
            {
                quantum = -Math.Abs(quantum);
            }

            frame.Origin += Velocity * quantum;
            frame.Rotate(Omega * quantum);
        }
Пример #8
0
        public void adjust_offset(AFrame offset, double quantum)
        {
            if (TargetID == 0 || !Initialized)
            {
                return;
            }

            var target         = PhysicsObj.GetObjectA(TargetID);
            var targetPosition = target == null ? TargetPosition : target.Position;

            offset.Origin   = PhysicsObj.Position.GetOffset(targetPosition);
            offset.Origin   = PhysicsObj.Position.GlobalToLocalVec(offset.Origin);
            offset.Origin.Z = 0.0f;

            var radius = PhysicsObj.GetRadius();
            var dist   = Position.CylinderDistanceNoZ(radius, PhysicsObj.Position, TargetRadius, targetPosition) - StickyRadius;

            CollisionInfo.NormalizeCheckSmall(ref offset.Origin);

            var speed   = 0.0f;
            var minterp = PhysicsObj.get_minterp();

            if (minterp != null)
            {
                speed = minterp.get_max_speed() * 5.0f;
            }

            var delta = speed * (float)quantum;

            if (delta >= Math.Abs(dist))
            {
                delta = dist;
            }

            offset.Origin *= delta;

            var heading = PhysicsObj.Position.heading(targetPosition) - PhysicsObj.Position.Frame.get_heading();

            if (Math.Abs(heading) < PhysicsGlobals.EPSILON)
            {
                heading = 0.0f;
            }
            if (heading < -PhysicsGlobals.EPSILON)
            {
                heading += 360.0f;
            }

            offset.set_heading(heading);
        }
Пример #9
0
 public void AdjustOffset(AFrame frame, double quantum)
 {
     if (InterpolationManager != null)
     {
         InterpolationManager.adjust_offset(frame, quantum);
     }
     if (StickyManager != null)
     {
         StickyManager.adjust_offset(frame, quantum);
     }
     if (ConstraintManager != null)
     {
         ConstraintManager.adjust_offset(frame, quantum);
     }
 }
Пример #10
0
 public void advance_to_next_animation_inner(float timeElapsed, AnimSequenceNode currAnim, double frameNum, AFrame frame, bool checkFrame, bool firstCheck)
 {
     if (frame != null && checkFrame)
     {
         if (currAnim.Anim.PosFrames.Count > 0)
         {
             if (firstCheck)
             {
                 frame.Subtract(currAnim.get_pos_frame((int)Math.Floor(frameNum)));
             }
             else
             {
                 frame = AFrame.Combine(frame, currAnim.get_pos_frame((int)Math.Floor(frameNum)));
             }
         }
         if (Math.Abs(currAnim.Framerate) > PhysicsGlobals.EPSILON)
         {
             apply_physics(frame, 1.0f / currAnim.Framerate, timeElapsed);
         }
     }
 }
Пример #11
0
        public void adjust_offset(AFrame offset, double quantum)
        {
            if (PhysicsObj == null || !IsConstrained)
            {
                return;
            }

            if (PhysicsObj.TransientState.HasFlag(TransientStateFlags.Contact))
            {
                if (ConstraintPosOffset < ConstraintDistanceMax)
                {
                    if (ConstraintPosOffset > ConstraintDistanceStart)
                    {
                        offset.Origin *= (ConstraintDistanceMax - ConstraintPosOffset) / (ConstraintDistanceMax - ConstraintDistanceStart);
                    }
                }
                else
                {
                    offset.Origin = Vector3.Zero;
                }
            }
            ConstraintPosOffset = offset.Origin.Length();
        }
Пример #12
0
        public void update_internal(float timeElapsed, ref LinkedListNode <AnimSequenceNode> animNode, ref float frameNum, ref AFrame frame)
        {
            var currAnim = animNode.Value;

            var framerate = currAnim.Framerate;
            var frametime = framerate * timeElapsed;

            var lastFrame = (int)Math.Floor(frameNum);

            frameNum += frametime;
            var frameTimeElapsed = 0.0f;
            var animDone         = false;

            if (frametime > 0.0f)
            {
                if (currAnim.get_high_frame() < Math.Floor(frameNum))
                {
                    var frameOffset = frameNum - currAnim.get_high_frame() - 1.0f;
                    if (frameOffset < 0.0f)
                    {
                        frameOffset = 0.0f;
                    }

                    if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                    {
                        frameTimeElapsed = frameOffset / framerate;
                    }

                    frameNum = currAnim.get_high_frame();
                    animDone = true;
                }
                while (Math.Floor(frameNum) > lastFrame)
                {
                    if (frame != null)
                    {
                        if (currAnim.Anim.PosFrames != null)
                        {
                            frame = AFrame.Combine(frame, currAnim.get_pos_frame(lastFrame));
                        }

                        if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                        {
                            apply_physics(frame, 1.0f / framerate, timeElapsed);
                        }
                    }

                    execute_hooks(currAnim.get_part_frame(lastFrame), AnimationHookDir.Forward);
                    lastFrame++;
                }
            }
            else if (frametime < 0.0f)
            {
                if (currAnim.get_low_frame() > Math.Floor(frameNum))
                {
                    var frameOffset = frameNum - currAnim.get_low_frame();
                    if (frameOffset > 0.0f)
                    {
                        frameOffset = 0.0f;
                    }

                    if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                    {
                        frameTimeElapsed = frameOffset / framerate;
                    }

                    frameNum = currAnim.get_low_frame();
                    animDone = true;
                }
                while (Math.Floor(frameNum) < lastFrame)
                {
                    if (frame != null)
                    {
                        if (currAnim.Anim.PosFrames != null)
                        {
                            frame.Subtract(currAnim.get_pos_frame(lastFrame));
                        }

                        if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                        {
                            apply_physics(frame, 1.0f / framerate, timeElapsed);
                        }
                    }

                    execute_hooks(currAnim.get_part_frame(lastFrame), AnimationHookDir.Backward);
                    lastFrame--;
                }
            }
            else
            {
                if (frame != null && Math.Abs(timeElapsed) > PhysicsGlobals.EPSILON)
                {
                    apply_physics(frame, timeElapsed, timeElapsed);
                }
            }

            if (!animDone)
            {
                return;
            }

            if (HookObj != null)
            {
                var node = AnimList.First;
                if (!node.Equals(FirstCyclic))
                {
                    var animDoneHook = new AnimDoneHook();  // static?
                    HookObj.add_anim_hook(animDoneHook);
                }
            }

            advance_to_next_animation(timeElapsed, ref animNode, ref frameNum, ref frame);
            timeElapsed = frameTimeElapsed;

            // loop to next anim
            update_internal(timeElapsed, ref animNode, ref frameNum, ref frame);
        }
Пример #13
0
 public bool IsQuaternionEqual(AFrame frame)
 {
     return(Orientation.Equals(frame.Orientation));
 }
Пример #14
0
        public void adjust_offset(AFrame frame, double quantum)
        {
            if (PositionQueue.Count == 0 || PhysicsObj == null || !PhysicsObj.TransientState.HasFlag(TransientStateFlags.Contact))
            {
                return;
            }

            var first = PositionQueue.First();

            if (first.Type == InterpolationNodeType.JumpType || first.Type == InterpolationNodeType.VelocityType)
            {
                return;
            }

            var dist = PhysicsObj.Position.Distance(first.Position);

            if (dist < 0.05f)
            {
                NodeCompleted(true);
                return;
            }
            var maxSpeed = 0.0f;
            var minterp  = PhysicsObj.get_minterp();

            if (minterp != null)
            {
                if (UseAdjustedSpeed)
                {
                    maxSpeed = minterp.get_adjusted_max_speed() * 2.0f;
                }
                else
                {
                    maxSpeed = minterp.get_max_speed() * 2.0f;
                }
            }
            if (maxSpeed < PhysicsGlobals.EPSILON)
            {
                maxSpeed = MaxInterpolatedVelocity;
            }

            var delta = OriginalDistance - dist;

            ProgressQuantum += (float)quantum;
            FrameCounter++;

            if (FrameCounter < 5 || (PhysicsObj.get_sticky_object() != 0 ||
                                     delta > PhysicsGlobals.EPSILON && delta / ProgressQuantum / maxSpeed >= 0.3f))
            {
                if (FrameCounter >= 5)
                {
                    FrameCounter     = 0;
                    ProgressQuantum  = 0.0f;
                    OriginalDistance = dist;
                }

                var offset     = first.Position.Subtract(PhysicsObj.Position);
                var maxQuantum = maxSpeed * quantum;
                var distance   = offset.Origin.Length();

                if (distance <= 0.05f)
                {
                    NodeCompleted(true);
                }

                if (distance > maxQuantum)
                {
                    offset.Origin *= (float)maxQuantum / distance;
                }

                if (KeepHeading)
                {
                    offset.set_heading(0.0f);
                }

                frame = offset;
                return;
            }
            NodeFailCounter++;
            NodeCompleted(false);
        }
Пример #15
0
 public void InterpolateRotation(AFrame from, AFrame to, float t)
 {
     Orientation = Quaternion.Lerp(from.Orientation, to.Orientation, t);
 }
Пример #16
0
 public bool IsEqual(AFrame frame)
 {
     // implement IEquatable
     return(frame.Equals(this));
 }
Пример #17
0
 public void Combine(AFrame a, AFrame b, Vector3 scale)
 {
     Origin      += a.Origin + b.Origin;
     Orientation *= Quaternion.Multiply(a.Orientation, b.Orientation);
 }
Пример #18
0
 public void InterpolateOrigin(AFrame from, AFrame to, float t)
 {
     Origin = Vector3.Lerp(from.Origin, to.Origin, t);
 }
Пример #19
0
        public void advance_to_next_animation(float timeElapsed, AnimSequenceNode currAnim, double frameNum, AFrame frame)
        {
            var firstFrame  = currAnim.Framerate >= 0.0f;
            var secondFrame = currAnim.Framerate < 0.0f;

            if (timeElapsed >= 0.0)
            {
                firstFrame  = currAnim.Framerate < 0.0f;
                secondFrame = currAnim.Framerate > 0.0f;
            }
            advance_to_next_animation_inner(timeElapsed, currAnim, frameNum, frame, firstFrame);

            if (currAnim.GetNext() != null)
            {
                currAnim = currAnim.GetNext();
            }
            else
            {
                currAnim = FirstCyclic.Value;
            }

            // ref?
            frameNum = currAnim.get_starting_frame();

            advance_to_next_animation_inner(timeElapsed, currAnim, frameNum, frame, secondFrame);
        }
Пример #20
0
 public AFrame(AFrame frame)
 {
     Origin      = new Vector3(frame.Origin.X, frame.Origin.Y, frame.Origin.Z);
     Orientation = new Quaternion(frame.Orientation.X, frame.Orientation.Y, frame.Orientation.Z, frame.Orientation.W);
 }
Пример #21
0
 public void AdjustOffset(AFrame frame, double quantum)
 {
 }
Пример #22
0
        public void advance_to_next_animation(float timeElapsed, ref LinkedListNode <AnimSequenceNode> animNode, ref float frameNum, ref AFrame frame)
        {
            var currAnim = animNode.Value;

            if (timeElapsed >= 0.0f)
            {
                if (frame != null && currAnim.Framerate < 0.0f)
                {
                    if (currAnim.Anim.PosFrames.Count > 0)
                    {
                        frame.Subtract(currAnim.get_pos_frame((int)frameNum));
                    }
                    if (Math.Abs(currAnim.Framerate) > PhysicsGlobals.EPSILON)
                    {
                        apply_physics(frame, 1.0f / currAnim.Framerate, timeElapsed);
                    }
                }
                if (animNode.Next != null)
                {
                    animNode = animNode.Next;
                }
                else
                {
                    animNode = FirstCyclic;
                }

                currAnim = animNode.Value;

                frameNum = currAnim.get_starting_frame();

                if (frame != null && currAnim.Framerate > 0.0f)
                {
                    if (currAnim.Anim.PosFrames.Count > 0)
                    {
                        frame = AFrame.Combine(frame, currAnim.get_pos_frame((int)frameNum));
                    }
                    if (Math.Abs(currAnim.Framerate) > PhysicsGlobals.EPSILON)
                    {
                        apply_physics(frame, 1.0f / currAnim.Framerate, timeElapsed);
                    }
                }
            }
            else
            {
                if (frame != null && currAnim.Framerate >= 0.0f)
                {
                    if (currAnim.Anim.PosFrames.Count > 0)
                    {
                        frame.Subtract(currAnim.get_pos_frame((int)frameNum));
                    }
                    if (Math.Abs(currAnim.Framerate) > PhysicsGlobals.EPSILON)
                    {
                        apply_physics(frame, 1.0f / currAnim.Framerate, timeElapsed);
                    }
                }
                if (animNode.Previous != null)
                {
                    animNode = animNode.Previous;
                }
                else
                {
                    animNode = animNode.List.Last;
                }

                currAnim = animNode.Value;

                frameNum = currAnim.get_ending_frame();

                if (frame != null && currAnim.Framerate < 0.0f)
                {
                    if (currAnim.Anim.PosFrames.Count > 0)
                    {
                        frame = AFrame.Combine(frame, currAnim.get_pos_frame((int)frameNum));
                    }
                    if (Math.Abs(currAnim.Framerate) > PhysicsGlobals.EPSILON)
                    {
                        apply_physics(frame, 1.0f / currAnim.Framerate, timeElapsed);
                    }
                }
            }
        }
Пример #23
0
 public AFrame Combine(AFrame a, AFrame b, Vector3 scale)
 {
     return(null);
 }
Пример #24
0
 public static AFrame Combine(AFrame a, AFrame b)
 {
     return(null);
 }
Пример #25
0
 public void Subtract(AFrame frame)
 {
     Origin     -= Vector3.Transform(frame.Origin, frame.Orientation);
     Orientation = Quaternion.Multiply(Orientation, frame.Orientation);
 }
Пример #26
0
        public bool FindPlacementPos()
        {
            // refactor me
            SpherePath.SetCheckPos(SpherePath.CurPos, SpherePath.CurCell);

            CollisionInfo.SlidingNormalValid  = false;
            CollisionInfo.ContactPlaneValid   = false;
            CollisionInfo.ContactPlaneIsWater = false;

            var transitionState = TransitionalInsert(3);

            var redo = 0;

            transitionState = ValidatePlacementTransition(transitionState, ref redo);

            if (transitionState == TransitionState.OK)
            {
                return(true);
            }

            if (!SpherePath.PlacementAllowsSliding)
            {
                return(false);
            }

            var adjustDist = 4.0f;
            var adjustRad  = adjustDist;
            var sphereRad  = SpherePath.LocalSphere[0].Radius;

            var fakeSphere = false;

            if (sphereRad < 0.125f)
            {
                fakeSphere = true;
                adjustRad  = 2.0f;
            }
            else if (sphereRad < 0.48f)
            {
                sphereRad = 0.48f;
            }

            var movementDelta = sphereRad;

            var fNumSteps = 4.0f / movementDelta;

            if (fakeSphere)
            {
                fNumSteps *= 0.5f;
            }

            if (fNumSteps <= 1.0f)
            {
                return(false);
            }

            var numSteps       = (int)Math.Ceiling(fNumSteps);
            var distPerStep    = adjustRad / numSteps;
            var radiansPerStep = (float)(Math.PI * distPerStep / sphereRad);

            var totalDist = 0.0f;
            var totalRad  = 0.0f;

            for (var i = 0; i < numSteps; i++)
            {
                totalDist += distPerStep;
                totalRad  += radiansPerStep;

                var rad = (int)Math.Ceiling(totalRad);
                rad *= 2;
                var angle = 360.0f / rad;

                var frame = new AFrame();

                for (var j = 0; j < rad; j++)
                {
                    SpherePath.SetCheckPos(SpherePath.CurPos, SpherePath.CurCell);
                    frame.set_heading(angle * j);
                    var offset = frame.get_vector_heading() * totalDist;
                    SpherePath.GlobalOffset = AdjustOffset(offset);
                    if (SpherePath.GlobalOffset.Length() >= PhysicsGlobals.EPSILON)
                    {
                        SpherePath.AddOffsetToCheckPos(SpherePath.GlobalOffset);

                        // possibly reset by AdjustOffset
                        CollisionInfo.SlidingNormalValid  = false;
                        CollisionInfo.ContactPlaneValid   = false;
                        CollisionInfo.ContactPlaneIsWater = false;

                        transitionState = TransitionalInsert(3);
                        transitionState = ValidatePlacementTransition(transitionState, ref redo);

                        if (transitionState == TransitionState.OK)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Пример #27
0
 public void Update(double quantum, AFrame offsetFrame)
 {
 }