Exemplo 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);
            }
        }
Exemplo n.º 2
0
        /// <inheritdoc/>
        protected override void OnChanged(ShapeChangedEventArgs eventArgs)
        {
            // Set cached AABB to "invalid".
            _aabbLocal  = new Aabb(new Vector3(float.NaN), new Vector3(float.NaN));
            _innerPoint = new Vector3(float.NaN);

            base.OnChanged(eventArgs);
        }
Exemplo 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);
            }
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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 Vector3(float.NaN), new Vector3(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();
            }
        }
Exemplo n.º 6
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);
        }
Exemplo 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();
        }
Exemplo n.º 8
0
 /// <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);
 }