Esempio n. 1
0
        new public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            if (!IsActive)
            {
                return;
            }

            // How would this get a NaN anyway?
            if (MathFunctions.HasNan(Velocity))
            {
                Velocity = Vector3.Zero;
            }

            // If we're not sleeping and moving very slowly, go to sleep.
            if (!IsSleeping && Velocity.LengthSquared() < 0.0225f)
            {
                SleepTimer.Update(gameTime);
                if (SleepTimer.HasTriggered)
                {
                    applyGravityThisFrame = false;
                    Velocity   = Vector3.Zero;
                    IsSleeping = true;
                }
            }
            else
            {
                SleepTimer.Reset();
                IsSleeping = false;
            }

            // If not sleeping, update physics.
            if (!IsSleeping || overrideSleepThisFrame)
            {
                overrideSleepThisFrame = false;

                float dt = (float)(gameTime.ElapsedGameTime.TotalSeconds);

                // Calculate the number of timesteps to apply.
                int numTimesteps = Math.Min(MaxTimesteps, Math.Max((int)(dt / FixedDT), 1));

                float velocityLength = Math.Max(Velocity.Length(), 1.0f);

                // Prepare expanded world bounds.
                BoundingBox worldBounds = chunks.Bounds;
                worldBounds.Max.Y += 50;

                // For each timestep, move and collide.
                for (int n = 0; n < numTimesteps * velocityLength; n++)
                {
                    // Move by a fixed amount.
                    Move(FixedDT / velocityLength);

                    // Get the current voxel.
                    chunks.ChunkData.GetVoxel(Position, ref CurrentVoxel);
                    if (CurrentVoxel != null && CurrentVoxel.Chunk != null)
                    {
                        Vector3 gridPos = CurrentVoxel.GridPosition;
                        CurrentVoxel.Chunk.GetNeighborsSuccessors(VoxelChunk.ManhattanSuccessors, (int)gridPos.X,
                                                                  (int)gridPos.Y, (int)gridPos.Z, Neighbors);
                    }

                    // Collide with the world.
                    HandleCollisions(chunks, FixedDT);

                    Matrix transform = LocalTransform;
                    // Avoid leaving the world.
                    if (worldBounds.Contains(LocalTransform.Translation + Velocity * dt) != ContainmentType.Contains)
                    {
                        transform.Translation = LocalTransform.Translation - 0.1f * Velocity * dt;
                        Velocity = new Vector3(Velocity.X * -0.9f, Velocity.Y, Velocity.Z * -0.9f);
                    }


                    // If we're outside the world, die
                    if (LocalTransform.Translation.Y < -10 ||
                        worldBounds.Contains(GetBoundingBox()) == ContainmentType.Disjoint)
                    {
                        Die();
                    }


                    // Orientation logic.
                    if (Orientation == OrientMode.Physics)
                    {
                        Matrix dA = Matrix.Identity;
                        dA *= Matrix.CreateRotationX(AngularVelocity.X * FixedDT);
                        dA *= Matrix.CreateRotationY(AngularVelocity.Y * FixedDT);
                        dA *= Matrix.CreateRotationZ(AngularVelocity.Z * FixedDT);

                        transform = dA * transform;
                    }
                    else if (Orientation != OrientMode.Fixed)
                    {
                        if (Velocity.Length() > 0.4f)
                        {
                            if (Orientation == OrientMode.LookAt)
                            {
                                Matrix newTransform =
                                    Matrix.Invert(Matrix.CreateLookAt(Position, Position + Velocity, Vector3.Down));
                                newTransform.Translation = transform.Translation;
                                transform = newTransform;
                            }
                            else if (Orientation == OrientMode.RotateY)
                            {
                                Rotation = (float)Math.Atan2(Velocity.X, -Velocity.Z);
                                Quaternion newRotation =
                                    Quaternion.CreateFromRotationMatrix(Matrix.CreateRotationY(Rotation));
                                Quaternion oldRotation = Quaternion.CreateFromRotationMatrix(LocalTransform);
                                Quaternion finalRot    = Quaternion.Slerp(oldRotation, newRotation, 0.1f);
                                finalRot.Normalize();
                                Matrix newTransform = Matrix.CreateFromQuaternion(finalRot);
                                newTransform.Translation = transform.Translation;
                                newTransform.Right.Normalize();
                                newTransform.Up.Normalize();
                                newTransform.Forward.Normalize();
                                newTransform.M14 = 0;
                                newTransform.M24 = 0;
                                newTransform.M34 = 0;
                                newTransform.M44 = 1;
                                transform        = newTransform;
                            }
                        }
                    }

                    // Final check to ensure we're in the world.
                    transform.Translation = ClampToBounds(transform.Translation);
                    LocalTransform        = transform;

                    // Assume that if velocity is small, we're standing on ground (lol bad assumption)
                    // Apply friction.
                    if (Math.Abs(Velocity.Y) < 0.1f)
                    {
                        Velocity = new Vector3(Velocity.X * Friction, Velocity.Y, Velocity.Z * Friction);
                    }

                    // Apply gravity.
                    if (applyGravityThisFrame)
                    {
                        ApplyForce(Gravity, FixedDT / velocityLength);
                    }

                    // Damp the velocity.
                    Vector3 dampingForce = -Velocity * (1.0f - LinearDamping);

                    Velocity        += dampingForce * FixedDT;
                    AngularVelocity *= AngularDamping;

                    // These will get called next time around anyway...
                    UpdateBoundingBox();
                    UpdateTransformsRecursive(Parent as Body);
                }
            }

            applyGravityThisFrame = true;
            CheckLiquids(chunks, (float)gameTime.ElapsedGameTime.TotalSeconds);
            PreviousVelocity = Velocity;
            PreviousPosition = Position;
            base.Update(gameTime, chunks, camera);
        }
Esempio n. 2
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            base.Update(gameTime, chunks, camera);

            if (!Active)
            {
                return;
            }

            // Never apply physics when animating!
            if (AnimationQueue.Count > 0)
            {
                Velocity = Vector3.Zero;
                return;
            }

            if (gameTime.Speed < 0.01) // This a poor man's IsPaused? Does this even get called if paused?
            {
                return;
            }

            // How would this get a NaN anyway?
            if (MathFunctions.HasNan(Velocity))
            {
                Velocity = Vector3.Zero;
            }

            if (AllowPhysicsSleep)
            {
                bool goingSlow = Velocity.LengthSquared() < 0.05f;
                // If we're not sleeping and moving very slowly, go to sleep.

                if (!IsSleeping && goingSlow)
                {
                    WakeTimer.Reset();
                    SleepTimer.Update(gameTime);
                    if (SleepTimer.HasTriggered)
                    {
                        WakeTimer.Reset();
                        Velocity   = Vector3.Zero;
                        IsSleeping = true;
                    }
                }
                else if (IsSleeping && !goingSlow)
                {
                    WakeTimer.Update(gameTime);
                    SleepTimer.Reset();
                    if (WakeTimer.HasTriggered)
                    {
                        IsSleeping = false;
                    }
                }
            }

            // If not sleeping, update physics.
            if (!IsSleeping || overrideSleepThisFrame)
            {
                overrideSleepThisFrame = false;

                float dt = (float)(gameTime.ElapsedGameTime.TotalSeconds);

                // Calculate the number of timesteps to apply.
                int numTimesteps = Math.Min(MaxTimesteps, Math.Max((int)(dt / FixedDT), 1));

                float velocityLength = Math.Max(Velocity.Length(), 1.0f);

                // Prepare expanded world bounds.
                BoundingBox worldBounds = chunks.Bounds;
                worldBounds.Max.Y += 50;
                // For each timestep, move and collide.
                for (int n = 0; n < numTimesteps * velocityLength; n++)
                {
                    // Move by a fixed amount.
                    Move(FixedDT / velocityLength);

                    prevVoxel = CurrentVoxel;
                    // Get the current voxel.
                    CurrentVoxel = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position));

                    if (CurrentVoxel != prevVoxel)
                    {
                        queryNeighborhood = true;
                    }

                    // Collide with the world.
                    if (CollisionType != CollisionType.None)
                    {
                        HandleCollisions(queryNeighborhood, neighborHood, chunks, FixedDT);
                    }
                    queryNeighborhood = false;
                    Matrix transform = LocalTransform;
                    // Avoid leaving the world.
                    if (worldBounds.Contains(LocalTransform.Translation + Velocity * dt) != ContainmentType.Contains)
                    {
                        transform.Translation = LocalTransform.Translation - 0.1f * Velocity * dt;
                        Velocity = new Vector3(Velocity.X * -0.9f, Velocity.Y, Velocity.Z * -0.9f);
                    }


                    // If we're outside the world, die
                    if (LocalTransform.Translation.Y < -10 ||
                        worldBounds.Contains(GetBoundingBox()) == ContainmentType.Disjoint)
                    {
                        Die();
                    }

                    // Final check to ensure we're in the world.
                    transform.Translation = ClampToBounds(transform.Translation);
                    LocalTransform        = transform;

                    // Assume that if velocity is small, we're standing on ground (lol bad assumption)
                    // Apply friction.
                    if (Math.Abs(Velocity.Y) < 0.1f)
                    {
                        Velocity = new Vector3(Velocity.X * Friction, Velocity.Y, Velocity.Z * Friction);
                    }

                    // Apply gravity.
                    ApplyForce(Gravity, FixedDT / velocityLength);

                    // Damp the velocity.
                    Vector3 dampingForce = -Velocity * (1.0f - LinearDamping);

                    Velocity        += dampingForce * FixedDT;
                    AngularVelocity *= AngularDamping;

                    // These will get called next time around anyway... -@blecki
                    // No they won't @blecki, this broke everything!! -@mklingen
                    // Remove check so that it is ALWAYS called when an object moves. Call removed
                    //   from component update in ComponentManager. -@blecki
                    if (numTimesteps * velocityLength > 1)
                    {
                        // Assume all physics are attached to the root.
                        if (Parent != null)
                        {
                            globalTransform = LocalTransform * (Parent as GameComponent).GlobalTransform;
                        }
                        else
                        {
                            globalTransform = LocalTransform;
                        }
                        UpdateBoundingBox();

                        //UpdateTransformsRecursive(Parent as Body);
                    }
                }



                if (Orientation != OrientMode.Fixed)
                {
                    Matrix transform = LocalTransform;
                    if (Velocity.Length() > 0.4f)
                    {
                        if (Orientation == OrientMode.LookAt)
                        {
                            if (Math.Abs(Vector3.Dot(Vector3.Down, Velocity)) < 0.99 * Velocity.Length())
                            {
                                Matrix newTransform =
                                    Matrix.Invert(Matrix.CreateLookAt(LocalPosition, LocalPosition + Velocity, Vector3.Down));
                                newTransform.Translation = transform.Translation;
                                transform = newTransform;
                            }
                            else
                            {
                                {
                                    Matrix newTransform =
                                        Matrix.Invert(Matrix.CreateLookAt(LocalPosition, LocalPosition + Velocity, Vector3.Right));
                                    newTransform.Translation = transform.Translation;
                                    transform = newTransform;
                                }
                            }
                        }
                        else if (Orientation == OrientMode.RotateY)
                        {
                            Rotation = (float)Math.Atan2(Velocity.X, -Velocity.Z);
                            Quaternion newRotation =
                                Quaternion.CreateFromRotationMatrix(Matrix.CreateRotationY(Rotation));
                            Quaternion oldRotation = Quaternion.CreateFromRotationMatrix(LocalTransform);
                            Quaternion finalRot    = Quaternion.Slerp(oldRotation, newRotation, 0.1f);
                            finalRot.Normalize();
                            Matrix newTransform = Matrix.CreateFromQuaternion(finalRot);
                            newTransform.Translation = transform.Translation;
                            newTransform.Right.Normalize();
                            newTransform.Up.Normalize();
                            newTransform.Forward.Normalize();
                            newTransform.M14 = 0;
                            newTransform.M24 = 0;
                            newTransform.M34 = 0;
                            newTransform.M44 = 1;
                            transform        = newTransform;
                        }
                    }
                    LocalTransform = transform;
                }
            }

            CheckLiquids(chunks, (float)gameTime.ElapsedGameTime.TotalSeconds);
            PreviousVelocity = Velocity;
            PreviousPosition = Position;
        }
Esempio n. 3
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            if (!IsActive)
            {
                return;
            }

            BoundingBox bounds = chunks.Bounds;

            bounds.Max.Y += 50;

            if (!IsSleeping && (Velocity).Length() < 0.15f)
            {
                SleepTimer.Update(gameTime);
                if (SleepTimer.HasTriggered)
                {
                    applyGravityThisFrame = false;
                    Velocity  *= 0.0f;
                    IsSleeping = true;
                }
            }
            else
            {
                SleepTimer.Reset();
                IsSleeping = false;
            }

            if (!IsSleeping || overrideSleepThisFrame)
            {
                if (overrideSleepThisFrame)
                {
                    overrideSleepThisFrame = false;
                }

                float dt = (float)(gameTime.ElapsedGameTime.TotalSeconds);


                if (MathFunctions.HasNan(Velocity))
                {
                    Velocity = Vector3.Zero;
                }

                MoveY(dt);
                MoveX(dt);
                MoveZ(dt);
                chunks.ChunkData.GetVoxel(Position, ref CurrentVoxel);
                if (CurrentVoxel != null && CurrentVoxel.Chunk != null)
                {
                    Vector3 gridPos = CurrentVoxel.GridPosition;
                    CurrentVoxel.Chunk.GetNeighborsSuccessors(VoxelChunk.ManhattanSuccessors, (int)gridPos.X, (int)gridPos.Y, (int)gridPos.Z, Neighbors);
                }
                HandleCollisions(chunks, dt);

                Matrix transform = LocalTransform;
                if (bounds.Contains(LocalTransform.Translation + Velocity * dt) != ContainmentType.Contains)
                {
                    transform.Translation = LocalTransform.Translation - 0.1f * Velocity * dt;
                    Velocity = new Vector3(Velocity.X * -0.9f, Velocity.Y, Velocity.Z * -0.9f);
                }


                if (LocalTransform.Translation.Z < -10 || bounds.Contains(GetBoundingBox()) == ContainmentType.Disjoint)
                {
                    Die();
                }


                if (Orientation == OrientMode.Physics)
                {
                    Matrix dA = Matrix.Identity;
                    dA *= Matrix.CreateRotationX(AngularVelocity.X * dt);
                    dA *= Matrix.CreateRotationY(AngularVelocity.Y * dt);
                    dA *= Matrix.CreateRotationZ(AngularVelocity.Z * dt);

                    transform = dA * transform;
                }
                else if (Orientation != OrientMode.Fixed)
                {
                    if (Velocity.Length() > 0.4f)
                    {
                        if (Orientation == OrientMode.LookAt)
                        {
                            Matrix newTransform =
                                Matrix.Invert(Matrix.CreateLookAt(Position, Position + Velocity, Vector3.Down));
                            newTransform.Translation = transform.Translation;
                            transform = newTransform;
                        }
                        else if (Orientation == OrientMode.RotateY)
                        {
                            Rotation = (float)Math.Atan2(Velocity.X, -Velocity.Z);
                            Quaternion newRotation = Quaternion.CreateFromRotationMatrix(Matrix.CreateRotationY(Rotation));
                            Quaternion oldRotation = Quaternion.CreateFromRotationMatrix(LocalTransform);
                            Quaternion finalRot    = Quaternion.Slerp(oldRotation, newRotation, 0.1f);
                            finalRot.Normalize();
                            Matrix newTransform = Matrix.CreateFromQuaternion(finalRot);
                            newTransform.Translation = transform.Translation;
                            newTransform.Right.Normalize();
                            newTransform.Up.Normalize();
                            newTransform.Forward.Normalize();
                            newTransform.M14 = 0;
                            newTransform.M24 = 0;
                            newTransform.M34 = 0;
                            newTransform.M44 = 1;
                            transform        = newTransform;
                        }
                    }
                }

                transform.Translation = ClampToBounds(transform.Translation);
                LocalTransform        = transform;

                if (Math.Abs(Velocity.Y) < 0.1f)
                {
                    Velocity = new Vector3(Velocity.X * Friction, Velocity.Y, Velocity.Z * Friction);
                }

                if (applyGravityThisFrame)
                {
                    ApplyForce(Gravity, dt);
                }
                else
                {
                    applyGravityThisFrame = true;
                }

                Velocity        *= LinearDamping;
                AngularVelocity *= AngularDamping;
                UpdateBoundingBox();
            }
            CheckLiquids(chunks, (float)gameTime.ElapsedGameTime.TotalSeconds);
            Velocity         = (PreviousVelocity * 0.1f + Velocity * 0.9f);
            PreviousVelocity = Velocity;
            PreviousPosition = Position;
            base.Update(gameTime, chunks, camera);
        }