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; }
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); }
/// <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); }
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); }
/// <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; }
/// <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); }
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(); } }
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) { }
/// <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); }
/// <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); } }
/// <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; }
void _meshingStage_OnShapeNeedsFreeing(PhysicsShape shape) { this.QueueCommand(new Commands.DestroyShapeCmd { Shape = shape }); }
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(); } }
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(); }
/// <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; }
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); } }
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; }
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); }
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(); } }
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; }