/// <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); } }
/// <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); }
/// <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); } }
/// <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); }
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); }
/// <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(); } }
/// <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(); }
/// <inheritdoc/> protected override void OnShapeChanged(ShapeChangedEventArgs eventArgs) { base.OnShapeChanged(eventArgs); // Synchronize absolute scale. // (Remember: ShapeChanged is also triggered by scale changes.) Levels.SetScale(ScaleWorld); }
/// <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); }
/// <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); }
/// <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; } }
/// <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); }
private void OnVolumeChanged(object sender, ShapeChangedEventArgs eventArgs) { Update(true); }
/// <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; } }
private void OnShapeChanged(object sender, ShapeChangedEventArgs eventArgs) { _aabbIsValid = false; var handler = _shapeChanged; if (handler != null) handler(this, eventArgs); }
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); }
/// <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); }
/// <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); }