Exemplo n.º 1
0
        private void NewElement(PhysicsElement element, AssociatedData data, Entity entity)
        {
            if (element.Shape == null || element.Shape.Descriptions == null || element.Shape.Shape == null)
            {
                return;                                                                                             //no shape no purpose
            }
            var shape = element.Shape.Shape;

            element.Data      = data;
            element.BoneIndex = -1;

            if (!element.LinkedBoneName.IsNullOrEmpty())
            {
                element.BoneIndex = data.ModelComponent.ModelViewHierarchy.Nodes.IndexOf(x => x.Name == element.LinkedBoneName);

                if (element.BoneIndex == -1)
                {
                    throw new Exception("The specified LinkedBoneName doesn't exist in the model hierarchy.");
                }

                element.BoneWorldMatrixOut = element.BoneWorldMatrix = data.ModelComponent.ModelViewHierarchy.NodeTransformations[element.BoneIndex].WorldMatrix;
            }

            var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0;

            switch (element.Type)
            {
            case PhysicsElement.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);
                }
                else
                {
                    simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.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

                c.IsTrigger = false;

                if (defaultGroups)
                {
                    simulation.AddCollider(c);
                }
                else
                {
                    simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.StaticRigidBody:
            {
                var rb = Simulation.CreateRigidBody(shape);

                rb.Entity = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Static;

                if (defaultGroups)
                {
                    simulation.AddRigidBody(rb);
                }
                else
                {
                    simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.DynamicRigidBody:
            {
                var rb = Simulation.CreateRigidBody(shape);

                rb.Entity = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Dynamic;
                rb.Mass = 1.0f;

                if (defaultGroups)
                {
                    simulation.AddRigidBody(rb);
                }
                else
                {
                    simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.KinematicRigidBody:
            {
                var rb = Simulation.CreateRigidBody(shape);

                rb.Entity = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Kinematic;
                rb.Mass = 0.0f;

                if (defaultGroups)
                {
                    simulation.AddRigidBody(rb);
                }
                else
                {
                    simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.CharacterController:
            {
                var ch = Simulation.CreateCharacter(shape, element.StepHeight);

                element.Collider        = ch;
                element.Collider.Entity = entity;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                if (defaultGroups)
                {
                    simulation.AddCharacter(ch);
                }
                else
                {
                    simulation.AddCharacter(ch, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }

                characters.Add(element);
            }
            break;
            }

            elements.Add(element);
            if (element.BoneIndex != -1)
            {
                boneElements.Add(element);
            }
        }
Exemplo n.º 2
0
        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?.ModelViewHierarchy != 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.ModelViewHierarchy.NodeTransformations[0].LocalMatrix       = entity.Transform.WorldMatrix;
                    data.ModelComponent.ModelViewHierarchy.NodeTransformations[0].IsScalingNegative = isScalingNegative;
                    data.ModelComponent.ModelViewHierarchy.UpdateMatrices();
                    data.BoneMatricesUpdated = true;
                }

                skinnedElement.BoneIndex = data.ModelComponent.ModelViewHierarchy.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.ModelViewHierarchy.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;
            }

            elements.Add(element);
            if (element.BoneIndex != -1)
            {
                boneElements.Add(element);
            }
        }