// The object is going dynamic (physical). Do any setup necessary // for a dynamic linkset. // Only the state of the passed object can be modified. The rest of the linkset // has not yet been fully constructed. // Return 'true' if any properties updated on the passed object. // Called at taint-time! public override bool MakeDynamic(BSPhysObject child) { bool ret = false; DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); if (IsRoot(child)) { // The root is going dynamic. Make sure mass is properly set. ScheduleRebuild(LinksetRoot); } else { // The origional prims are removed from the world as the shape of the root compound // shape takes over. BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); // We don't want collisions from the old linkset children. BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); child.PhysBody.collisionType = CollisionType.LinksetChild; ret = true; } return(ret); }
private void SetPhysicalProperties() { BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); ZeroMotion(true); ForcePosition = _position; // Set the velocity and compute the proper friction ForceVelocity = _velocity; // Setting the current and target in the motor will cause it to start computing any deceleration. _velocityMotor.Reset(); _velocityMotor.SetCurrent(_velocity); _velocityMotor.SetTarget(_velocity); _velocityMotor.Enabled = false; // This will enable or disable the flying buoyancy of the avatar. // Needs to be reset especially when an avatar is recreated after crossing a region boundry. Flying = _flying; BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution); BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin); BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold); if (BSParam.CcdMotionThreshold > 0f) { BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold); BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } UpdatePhysicalMassProperties(RawMass, false); // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr, _position, _orientation); // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); // Do this after the object has been added to the world PhysBody.collisionType = CollisionType.Avatar; PhysBody.ApplyCollisionMask(); }
// Subscribe for collision events. // Parameter is the millisecond rate the caller wishes collision events to occur. public override void SubscribeEvents(int ms) { // DetailLog("{0},{1}.SubscribeEvents,subscribing,ms={2}", LocalID, TypeName, ms); SubscribedEventsMs = ms; if (ms > 0) { // make sure first collision happens NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); PhysicsScene.TaintedObject(TypeName + ".SubscribeEvents", delegate() { if (PhysBody.HasPhysicalBody) { CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); } }); } else { // Subscribing for zero or less is the same as unsubscribing UnSubscribeEvents(); } }