private void IScene_PropertyChanged(object sender, PropertyChangedArgs e)
 {
     // Check whether a constraint property has been changed, so that we can update the native
     // properties (useful when running the game in editor). Situations to cover:
     // - User directly modified a property of the typeProperty instance: can be explicitly checked
     // - User modified the value of a sub-property: difficult to check. In that case we assume that
     //   any component belonging to the HavokEditorPlugin/HavokManaged assemblies is relevant for us.
     if (e._component == _typeProperties ||
         e._component.GetType().Assembly == this.GetType().Assembly ||
         e._component.GetType().Assembly == typeof(HavokManaged.ConstraintChainStateBase).Assembly)
     {
         if (_engineInstance != null && ParentLayer.Modifiable)
         {
             // Set the constraint properties on the engine instance, since the user modified them
             EngineConstraintChainInstance.SetConstraintChainProperties(_typeProperties);
             this.ParentLayer.Modified = true;
         }
     }
 }
        /// <summary>
        /// Performs the actual linking on engine instances
        /// </summary>
        /// <param name="src"></param>
        /// <param name="target"></param>
        public override void OnLink(ShapeLink src, ShapeLink target)
        {
            base.OnLink(src, target);

            // Ignore links which don't belong to us
            if (src.OwnerShape != this)
            {
                return;
            }

            // Get the anchor the target link points to
            AnchorShape anchorShape = GetAnchorFromLink(target);

            if (anchorShape == null || !HasEngineInstance())
            {
                return;
            }

            // Get the entity instance the target points to
            EngineInstanceEntity entityInstance = GetEntityFromAnchor(anchorShape);

            // Add the actor to the constraint
            if (entityInstance != null)
            {
                // We have an anchor which belongs to an entity. Add the entity to the constraint
                // and pass the anchor position, relative to the parent entity.
                Vector3F anchorPositionLS = anchorShape.LocalSpacePosition;
                bool     bResult          = EngineConstraintChainInstance.AddEntityAnchor(
                    (long)anchorShape.UniqueID, entityInstance, anchorPositionLS);
                Debug.Assert(bResult == true);
            }
            else
            {
                // Our anchor is statically attached to the world.
                // Add the static world anchor to the constraint. Pass the world space position of the anchor
                // for this purpose.
                Vector3F anchorPositionWS = anchorShape.Position;
                bool     bResult          = EngineConstraintChainInstance.AddWorldAnchor((long)anchorShape.UniqueID, anchorShape);
                Debug.Assert(bResult == true);
            }
        }
        /// <summary>
        /// unlinks a target from a source. Either src or target has this shape as owner
        /// </summary>
        /// <param name="src">the link source</param>
        /// <param name="target">the link target</param>
        public override void OnUnlink(ShapeLink src, ShapeLink target)
        {
            base.OnUnlink(src, target);

            // Ignore links which don't belong to us
            if (src.OwnerShape != this)
            {
                return;
            }

            // Get the anchor the target link points to
            AnchorShape anchorShape = GetAnchorFromLink(target);

            if (anchorShape == null || !HasEngineInstance())
            {
                return;
            }

            bool bResult = EngineConstraintChainInstance.RemoveAnchor((long)anchorShape.UniqueID);

            Debug.Assert(bResult == true);
        }