예제 #1
0
    public override void _PhysicsProcess(float delta)
    {
        if (_target == null)
        {
            return;
        }

        if (Input.GetMouseButtonMask() > 0)
        {
            Input.SetMouseMode(Input.MouseMode.Captured);
        }
        if (_hasInput == false)
        {
            _mouse = Vector2.Zero;
        }

        if (Input.GetMouseMode() == Input.MouseMode.Captured && _hasInput)
        {
            _hasInput = false;
            //Get updates from the input
            var joystick = new Vector2(
                Input.GetJoyAxis(0, 0),
                Input.GetJoyAxis(0, 1)
                );

            var input = joystick;
            if (input.LengthSquared() > 0 == false)
            {
                input = _mouse;
            }

            input *= delta;

            yaw   += cameraSpeed * input.x * (invertX ? -1 : 1);
            pitch += cameraSpeed * input.y * (invertY ? 1 : -1);
        }

        float actualDistance = distance;        // + (target.GetComponent<Marble>().radius * 2.0f);

        //Easy lock to the object
        Vector3 position = _target.Translation;

        //Rotate by pitch and yaw (and not roll, oh god my stomach)
        var rotation = new Quat(Vector3.Up, yaw);

        rotation *= new Quat(Vector3.Right, pitch);

        //Offset for orbiting
        position += Multiply(rotation, new Vector3(0.0f, 0.0f, actualDistance));

        var euler = rotation.GetEuler();

        //Lame way of updating the transform
        Rotation    = new Vector3(euler.x, euler.y, 0);
        Translation = position;
    }
        internal void CreateAnimation(
            string animationName,
            IEnumerable <MWAnimationKeyframe> keyframes,
            IEnumerable <MWAnimationEvent> events,
            MWAnimationWrapMode wrapMode,
            MWSetAnimationStateOptions initialState,
            bool isInternal,
            bool managed,
            Action onCreatedCallback)
        {
            var continuation = new MWContinuation(AttachedActor, null, (result) =>
            {
                var animationPlayer = GetOrCreateGodotAnimationPlayer(animationName);
                var animation       = new GodotAnimation();
                animation.Loop      = wrapMode.IsInterpolationLoopWrap();

                var curves = new Dictionary <string, int>();

                int GetOrCreateCurve(Type type, string propertyName)
                {
                    if (!curves.TryGetValue(propertyName, out int trackIndex))
                    {
                        trackIndex = animation.AddTrack(GodotAnimation.TrackType.Bezier);
                        curves.Add(propertyName, trackIndex);
                    }

                    return(trackIndex);
                }

                void AddFloatPatch(Type type, string propertyName, float time, float?value)
                {
                    if (value.HasValue)
                    {
                        var trackIndex = GetOrCreateCurve(type, propertyName);
                        animation.TrackSetPath(trackIndex, propertyName);
                        animation.BezierTrackInsertKey(trackIndex, time, value.Value);
                    }
                }

                void AddVector3Patch(Type type, string propertyName, float time, Vector3Patch value)
                {
                    AddFloatPatch(type, String.Format("{0}:x", propertyName), time, value?.X);
                    AddFloatPatch(type, String.Format("{0}:y", propertyName), time, value?.Y);
                    AddFloatPatch(type, String.Format("{0}:z", propertyName), time, value?.Z);
                }

                void AddQuaternionPatch(Type type, string propertyName, float time, QuaternionPatch value)
                {
                    AddFloatPatch(type, String.Format("{0}:x", propertyName), time, value?.X);
                    AddFloatPatch(type, String.Format("{0}:y", propertyName), time, value?.Y);
                    AddFloatPatch(type, String.Format("{0}:z", propertyName), time, value?.Z);
                    AddFloatPatch(type, String.Format("{0}:w", propertyName), time, value?.W);
                }

                void AddTransformPatch(float time, ScaledTransformPatch value)
                {
                    // Work around a Unity bug/feature where all position components must be specified
                    // in the keyframe or the missing fields get set to zero.
                    Vector3Patch position = value?.Position;
                    if (position != null && position.IsPatched())
                    {
                        if (!position.X.HasValue)
                        {
                            position.X = Transform.origin.x;
                        }
                        if (!position.Y.HasValue)
                        {
                            position.Y = Transform.origin.y;
                        }
                        if (!position.Z.HasValue)
                        {
                            position.Z = Transform.origin.z;
                        }
                    }
                    // Work around a Unity bug/feature where all scale components must be specified
                    // in the keyframe or the missing fields get set to one.
                    Vector3Patch scale = value?.Scale;
                    if (scale != null && scale.IsPatched())
                    {
                        if (!scale.X.HasValue)
                        {
                            scale.X = Scale.x;
                        }
                        if (!scale.Y.HasValue)
                        {
                            scale.Y = Scale.y;
                        }
                        if (!scale.Z.HasValue)
                        {
                            scale.Z = Scale.z;
                        }
                    }
                    AddVector3Patch(typeof(Transform), "..:translation", time, value?.Position);
                    var ratation = value?.Rotation;
                    var quat     = new Quat(ratation.X.Value, ratation.Y.Value, ratation.Z.Value, ratation.W.Value);
                    var vector3  = quat.GetEuler();
                    AddVector3Patch(typeof(Transform), "..:rotation_degrees", time, new Vector3Patch(vector3));
                    AddVector3Patch(typeof(Transform), "..:scale", time, value?.Scale);
                }

                void AddActorPatch(float time, ActorPatch value)
                {
                    AddTransformPatch(time, value?.Transform.Local);
                }

                void AddKeyframe(MWAnimationKeyframe keyframe)
                {
                    AddActorPatch(keyframe.Time, keyframe.Value);
                    if (animation.Length < keyframe.Time)
                    {
                        animation.Length = keyframe.Time;
                    }
                }

                foreach (var keyframe in keyframes)
                {
                    AddKeyframe(keyframe);
                }

                _animationData[animationName] = new AnimationData()
                {
                    IsInternal = isInternal,
                    Managed    = managed
                };

                float initialTime   = 0f;
                float initialSpeed  = 1f;
                bool initialEnabled = false;

                if (initialState != null)
                {
                    initialTime    = initialState.Time ?? initialTime;
                    initialSpeed   = initialState.Speed ?? initialSpeed;
                    initialEnabled = initialState.Enabled ?? initialEnabled;
                }

                animationPlayer.AddAnimation(animationName, animation);
                animationPlayer.AssignedAnimation = animationName;

                SetAnimationState(animationName, initialTime, initialSpeed, initialEnabled);

                onCreatedCallback?.Invoke();
            });

            continuation.Start();
        }
예제 #3
0
    void _advancePhysics(ref float dt)
    {
        List <CollisionInfo> contacts = new List <CollisionInfo>();
        Vector3 pos      = Translation;
        Quat    rot      = new Quat(Rotation);
        Vector3 velocity = Velocity;
        Vector3 omega    = AngularVelocity;

        if (useGodotContacts)
        {
            var root = GetTree().Root.GetNodeOrNull("Spatial/Collisions");
            if (root != null)
            {
                foreach (Node item in root.GetChildren())
                {
                    _recycleNodes.Enqueue(item);
                    root.RemoveChild(item);
                }
            }

            var collisionShapes = new List <CollisionShape>(5);
            while (MoveAndCollide(Vector3.Zero, true, true, true) is KinematicCollision collision)
            {
                var shape = (CollisionShape)collision.ColliderShape;
                collisionShapes.Add(shape);
                shape.Disabled = true;

                var penetration = Translation.DistanceTo(collision.Position) - Radius;
                var col         = new CollisionInfo {
                    Penetration = penetration,
                    Restitution = 1,
                    Friction    = 1,
                    Normal      = collision.Normal,
                    Point       = collision.Position
                };

                /*if (contact.otherCollider.attachedRigidbody != null) {
                 *      col.Collider = contact.otherCollider;
                 *      col.Velocity = contact.otherCollider.attachedRigidbody.GetPointVelocity(contact.point);
                 * }*/
                contacts.Add(col);

                if (root != null)                // draw debug lol
                {
                    Spatial spatial = null;
                    if (_recycleNodes.Count > 0)
                    {
                        spatial = (Spatial)_recycleNodes.Dequeue();
                    }
                    if (spatial == null)
                    {
                        spatial = new Spatial();
                        var meshInstance = new MeshInstance();
                        meshInstance.Mesh  = new SphereMesh();
                        meshInstance.Scale = new Vector3(0.1f, 0.1f, 0.1f);
                        spatial.AddChild(meshInstance);
                    }
                    spatial.Translation = Translation + collision.Normal * 0.3f;
                    root.AddChild(spatial);
                }
            }
            foreach (var item in collisionShapes)
            {
                item.Disabled = false;
            }
        }

        _updateMove(ref dt, ref velocity, ref omega, contacts);
        // velocity += _gravityDir * _gravity * dt;

        _updateIntegration(dt, ref pos, ref rot, velocity, omega);

        if (useGodotContacts)
        {
            Translation = pos;
            Rotation    = rot.GetEuler();
        }
        else
        {
            Translation = pos;
            Rotation    = rot.GetEuler();
        }
        Velocity        = velocity;
        AngularVelocity = omega;
    }