protected override void OnAttach() { InternalRigidBody = new BulletSharp.RigidBody(0.0f, MotionState, ColliderShape.InternalShape, Vector3.Zero) { UserObject = this }; NativeCollisionObject = InternalRigidBody; NativeCollisionObject.ContactProcessingThreshold = !Simulation.CanCcd ? 1e18f : 1e30f; if (ColliderShape.NeedsCustomCollisionCallback) { NativeCollisionObject.CollisionFlags |= BulletSharp.CollisionFlags.CustomMaterialCallback; } if (ColliderShape.Is2D) //set different defaults for 2D shapes { InternalRigidBody.LinearFactor = new Vector3(1.0f, 1.0f, 0.0f); InternalRigidBody.AngularFactor = new Vector3(0.0f, 0.0f, 1.0f); } var inertia = ColliderShape.InternalShape.CalculateLocalInertia(mass); InternalRigidBody.SetMassProps(mass, inertia); InternalRigidBody.UpdateInertiaTensor(); //this was the major headache when I had to debug Slider and Hinge constraint base.OnAttach(); Mass = mass; LinearDamping = linearDamping; AngularDamping = angularDamping; OverrideGravity = overrideGravity; Gravity = gravity; RigidBodyType = IsKinematic ? RigidBodyTypes.Kinematic : RigidBodyTypes.Dynamic; GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(out transform); SetWorldTransformCallback = transform => RigidBodySetWorldTransform(ref transform); UpdatePhysicsTransformation(); //this will set position and rotation of the collider if (IsDefaultGroup) { Simulation.AddRigidBody(this, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { Simulation.AddRigidBody(this, (CollisionFilterGroupFlags)CollisionGroup, CanCollideWith); } }
private void NewElement(PhysicsElementBase element, AssociatedData data, Entity entity) { element.Data = data; if (element.ColliderShapes.Count == 0) { return; //no shape no purpose } if (element.ColliderShape == null) { element.ComposeShape(); } var shape = element.ColliderShape; if (shape == null) { return; //no shape no purpose } element.BoneIndex = -1; var skinnedElement = element as PhysicsSkinnedElementBase; if (skinnedElement != null && !skinnedElement.NodeName.IsNullOrEmpty() && data.ModelComponent?.Skeleton != null) { if (!data.BoneMatricesUpdated) { Vector3 position, scaling; Quaternion rotation; entity.Transform.WorldMatrix.Decompose(out scaling, out rotation, out position); var isScalingNegative = scaling.X * scaling.Y * scaling.Z < 0.0f; data.ModelComponent.Skeleton.NodeTransformations[0].LocalMatrix = entity.Transform.WorldMatrix; data.ModelComponent.Skeleton.NodeTransformations[0].IsScalingNegative = isScalingNegative; data.ModelComponent.Skeleton.UpdateMatrices(); data.BoneMatricesUpdated = true; } skinnedElement.BoneIndex = data.ModelComponent.Skeleton.Nodes.IndexOf(x => x.Name == skinnedElement.NodeName); if (element.BoneIndex == -1) { throw new Exception("The specified NodeName doesn't exist in the model hierarchy."); } element.BoneWorldMatrixOut = element.BoneWorldMatrix = data.ModelComponent.Skeleton.NodeTransformations[element.BoneIndex].WorldMatrix; } var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0; switch (element.Type) { case PhysicsElementBase.Types.PhantomCollider: { var c = simulation.CreateCollider(shape); element.Collider = c; //required by the next call element.Collider.Entity = entity; //required by the next call element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider c.IsTrigger = true; if (defaultGroups) { simulation.AddCollider(c, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElementBase.Types.StaticCollider: { var c = simulation.CreateCollider(shape); element.Collider = c; //required by the next call element.Collider.Entity = entity; //required by the next call element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider if (defaultGroups) { simulation.AddCollider(c, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElementBase.Types.StaticRigidBody: { var rb = simulation.CreateRigidBody(shape); rb.Entity = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, ref transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Static; rb.Mass = 0.0f; if (defaultGroups) { simulation.AddRigidBody(rb, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElementBase.Types.DynamicRigidBody: { var rb = simulation.CreateRigidBody(shape); rb.Entity = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, ref transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Dynamic; if (rb.Mass == 0.0f) { rb.Mass = 1.0f; } if (defaultGroups) { simulation.AddRigidBody(rb, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElementBase.Types.KinematicRigidBody: { var rb = simulation.CreateRigidBody(shape); rb.Entity = entity; rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform); rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, ref transform); element.Collider = rb; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider rb.Type = RigidBodyTypes.Kinematic; if (rb.Mass == 0.0f) { rb.Mass = 1.0f; } if (defaultGroups) { simulation.AddRigidBody(rb, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } } break; case PhysicsElementBase.Types.CharacterController: { var charElem = (CharacterElement)element; var ch = simulation.CreateCharacter(shape, charElem.StepHeight); element.Collider = ch; element.Collider.Entity = entity; element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider if (defaultGroups) { simulation.AddCharacter(ch, CollisionFilterGroupFlags.DefaultFilter, CollisionFilterGroupFlags.AllFilter); } else { simulation.AddCharacter(ch, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith); } characters.Add(element); } break; } if (colliderShapesRendering) { element.AddDebugEntity(sceneSystem.SceneInstance.Scene); } elements.Add(element); if (element.BoneIndex != -1) { boneElements.Add(skinnedElement); } }