Beispiel #1
0
        public override void Remove(Item item)
        {
            if (_cluster.ContainsKey(item.Id))
            {
                PhysicsUnit cluster = _cluster[item.Id];

                // Im Falle von Kollisionen aus der Liste entfernen
                if (cluster.CanCollide)
                {
                    _collidables.Remove(cluster);
                }

                cluster.Dispose();
                _cluster.Remove(item.Id);
            }
        }
Beispiel #2
0
        public override void Insert(Item item)
        {
            // Relevante Elemente finden
            if ((item.ContainsProperty <WalkingProperty>() ||
                 item.ContainsProperty <CollidableProperty>() ||
                 item.ContainsProperty <CarrierProperty>() ||
                 item.ContainsProperty <PortableProperty>()) &&
                !_cluster.ContainsKey(item.Id))
            {
                var cluster = new PhysicsUnit(item, _cluster);
                _cluster.Add(item.Id, cluster);

                // Im Falle von Kollisionen in die Liste einsortieren
                if (cluster.CanCollide)
                {
                    _collidables.Add(cluster);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        ///     Das tragende Teil wurde geändert - Abhängigkeiten neu prüfen
        /// </summary>
        /// <param name="item"></param>
        /// <param name="newValue"></param>
        private void carrier_OnCarrierLoadChanged(Item item, PortableProperty newValue)
        {
            if (newValue != null)
            {
                int id = newValue.Item.Id;
                if (!items.ContainsKey(id))
                {
                    throw new IndexOutOfRangeException("Item does not exist");
                }

                load = items[id];
            }
            else
            {
                load = null;
            }

            Recalc();
        }
Beispiel #4
0
        /// <summary>
        ///     Das tragende Teil wurde geändert - Abhängigkeiten neu prüfen
        /// </summary>
        /// <param name="item"></param>
        /// <param name="newValue"></param>
        private void carrier_OnCarrierLoadChanged(Item item, PortableProperty newValue)
        {
            if (newValue != null)
            {
                int id = newValue.Item.Id;
                if (!items.ContainsKey(id))
                    throw new IndexOutOfRangeException("Item does not exist");

                load = items[id];
            }
            else
                load = null;

            Recalc();
        }
Beispiel #5
0
        /// <summary>
        ///     Kümmert sich um eine Kollision zweier Elemente.
        /// </summary>
        /// <param name="cluster"></param>
        public void Collide(PhysicsUnit cluster)
        {
            float max = Radius + cluster.Radius;
            float dist = (Position - cluster.Position).Length();

            // Auflösung
            if (!IsFixed || !cluster.IsFixed)
            {
                // Richtungsvektor Item1->Item2
                Vector3 direction = (cluster.Position - Position);

                // Fallback 1, falls direction == [0,0]:
                // vorherige Positionen zum Diff verwenden
                if (direction.LengthSquared() < Vector3.EPS_MIN)
                    direction = ((cluster.Position - cluster.AppliedVelocity) - (Position - AppliedVelocity));

                // Fallback 2, falls direction == [0,0];
                // fixe Achse
                if (direction.LengthSquared() < Vector3.EPS_MIN)
                    direction = new Vector3(1, 0, 0);

                // Richtungsvektor Normalisieren
                direction = direction.Normalize();

                float diff = max - dist;
                var bounce = new Vector3();

                // Item1 fixed, item2 not fixed
                if (IsFixed)
                {
                    // Nur Item2 bewegen
                    // Ignore Result, da eh nix zu retten ist
                    cluster.SetPosition(cluster.Position + (direction*diff), ref bounce, true);
                }
                    // Item1 not fixed, item2 fixed
                else if (cluster.IsFixed)
                {
                    // Nur Item1 bewegen
                    // Result unwichtig, da eh nichts zu retten ist
                    SetPosition(Position + (direction.InvertXYZ()*diff), ref bounce, true);
                }
                else
                {
                    // Über Masse auflösen
                    float totalmass = AppliedMass + cluster.AppliedMass;
                    float spanItem1 = diff*(cluster.AppliedMass/totalmass);
                    float spanItem2 = diff*(AppliedMass/totalmass);
                    Vector3 diffItem1 = direction.InvertXYZ()*spanItem1;
                    Vector3 diffItem2 = direction*spanItem2;

                    // Apply
                    // Im Falle eines Blocks wird der Bounce auf das andere Element übertragen.
                    bounce = Vector3.Zero;
                    if (SetPosition(Position + diffItem1, ref bounce, true) == PositionResult.Blocked)
                        diffItem2 += bounce;

                    // Im Falle eines Bounce beim zweiten Element wird der Bounce ein letztes mal an Element 1 weiter gegeben.
                    bounce = Vector3.Zero;
                    if (cluster.SetPosition(cluster.Position + diffItem2, ref bounce, true) == PositionResult.Blocked)
                        SetPosition(Position + bounce, ref bounce, true);
                }
            }

            // Kollision melden
            if (collidable != null)
                collidable.CollideItem(cluster.Item);
            if (cluster.collidable != null)
                cluster.collidable.CollideItem(Item);
        }
Beispiel #6
0
 private void KillUnit(PhysicsUnit unit)
 {
     // Remove
     Engine.RemoveItem(unit.Item);
 }
Beispiel #7
0
        /// <summary>
        ///     Kümmert sich um eine Kollision zweier Elemente.
        /// </summary>
        /// <param name="cluster"></param>
        public void Collide(PhysicsUnit cluster)
        {
            float max  = Radius + cluster.Radius;
            float dist = (Position - cluster.Position).Length();

            // Auflösung
            if (!IsFixed || !cluster.IsFixed)
            {
                // Richtungsvektor Item1->Item2
                Vector3 direction = (cluster.Position - Position);

                // Fallback 1, falls direction == [0,0]:
                // vorherige Positionen zum Diff verwenden
                if (direction.LengthSquared() < Vector3.EPS_MIN)
                {
                    direction = ((cluster.Position - cluster.AppliedVelocity) - (Position - AppliedVelocity));
                }

                // Fallback 2, falls direction == [0,0];
                // fixe Achse
                if (direction.LengthSquared() < Vector3.EPS_MIN)
                {
                    direction = new Vector3(1, 0, 0);
                }

                // Richtungsvektor Normalisieren
                direction = direction.Normalize();


                float diff   = max - dist;
                var   bounce = new Vector3();

                // Item1 fixed, item2 not fixed
                if (IsFixed)
                {
                    // Nur Item2 bewegen
                    // Ignore Result, da eh nix zu retten ist
                    cluster.SetPosition(cluster.Position + (direction * diff), ref bounce, true);
                }
                // Item1 not fixed, item2 fixed
                else if (cluster.IsFixed)
                {
                    // Nur Item1 bewegen
                    // Result unwichtig, da eh nichts zu retten ist
                    SetPosition(Position + (direction.InvertXYZ() * diff), ref bounce, true);
                }
                else
                {
                    // Über Masse auflösen
                    float   totalmass = AppliedMass + cluster.AppliedMass;
                    float   spanItem1 = diff * (cluster.AppliedMass / totalmass);
                    float   spanItem2 = diff * (AppliedMass / totalmass);
                    Vector3 diffItem1 = direction.InvertXYZ() * spanItem1;
                    Vector3 diffItem2 = direction * spanItem2;

                    // Apply
                    // Im Falle eines Blocks wird der Bounce auf das andere Element übertragen.
                    bounce = Vector3.Zero;
                    if (SetPosition(Position + diffItem1, ref bounce, true) == PositionResult.Blocked)
                    {
                        diffItem2 += bounce;
                    }

                    // Im Falle eines Bounce beim zweiten Element wird der Bounce ein letztes mal an Element 1 weiter gegeben.
                    bounce = Vector3.Zero;
                    if (cluster.SetPosition(cluster.Position + diffItem2, ref bounce, true) == PositionResult.Blocked)
                    {
                        SetPosition(Position + bounce, ref bounce, true);
                    }
                }
            }

            // Kollision melden
            if (collidable != null)
            {
                collidable.CollideItem(cluster.Item);
            }
            if (cluster.collidable != null)
            {
                cluster.collidable.CollideItem(Item);
            }
        }