Ejemplo n.º 1
0
        /// <summary>
        /// Called when the <see cref="Children"/> collection was changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="eventArgs">
        /// The <see cref="CollectionChangedEventArgs{IGeometricObject}"/> instance containing the event
        /// data.
        /// </param>
        private void OnChildrenChanged(object sender, CollectionChangedEventArgs <IGeometricObject> eventArgs)
        {
            if (eventArgs.Action == CollectionChangedAction.Move)
            {
                return;
            }

            // Handle removed items.
            var oldItems         = eventArgs.OldItems;
            int numberOfOldItems = oldItems.Count;

            for (int i = 0; i < numberOfOldItems; i++)
            {
                var geometricObject = oldItems[i];

                geometricObject.PoseChanged  -= OnChildShapeChanged;
                geometricObject.ShapeChanged -= OnChildShapeChanged;
            }

            // Handle new items.
            var newItems         = eventArgs.NewItems;
            int numberOfNewItems = newItems.Count;

            for (int i = 0; i < numberOfNewItems; i++)
            {
                var geometricObject = newItems[i];

                geometricObject.PoseChanged  += OnChildShapeChanged;
                geometricObject.ShapeChanged += OnChildShapeChanged;
            }

            // Rebuild spatial partition.
            if (_partition != null)
            {
                _partition.Clear();
                int numberOfChildren = Children.Count;
                for (int i = 0; i < numberOfChildren; i++)
                {
                    _partition.Add(i);
                }
            }

            if (numberOfOldItems == 1 &&
                numberOfNewItems == 1 &&
                eventArgs.OldItemsIndex == eventArgs.NewItemsIndex)
            {
                // Exactly one item was replaced.
                // --> Set the feature index of the item in the event args.
                var shapeChangedEventArgs = ShapeChangedEventArgs.Create(eventArgs.OldItemsIndex);
                OnChanged(shapeChangedEventArgs);
                shapeChangedEventArgs.Recycle();
            }
            else
            {
                // Multiple items added or removed. The indices of multiple items have changed.
                // --> Do not set a feature index. Use the default.
                OnChanged(ShapeChangedEventArgs.Empty);
            }
        }
Ejemplo n.º 2
0
        /// <inheritdoc/>
        protected override void OnChanged(ShapeChangedEventArgs eventArgs)
        {
            // Set cached AABB to "invalid".
            _aabbLocal  = new Aabb(new Vector3F(float.NaN), new Vector3F(float.NaN));
            _innerPoint = new Vector3F(float.NaN);

            base.OnChanged(eventArgs);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Raises the <see cref="Shape.Changed"/> event.
        /// </summary>
        /// <param name="eventArgs">
        /// <see cref="ShapeChangedEventArgs"/> object that provides the arguments for the event.
        /// </param>
        /// <remarks>
        /// <strong>Notes to Inheritors:</strong> When overriding <see cref="OnChanged"/> in a derived
        /// class, be sure to call the base class's <see cref="OnChanged"/> method so that registered
        /// delegates receive the event.
        /// </remarks>
        protected virtual void OnChanged(ShapeChangedEventArgs eventArgs)
        {
            var handler = _changed;

            if (handler != null)
            {
                handler(this, eventArgs);
            }
        }
Ejemplo n.º 4
0
        /// <inheritdoc/>
        protected override void OnChanged(ShapeChangedEventArgs eventArgs)
        {
            // Set cached AABB to "invalid".
            _minHeight = float.NaN;
            _maxHeight = float.NaN;

            // Cached normals are also invalid.
            //NormalArray = null;

            base.OnChanged(eventArgs);
        }
Ejemplo n.º 5
0
        private void OnChildShapeChanged(object sender, ShapeChangedEventArgs eventArgs)
        {
            IGeometricObject geometricObject = (IGeometricObject)sender;

            if (geometricObject.Shape is ConvexShape == false)
            {
                throw new GeometryException("The child objects in a ConvexHullOfShapes must have ConvexShapes.");
            }

            OnChanged(ShapeChangedEventArgs.Empty);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Invalidates the whole triangle mesh or a single triangle.
        /// </summary>
        /// <param name="triangleIndex">
        /// Index of the triangle. Can be -1 to invalidate the whole mesh.
        /// </param>
        /// <param name="invalidateTopology">
        /// If set to <see langword="true"/> the mesh topology is invalidated.
        /// </param>
        /// <remarks>
        /// <para>
        /// This method must be called if the position of a triangle stored in <see cref="Mesh"/> is
        /// changed. This method updates the <see cref="Partition"/> and raises the
        /// <see cref="Shape.Changed"/> event by calling <see cref="Shape.OnChanged"/>.
        /// </para>
        /// <para>
        /// If the mesh topology has changed, <paramref name="invalidateTopology"/> must be set to
        /// <see langword="true"/>. The topology has changed if triangle neighbor relationships have
        /// changed. If each triangle has the same neighbor triangles as before and only the vertices
        /// were moved, <paramref name="invalidateTopology"/> can be <see langword="false"/>.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="triangleIndex"/> is out of range.
        /// </exception>
        public void Invalidate(int triangleIndex, bool invalidateTopology)
        {
            int numberOfTriangles = Mesh.NumberOfTriangles;

            if (triangleIndex >= numberOfTriangles)
            {
                throw new ArgumentOutOfRangeException("triangleIndex");
            }

            // Set cached AABB to "invalid".
            _aabbLocal = new Aabb(new Vector3F(float.NaN), new Vector3F(float.NaN));

            // Fill new spatial partition.
            if (_partition != null)
            {
                if (numberOfTriangles != _partition.Count)
                {
                    // Triangle count has changed. Re-initialize partition content.
                    _partition.Clear();
                    for (int i = 0; i < numberOfTriangles; i++)
                    {
                        _partition.Add(i);
                    }
                }
                else
                {
                    // Same number of triangles - invalidate the triangle.
                    if (triangleIndex >= 0)
                    {
                        _partition.Invalidate(triangleIndex);
                    }
                    else
                    {
                        _partition.Invalidate();
                    }
                }
            }

            if (invalidateTopology)
            {
                ComputeTriangleNeighbors();
            }

            if (triangleIndex < 0)
            {
                OnChanged(ShapeChangedEventArgs.Empty);
            }
            else
            {
                var eventArgs = ShapeChangedEventArgs.Create(triangleIndex);
                OnChanged(eventArgs);
                eventArgs.Recycle();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Called when a child object was changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="eventArgs">
        /// The <see cref="EventArgs"/> instance containing the event data.
        /// </param>
        private void OnChildShapeChanged(object sender, EventArgs eventArgs)
        {
            // Invalidate partition.
            var index = Children.IndexOf(sender as IGeometricObject);

            if (Partition != null)
            {
                if (index >= 0)
                {
                    Partition.Invalidate(index);
                }
                else
                {
                    Partition.Invalidate();
                }
            }

            var shapeChangedEventArgs = ShapeChangedEventArgs.Create(index);

            OnChanged(shapeChangedEventArgs);
            shapeChangedEventArgs.Recycle();
        }
Ejemplo n.º 8
0
        /// <inheritdoc/>
        protected override void OnShapeChanged(ShapeChangedEventArgs eventArgs)
        {
            base.OnShapeChanged(eventArgs);

              // Synchronize absolute scale.
              // (Remember: ShapeChanged is also triggered by scale changes.)
              Levels.SetScale(ScaleWorld);
        }
Ejemplo n.º 9
0
    /// <summary>
    /// Raises the <see cref="ShapeChanged"/> event.
    /// </summary>
    /// <param name="eventArgs">
    /// <see cref="ShapeChangedEventArgs"/> object that provides the arguments for the event.
    /// </param>
    /// <remarks>
    /// <strong>Notes to Inheritors:</strong> When overriding 
    /// <see cref="OnShapeChanged(ShapeChangedEventArgs)"/> in a derived class, be sure to call the
    /// base class's <see cref="OnShapeChanged(ShapeChangedEventArgs)"/> method so that registered
    /// delegates receive the event.
    /// </remarks>
    protected virtual void OnShapeChanged(ShapeChangedEventArgs eventArgs)
    {
      _aabbIsValid = false;

      var handler = ShapeChanged;

      if (handler != null)
        handler(this, eventArgs);
    }
Ejemplo n.º 10
0
        /// <inheritdoc/>
        protected override void OnChanged(ShapeChangedEventArgs eventArgs)
        {
            // Set cached AABB to "invalid".
              _minHeight = float.NaN;
              _maxHeight = float.NaN;

              // Cached normals are also invalid.
              //NormalArray = null;

              base.OnChanged(eventArgs);
        }
        /// <summary>
        /// Raises the <see cref="ShapeChanged"/> event.
        /// </summary>
        /// <param name="eventArgs">
        /// <see cref="ShapeChangedEventArgs"/> object that provides the arguments for the event.
        /// </param>
        /// <remarks>
        /// <strong>Notes to Inheritors:</strong> When overriding <see cref="OnShapeChanged(ShapeChangedEventArgs)"/> 
        /// in a derived class, be sure to call the base class's <see cref="OnShapeChanged(ShapeChangedEventArgs)"/> 
        /// method so that registered delegates receive the event.
        /// </remarks>
        protected virtual void OnShapeChanged(ShapeChangedEventArgs eventArgs)
        {
            // Reset shape dependent stuff.
              _aabbIsValid = false;
              BuoyancyData = null;

              WakeUp();

              UpdateMassFrame();

              var handler = ShapeChanged;

              if (handler != null)
            handler(this, eventArgs);
        }
Ejemplo n.º 12
0
    /// <inheritdoc/>
    protected override void OnShapeChanged(ShapeChangedEventArgs eventArgs)
    {
      base.OnShapeChanged(eventArgs);

      // (Remember: ShapeChanged is also triggered by scale changes.)
      if (_node != null)
      {
        _ignoreChanges = true;
        _node.ScaleLocal = ScaleWorld;
        _ignoreChanges = false;
      }
    }
Ejemplo n.º 13
0
    /// <summary>
    /// Raises the <see cref="ShapeChanged"/> event.
    /// </summary>
    /// <param name="eventArgs">
    /// <see cref="EventArgs"/> object that provides the arguments for the event.
    /// </param>
    /// <remarks>
    /// <strong>Notes to Inheritors:</strong> When overriding 
    /// <see cref="OnShapeChanged(ShapeChangedEventArgs)"/> in a derived class, be sure to call the 
    /// base class' <see cref="OnShapeChanged(ShapeChangedEventArgs)"/> method so that registered 
    /// delegates receive the event.
    /// </remarks>
    protected virtual void OnShapeChanged(ShapeChangedEventArgs eventArgs)
    {
      SetFlag(SceneNodeFlags.IsAabbDirty | SceneNodeFlags.IsDirty | SceneNodeFlags.IsDirtyScene);

      var handler = ShapeChanged;
      if (handler != null)
        handler(this, eventArgs);

      OnSceneChanged(this, SceneChanges.ShapeChanged);
    }
 /// <summary>
 /// Called when child shape was changed.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="eventArgs">
 /// The <see cref="ShapeChangedEventArgs"/> instance containing the event data.
 /// </param>
 private void OnChildShapeChanged(object sender, ShapeChangedEventArgs eventArgs)
 {
     CheckShapes();
     OnChanged(eventArgs);
 }
Ejemplo n.º 15
0
 private void OnVolumeChanged(object sender, ShapeChangedEventArgs eventArgs)
 {
     Update(true);
 }
Ejemplo n.º 16
0
        /// <inheritdoc/>
        protected override void OnChanged(ShapeChangedEventArgs eventArgs)
        {
            // Set cached AABB to "invalid".
              _aabbLocal = new Aabb(new Vector3F(float.NaN), new Vector3F(float.NaN));
              _innerPoint = new Vector3F(float.NaN);

              base.OnChanged(eventArgs);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Called when the shape was changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="eventArgs">
        /// The <see cref="ShapeChangedEventArgs"/> instance containing the event data.
        /// </param>
        private void OnShapeChanged(object sender, ShapeChangedEventArgs eventArgs)
        {
            Changed = true;

              var shape = (_geometricObject != null) ? _geometricObject.Shape : null;

              // Check if shape type was changed (which invalidates the cached collision algos).
              // Instead of comparing the types, we simply compare the instances.
              ShapeTypeChanged = ShapeTypeChanged || (_shape != shape);

              // Remember current shape.
              _shape = shape;

              RayShape ray = shape as RayShape;
              if (ray != null)
            _shapeType = ray.StopsAtFirstHit ? ShapeType.RayThatStopsAtFirstHit : ShapeType.Ray;
              else
            _shapeType = ShapeType.Default;

              if (_domain == null)
            return;

              Debug.Assert(_domain != null);

              // Clear existing contact info only.
              int feature = eventArgs.Feature;
              if (feature == -1)
              {
            // Invalidate all contacts that contain this collision object.
            foreach (var contactSet in _domain.ContactSets.GetContacts(this))
            {
              foreach (var contact in contactSet)
            contact.Recycle();

              contactSet.Clear();
              contactSet.IsValid = false;
            }
            return;
              }

              Debug.Assert(feature >= 0);

              // Remove only the contacts of the given feature.
              foreach (var contactSet in _domain.ContactSets.GetContacts(this))
              {
            if (contactSet.ObjectA == this)
            {
              for (int i = contactSet.Count - 1; i >= 0; i--)
              {
            Contact contact = contactSet[i];
            if (contact.FeatureA == -1 || contact.FeatureA == feature)
            {
              contactSet.RemoveAt(i);
              contact.Recycle();
            }
              }
            }
            else
            {
              Debug.Assert(contactSet.ObjectB == this);
              for (int i = contactSet.Count - 1; i >= 0; i--)
              {
            Contact contact = contactSet[i];
            if (contact.FeatureB == -1 || contact.FeatureB == feature)
            {
              contactSet.RemoveAt(i);
              contact.Recycle();
            }
              }
            }

            contactSet.IsValid = false;
              }
        }
Ejemplo n.º 18
0
    private void OnShapeChanged(object sender, ShapeChangedEventArgs eventArgs)
    {
      _aabbIsValid = false;

      var handler = _shapeChanged;
      if (handler != null)
        handler(this, eventArgs);
    }
Ejemplo n.º 19
0
    private void OnChildShapeChanged(object sender, ShapeChangedEventArgs eventArgs)
    {
      IGeometricObject geometricObject = (IGeometricObject)sender;
      if (geometricObject.Shape is ConvexShape == false)
        throw new GeometryException("The child objects in a ConvexHullOfShapes must have ConvexShapes.");

      OnChanged(ShapeChangedEventArgs.Empty);
    }
Ejemplo n.º 20
0
 /// <summary>
 /// Called when the shape of a child geometric object was changed.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="eventArgs">
 /// The <see cref="ShapeChangedEventArgs"/> instance containing the event data.
 /// </param>
 private void OnChildShapeChanged(object sender, ShapeChangedEventArgs eventArgs)
 {
   OnChanged(eventArgs);
 }
Ejemplo n.º 21
0
    /// <summary>
    /// Raises the <see cref="Shape.Changed"/> event.
    /// </summary>
    /// <param name="eventArgs">
    /// <see cref="ShapeChangedEventArgs"/> object that provides the arguments for the event.
    /// </param>
    /// <remarks>
    /// <strong>Notes to Inheritors:</strong> When overriding <see cref="OnChanged"/> in a derived
    /// class, be sure to call the base class's <see cref="OnChanged"/> method so that registered
    /// delegates receive the event.
    /// </remarks>
    protected virtual void OnChanged(ShapeChangedEventArgs eventArgs)
    {
      var handler = _changed;

      if (handler != null)
        handler(this, eventArgs);
    }