Example #1
0
        private const uint CCD_STAY_DEAD_FRAMES = 320; //5 seconds

        /// <summary>
        /// Tests for a violation of limits that can be checked before an actor has been built
        /// </summary>
        /// <param name="newPrimaryShape"></param>
        /// <param name="newChildShapes"></param>
        /// <returns></returns>
        internal bool DynamicsPrecheck(PhysicsShape newPrimaryShape, Dictionary<PhysxPrim, RelatedShapes> newChildShapes)
        {
            int totalComplexity = newPrimaryShape.Complexity;

            if (newChildShapes != null)
            {
                foreach (var shape in newChildShapes)
                {
                    totalComplexity += shape.Value.ChildShape.Complexity;
                }
            }

            //check to make sure it is ok to make this physical
            if (totalComplexity > PhysxPrim.MAX_DYNAMIC_COMPLEXITY)
            {
                //too complex, back out
                newPrimaryShape.DecRef();

                if (newChildShapes != null)
                {
                    foreach (var shape in newChildShapes)
                    {
                        shape.Value.ChildShape.DecRef();
                    }
                }

                this.TriggerComplexityError(String.Format("({0} of {1} convex hulls)", totalComplexity, PhysxPrim.MAX_DYNAMIC_COMPLEXITY));
                return false;
            }

            return true;
        }
Example #2
0
        public static PhysX.RigidActor CreateProperInitialActor(PhysicsShape meshedShape, PhysxScene scene, OpenMetaverse.Vector3 pos,
                                                                OpenMetaverse.Quaternion rotation, PhysicsScene.AddPrimShapeFlags flags, out bool kinematicStatic,
                                                                Material material)
        {
            bool isPhysical = (flags & PhysicsScene.AddPrimShapeFlags.Physical) != 0;

            kinematicStatic = false;

            PhysX.RigidActor actor;
            if (isPhysical)
            {
                actor = PhysxActorFactory.CreateRigidDynamic(scene, meshedShape, pos, rotation, isPhysical, kinematicStatic, material);
            }
            else
            {
                if ((flags & PhysicsScene.AddPrimShapeFlags.FromSceneStartup) != 0)
                {
                    actor = PhysxActorFactory.CreateRigidStatic(scene, meshedShape, pos, rotation, material);
                }
                else
                {
                    kinematicStatic = true;
                    actor           = PhysxActorFactory.CreateRigidDynamic(scene, meshedShape, pos, rotation, isPhysical, kinematicStatic, material);
                }
            }

            return(actor);
        }
        private const uint CCD_STAY_DEAD_FRAMES      = 320; //5 seconds

        /// <summary>
        /// Tests for a violation of limits that can be checked before an actor has been built
        /// </summary>
        /// <param name="newPrimaryShape"></param>
        /// <param name="newChildShapes"></param>
        /// <returns></returns>
        internal bool DynamicsPrecheck(PhysicsShape newPrimaryShape, Dictionary <PhysxPrim, RelatedShapes> newChildShapes)
        {
            int totalComplexity = newPrimaryShape.Complexity;

            if (newChildShapes != null)
            {
                foreach (var shape in newChildShapes)
                {
                    totalComplexity += shape.Value.ChildShape.Complexity;
                }
            }

            //check to make sure it is ok to make this physical
            if (totalComplexity > PhysxPrim.MAX_DYNAMIC_COMPLEXITY)
            {
                //too complex, back out
                newPrimaryShape.DecRef();

                if (newChildShapes != null)
                {
                    foreach (var shape in newChildShapes)
                    {
                        shape.Value.ChildShape.DecRef();
                    }
                }

                this.TriggerComplexityError(String.Format("({0} of {1} convex hulls)", totalComplexity, PhysxPrim.MAX_DYNAMIC_COMPLEXITY));
                return(false);
            }

            return(true);
        }
Example #4
0
        /// <summary>
        /// Creates a new PhysX.RigidStatic using our defaults
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="position"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public static PhysX.RigidStatic CreateRigidStatic(PhysxScene scene, PhysicsShape shape, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation,
                                                          Material material)
        {
            PhysX.RigidStatic physActor = scene.SceneImpl.Physics.CreateRigidStatic();
            SetCommonProperties(scene, shape, position, rotation, physActor, false, material);

            return(physActor);
        }
Example #5
0
 private static void SetCommonProperties(PhysxScene scene, PhysicsShape shape, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation, PhysX.RigidActor physActor,
                                         bool physical, Material material)
 {
     shape.AssignToActor(physActor, material.PhyMaterial, physical);
     physActor.GlobalPose =
         PhysX.Math.Matrix.RotationQuaternion(new PhysX.Math.Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W)) *
         PhysX.Math.Matrix.Translation(position.X, position.Y, position.Z);
 }
Example #6
0
        /// <summary>
        /// Creates a new PhysX.RigidDynamic using our defaults
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="position"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public static PhysX.RigidDynamic CreateRigidDynamic(PhysxScene scene, PhysicsShape shape, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation,
            bool physical, bool kinematic, Material material)
        {
            PhysX.RigidDynamic physActor = scene.SceneImpl.Physics.CreateRigidDynamic();
            if (kinematic) physActor.Flags |= PhysX.RigidDynamicFlags.Kinematic;

            SetCommonProperties(scene, shape, position, rotation, physActor, physical, material);

            if (physical)
            {
                physActor.UpdateMassAndInertia(material.Density);
                physActor.MaxAngularVelocity *= 4;

                physActor.AngularDamping = DEFAULT_ANGULAR_DAMPING;
                physActor.LinearDamping = DEFAULT_LINEAR_DAMPING;
            }

            physActor.SleepThreshold = SLEEP_THRESHOLD;

            return physActor;
        }
Example #7
0
        /// <summary>
        /// Creates a new PhysX.RigidDynamic using our defaults
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="position"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public static PhysX.RigidDynamic CreateRigidDynamic(PhysxScene scene, PhysicsShape shape, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation,
                                                            bool physical, bool kinematic, Material material)
        {
            PhysX.RigidDynamic physActor = scene.SceneImpl.Physics.CreateRigidDynamic();
            if (kinematic)
            {
                physActor.Flags |= PhysX.RigidDynamicFlags.Kinematic;
            }

            SetCommonProperties(scene, shape, position, rotation, physActor, physical, material);

            if (physical)
            {
                physActor.UpdateMassAndInertia(material.Density);
                physActor.MaxAngularVelocity *= 4;

                physActor.AngularDamping = DEFAULT_ANGULAR_DAMPING;
                physActor.LinearDamping  = DEFAULT_LINEAR_DAMPING;
            }

            physActor.SleepThreshold = SLEEP_THRESHOLD;

            return(physActor);
        }
Example #8
0
        public PhysxPrim(PhysxPrim parent, PhysxScene scene, PrimitiveBaseShape baseShape, OpenMetaverse.Vector3 pos,
            OpenMetaverse.Quaternion rotation, PhysicsShape myShape, PhysX.RigidActor myActor,
            bool isPhysical, IPhysicsProperties properties, CollisionGroupFlag collisionGroup)
        {
            _parentPrim = parent;
            _scene = scene;
            _pbs = baseShape;
            _position = pos;
            _rotation = rotation;
            _isPhysical = isPhysical;
            _properties = (PhysicsProperties)properties;
            _collisionGroup = collisionGroup;

            this.AssignActor(myActor, myShape, _isPhysical, DeleteActorFlags.None);

            if (_properties.VehicleProps != null && _properties.VehicleProps.Type != VehicleType.None)
            {
                //init dynamics
                CheckCreateVehicleDynamics();
            }
        }
Example #9
0
 public PhysxPrim(PhysxScene scene, PrimitiveBaseShape baseShape, OpenMetaverse.Vector3 pos,
     OpenMetaverse.Quaternion rotation, PhysicsShape myShape, PhysX.RigidActor myActor,
     bool isPhysical, IPhysicsProperties properties, CollisionGroupFlag collisionGroup)
     : this(null, scene, baseShape, pos, rotation, myShape, myActor, isPhysical, properties, collisionGroup)
 {
     
 }
Example #10
0
        /// <summary>
        /// Called by a child prim of this group when its shape has changed
        /// </summary>
        /// <param name="physxPrim"></param>
        /// <param name="newShape"></param>
        private void ChildShapeChanged(PhysxPrim physxPrim, PhysicsShape newShape)
        {
            PhysicsShape oldShape = this.RemoveChildShape(physxPrim);

            if (oldShape != null)
            {
                _scene.MeshingStageImpl.UnrefShape(oldShape, _isPhysical);
            }

            this.CombineChildShape(newShape, physxPrim, physxPrim.Position, physxPrim.Rotation, false);
        }
Example #11
0
        /// <summary>
        /// Rebuilds this actor given a new shape and child shapes
        /// </summary>
        /// <param name="newShape"></param>
        /// <param name="childShapes"></param>
        /// <param name="physical"></param>
        internal void RebuildPhysxActorWithNewShape(PhysicsShape newShape, Dictionary<PhysxPrim, RelatedShapes> newChildShapes, bool physical,
            bool isChildUnlink)
        {
            if (HasActor || isChildUnlink)
            {
                PhysX.RigidDynamic physActor;
                if (physical)
                {
                    physActor = PhysxActorFactory.CreateRigidDynamic(_scene, newShape, _position, _rotation, physical, this.Selected, _properties.PhysxMaterial);
                    if (isChildUnlink) _scene.AddPrimSync(this, physical, false);
                    _scene.PrimMadeDynamic(this);
                }
                else
                {
                    physActor = PhysxActorFactory.CreateRigidDynamic(_scene, newShape, _position, _rotation, physical, true, _properties.PhysxMaterial);
                    if (isChildUnlink) _scene.AddPrimSync(this, physical, true);
                    _scene.PrimMadeStaticKinematic(this);
                }

                this.ReassignActors(newShape, physActor, newChildShapes, physical);

                if (!physical)
                {
                    this.ClearForcesAndSendUpdate();
                }
            }
            else
            {
                //we are a child prim and part of another group, let our parent know that our shape changed
                _parentPrim.ChildShapeChanged(this, newShape);
            }
        }
Example #12
0
        /// <summary>
        /// Checks whether or not this new child shape would put us over our complexity limit
        /// </summary>
        /// <param name="childShape">The shape to test</param>
        /// <returns>True if this actor is still under the limit with the shape installed, false if not</returns>
        private bool CheckComplexityLimitsWithNewChild(PhysicsShape childShape)
        {
            int newComplexity = childShape.Complexity + this.TotalComplexity;
            if (newComplexity > MAX_DYNAMIC_COMPLEXITY)
            {
                TriggerComplexityError(String.Format("Object was too complex to be made physical: ({0} of {1} convex hulls)", newComplexity, PhysxPrim.MAX_DYNAMIC_COMPLEXITY));
                return false;
            }

            return true;
        }
Example #13
0
 void _meshingStage_OnShapeNeedsFreeing(PhysicsShape shape)
 {
     this.QueueCommand(new Commands.DestroyShapeCmd {
         Shape = shape
     });
 }
Example #14
0
        private void DeleteActor(PhysX.RigidActor oldActor, PhysicsShape oldShape, bool wasPhysical, DeleteActorFlags flags)
        {
            if (oldActor != null)
            {
                if (_touchCounts.IsValueCreated)
                {
                    SendCollisionEndToContactedObjects();
                    _touchCounts.Value.Clear();
                }

                _scene.ForEachCharacter((PhysxCharacter character) =>
                {
                    character.InvalidateControllerCacheIfContacting(this);
                }
                );

                _scene.SceneImpl.RemoveActor(oldActor);
                oldActor.Dispose();

                if ((flags & DeleteActorFlags.DestroyPrimaryMaterial) != 0)
                {
                    _properties.PhysxMaterial.CheckedDispose();
                }

                if ((flags & DeleteActorFlags.DestroyChildMaterials) != 0)
                {
                    //also dispose child prim materials
                    foreach (PhysxPrim prim in _childShapes.Keys)
                    {
                        prim._properties.PhysxMaterial.CheckedDispose();
                    }
                }

                //unref our old shape
                if (oldShape != null)
                {
                    _scene.MeshingStageImpl.UnrefShape(oldShape, wasPhysical);

                    if ((flags & DeleteActorFlags.UnrefChildShapes) != 0)
                    {
                        //unref child shapes
                        foreach (RelatedShapes childShapes in _childShapes.Values)
                        {
                            _scene.MeshingStageImpl.UnrefShape(childShapes.ChildShape, wasPhysical);
                        }
                    }
                }

                //everyone watching us for delete should be informed
                Action<PhysxPrim> onDel = this.OnDeleted;
                if (onDel != null)
                {
                    onDel(this);
                    foreach (Action<PhysxPrim> act in onDel.GetInvocationList())
                    {
                        onDel -= act;
                    }
                }

                if (_primsBeingWatchedForDeletes.IsValueCreated)
                {
                    foreach (var prim in _primsBeingWatchedForDeletes.Value)
                    {
                        prim.OnDeleted -= new Action<PhysxPrim>(other_OnDeleted);
                    }

                    _primsBeingWatchedForDeletes = new Lazy<List<PhysxPrim>>();
                }

                //no matter if we're unreffing or not, the actual child shape list is now invalid becase
                //these shapes were part of our old physx actor
                _childShapes.Clear();
                _shapeToPrimIndex.Clear();
                _primaryShapes.Clear();
            }
        }
Example #15
0
        private void AssignActor(PhysX.RigidActor myActor, PhysicsShape newShape, bool isPhysical, DeleteActorFlags flags)
        {
            PhysX.RigidActor oldActor = _actor;
            PhysicsShape oldShape = null;
            
            if (newShape != null)
            {
                oldShape = _myShape;
                _myShape = newShape;
            }

            _actor = myActor;
            
            if (_actor != null && _actor is PhysX.RigidDynamic)
            {
                _dynActor = (PhysX.RigidDynamic)_actor;
                CacheMassData();
            }
            else
            {
                _dynActor = null;
            }

            bool wasPhysical = _isPhysical;
            _isPhysical = isPhysical;

            if (HasActor) _scene.SceneImpl.AddActor(_actor);       //add to physx scene
            this.DeleteActor(oldActor, oldShape, wasPhysical, flags);

            if (_actor != null)
            {
                _actor.UserData = this;
                this.IndexAndConfigurePrimaryShapes();
            }

            ClearForcesAndSendUpdate();
            ChangeGravityIfNeeded();
        }
Example #16
0
        /// <summary>
        /// Creates a new PhysX.RigidStatic using our defaults
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="position"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public static PhysX.RigidStatic CreateRigidStatic(PhysxScene scene, PhysicsShape shape, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation,
            Material material)
        {
            PhysX.RigidStatic physActor = scene.SceneImpl.Physics.CreateRigidStatic();
            SetCommonProperties(scene, shape, position, rotation, physActor, false, material);

            return physActor;
        }
Example #17
0
 private static void SetCommonProperties(PhysxScene scene, PhysicsShape shape, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation, PhysX.RigidActor physActor,
     bool physical, Material material)
 {
     shape.AssignToActor(physActor, material.PhyMaterial, physical);
     physActor.GlobalPose =
         PhysX.Math.Matrix.RotationQuaternion(new PhysX.Math.Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W)) *
         PhysX.Math.Matrix.Translation(position.X, position.Y, position.Z);
 }
Example #18
0
        private void ReassignActors(PhysicsShape shape, PhysX.RigidActor actor, Dictionary<PhysxPrim, RelatedShapes> newChildShapes, bool isPhysical)
        {
            OBBobject = null;

            //all bets are off for collision data, our actor has changed. Reset.
            ClearTrackedTouches();

            DeleteActorFlags flags = DeleteActorFlags.None;
            bool wasVd = IsVolumeDetect;

            if (newChildShapes != null)
            {
                //we are reassigning our children, so existing materials are still valid, but
                //the old shapes are not
                flags |= DeleteActorFlags.UnrefChildShapes;
            }
            else
            {
                newChildShapes = _childShapes;
                _childShapes = new Dictionary<PhysxPrim, RelatedShapes>();
            }

            this.AssignActor(actor, shape, isPhysical, flags);     //reassign member vars and remove old actor if exists
            
            if (newChildShapes != null)
            {
                foreach (KeyValuePair<PhysxPrim, RelatedShapes> kvp in newChildShapes)
                {
                    this.CombineChildShape(kvp.Value.ChildShape, kvp.Key, kvp.Key.Position, kvp.Key.Rotation, true);
                }

                UpdateMassAndInertia();
            }

            //make sure this is the last step so that all of our child shapes have been registered
            if (_properties.WantsCollisionNotification) this.EnableCollisionEventsSync();

            this.DynamicsPostcheck();

            if (wasVd)
            {
                SetVolumeDetectSync(wasVd);
            }
        }
Example #19
0
        private void ChangeToChild(PhysxPrim parent, OpenMetaverse.Vector3 localPos, OpenMetaverse.Quaternion localRot)
        {
            _parentPrim = parent;

            //this prim no longer has its old shape or its actor
            _scene.PrimBecameChild(this);

            //if we have children, we need to unref their shapes here, as our new parent (ours and our children)
            //may require different shape types and will be rebuilt
            this.DeleteActor(_actor, _myShape, _isPhysical, DeleteActorFlags.UnrefChildShapes);

            _actor = null;
            _dynActor = null;
            _myShape = null;

            _position = localPos;
            _rotation = localRot;
        }
Example #20
0
        internal void LinkPrimAsChildSync(PhysicsShape childShape, PhysxPrim newChild, OpenMetaverse.Vector3 localPos, OpenMetaverse.Quaternion localRot, 
            bool delayInertiaRecalc)
        {
            newChild.ChangeToChild(this, localPos, localRot);

            this.CombineChildShape(childShape, newChild, localPos, localRot, delayInertiaRecalc);
        }
Example #21
0
        private void CombineChildShape(PhysicsShape childShape, PhysxPrim newChild, OpenMetaverse.Vector3 localPos, OpenMetaverse.Quaternion localRot, 
            bool delayInertiaRecalc)
        {
            //calculate the local rotation for the new shape we'll add to replace the combined child
            PhysX.Math.Matrix localPose = PhysUtil.PositionToMatrix(localPos, localRot);

            if (!_isPhysical || this.CheckComplexityLimitsWithNewChild(childShape))
            {
                try
                {
                    List<PhysX.Shape> actorShapes = childShape.AssignToActor(_actor, newChild.PhysxProperties.PhysxMaterial.PhyMaterial, localPose, _isPhysical);

                    _childShapes.Add(newChild, new RelatedShapes { ChildShape = childShape, PhyShapes = actorShapes });
                    foreach (PhysX.Shape shape in actorShapes)
                    {
                        _shapeToPrimIndex.Add(shape, newChild);
                    }

                    CollisionGroup.SetCollisionGroup(_collisionGroup, actorShapes);

                    if (!delayInertiaRecalc) UpdateMassAndInertia();

                    if (newChild.Properties.WantsCollisionNotification)
                    {
                        this.EnableChildCollisionEventsSync(newChild, true);
                    }

                    newChild._isPhysical = _isPhysical;
                }
                catch (NullReferenceException e) //this catch is in place to try and find an obscure bug where a cast inside the C++/CLI side of the physx sdk throws
                {
                    m_log.ErrorFormat("[InWorldz.PhysX] Unable to assign child shapes to a physactor: {0}, Material: {1}, Pose: {2}", e, newChild.PhysxProperties.PhysxMaterial.PhyMaterial, localPose);
                    _childShapes.Add(newChild, new RelatedShapes { ChildShape = childShape, PhyShapes = new List<PhysX.Shape>(0) });
                    childShape.DecRef();
                }
            }
            else
            {
                //too complex, free the child shape and issue a warning to the owner
                _childShapes.Add(newChild, new RelatedShapes { ChildShape = childShape, PhyShapes = new List<PhysX.Shape>(0) });

                childShape.DecRef();
            }
        }
Example #22
0
 void _meshingStage_OnShapeNeedsFreeing(PhysicsShape shape)
 {
     this.QueueCommand(new Commands.DestroyShapeCmd { Shape = shape });
 }
Example #23
0
        public static PhysX.RigidActor CreateProperInitialActor(PhysicsShape meshedShape, PhysxScene scene, OpenMetaverse.Vector3 pos, 
            OpenMetaverse.Quaternion rotation, PhysicsScene.AddPrimShapeFlags flags, out bool kinematicStatic,
            Material material)
        {
            bool isPhysical = (flags & PhysicsScene.AddPrimShapeFlags.Physical) != 0;
            kinematicStatic = false;

            PhysX.RigidActor actor;
            if (isPhysical)
            {
                actor = PhysxActorFactory.CreateRigidDynamic(scene, meshedShape, pos, rotation, isPhysical, kinematicStatic, material);
            }
            else
            {
                if ((flags & PhysicsScene.AddPrimShapeFlags.FromSceneStartup) != 0)
                {
                    actor = PhysxActorFactory.CreateRigidStatic(scene, meshedShape, pos, rotation, material);
                }
                else
                {
                    kinematicStatic = true;
                    actor = PhysxActorFactory.CreateRigidDynamic(scene, meshedShape, pos, rotation, isPhysical, kinematicStatic, material);
                }
            }

            return actor;
        }