Charachter controller

Discuss any questions about BEPUphysics or problems encountered.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Charachter controller

Post by mohammadAdnan »

Hello BEPU :) ,

I try to implement Charachter controller for FPS game and for now the only errore is this in Querymanager.cs

cannot convert from 'BEPUphysics.CollisionRuleManagement.CollisionRules' to 'BEPUphysics.CollisionRuleManagement.ICollisionRulesOwner

this is the function
Func<BroadPhaseEntry, bool> SupportRayFilter;
bool SupportRayFilterFunction(BroadPhaseEntry entry)
{
//Only permit an object to be used as a support if it fully collides with the character.
return CollisionRules.CollisionRuleCalculator(entry.CollisionRules, character.Body.CollisionInformation.CollisionRules) == CollisionRule.Normal;
}

I hope to solve this error to see if charachter controller work :) !!!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

It sounds like it's related to a mismatched version of the character controller and BEPUphysics. I would recommend just grabbing the latest source from the development fork for both the library and the character; that will ensure consistency.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Re: Charachter controller

Post by mohammadAdnan »

thanks BEPU :) , I feel great .

BEPU I just want few steps to go on , I want to make FBX model move with camera nothing else ! :) so I hope to give me one mint to go on on my project , as my team know about AI,Graphics stuff.

Now I have Charachter controller ready (Jump , step ...etc ) great ! , now I import Skeleton model sample from microsoft (FBX) with animation clip done , how to import it inside physics simulation and plug it in my charachter controller so that it moves with the camera and his hands shown on the screen !
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

To make a model move around with the character controller, grab the CharacterController.Body.Position. This is the center of the character entity. You can use it to translate your model. For rotation, typically the view direction (or something based on the view direction) is used. Putting the character hands on the screen just depends on setting up the animation, models, and projections properly. All of this, however, is outside the scope of the physics; it is purely graphical in nature.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Re: Charachter controller

Post by mohammadAdnan »

Norbo How are you ? :)

Before I try to solve the previous problem , I try to used my own graphics drawer as this is your advice ! , of course Convex hull did not work ! I just try to replace the

ModelDrawer.draw(view , projection ) with my own :

ModelGraphics.Draw( View, projection); and of course before draw my model this is the code I used to make convex hull and add it to the Model.transform property :

Code: Select all

            //-----------------------------
            //--container
            //-----------------------------
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices2;
            int[] indices2;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/container"), out vertices2, out indices2);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh3 = new StaticMesh(vertices2, indices2, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices2, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/container"), hull.WorldTransform));
and this is the the class I coded instead of DrawerModel coded by BEPU :

Code: Select all

    class ModelGraphics
    {
        Model model;

        /// <summary>
        /// Base transformation to apply to the model.
        /// </summary>
        public Matrix Transform;
        Matrix[] boneTransforms;


        /// <summary>
        /// Creates a new EntityModel.
        /// </summary>
        /// <param name="entity">Entity to attach the graphical representation to.</param>
        /// <param name="model">Graphical representation to use for the entity.</param>
        /// <param name="transform">Base transformation to apply to the model before moving to the entity.</param>
        /// <param name="game">Game to which this component will belong.</param>
        public ModelGraphics(Model model, Matrix transform)
        {
            this.model = model;
            this.Transform = transform;

            //Collect any bone transformations in the model itself.
            //The default cube model doesn't have any, but this allows the EntityModel to work with more complicated shapes.
            boneTransforms = new Matrix[model.Bones.Count];

            foreach (ModelMesh mesh in model.Meshes) {
                foreach (BasicEffect effect in mesh.Effects) {
                    effect.EnableDefaultLighting();
                }
            }
        }

        public void Draw(ModelDrawer modeldrawer, Matrix View, Matrix Projection)
        {
            //modeldrawer.Draw(View, Projection);

            //Notice that the entity's worldTransform property is being accessed here.
            //This property is returns a rigid transformation representing the orientation
            //and translation of the entity combined.
            //There are a variety of properties available in the entity, try looking around
            //in the list to familiarize yourself with it.
             Matrix worldMatrix = Transform;

            model.CopyAbsoluteBoneTransformsTo(boneTransforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = boneTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = View;
                    effect.Projection = Projection;
                }
                mesh.Draw();
            }
        }
Norbo , when the game starts my character falls and never collide with the Models!
I don't know what is the problem , I read all the topics around and in the documentation of BEPU ,Norbo sorry for this question because I know you answered it alot !!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

Norbo , when the game starts my character falls and never collide with the Models!
Make sure everything you want to collide with is actually added to the Space. I don't see a Space.Add for the mesh in the given code. In addition, if things seem to collide in the wrong place or fall through and hit a ghost surface, the graphics are probably just offset from the physics.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Re: Charachter controller

Post by mohammadAdnan »

Code: Select all

 Vector3[] vertices2;
            int[] indices2;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/container"), out vertices2, out indices2);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh3 = new StaticMesh(vertices2, indices2, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices2, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/container"), hull.WorldTransform));
Norbo . first, I add the hull of the model to the space not the model it self !! and send the hull.world transform to offset the model when draw .
second , dose I have to update the transform matrix used to offset the model every time I draw the model with convex hull ?

this is the complete modelmanager.cs class :

Code: Select all

 public ModelDrawer ModelDrawer;
        //private ModelGraphics AM_GraphicsModelGraphics;
        private List<ModelGraphics> models = new List<ModelGraphics>();

        public Space space = new Space();
        //Model CubeModel;

        CharacterControllerInput cci;

        GraphicsDevice graphicsDevice;

        Game game;

        // Load Models ,Charachter controller
        public ModelManager(Game game , GraphicsDevice graphicdevice)
        {
            ModelDrawer = new BruteModelDrawer(game);
            this.game = game;
            this.graphicsDevice = graphicdevice;
        }


        public void LoadContent(ContentManager Content , Camera camera)
        {
            ConvexHull hull;

            //CubeModel = Content.Load<Model>("Models/Level1/cube");

            //-----------------------------
            //--Level 1
            //-----------------------------
            Model Leve1 = Content.Load<Model>("Models/Level1/playground");
            Vector3[] vertices;
            int[] indices;
            TriangleMesh.GetVerticesAndIndicesFromModel(Leve1, out vertices, out indices);
            StaticMesh meshh = new StaticMesh(vertices, indices, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(0, -500, 0)));

            // Add Hull
            hull = new ConvexHull(vertices, 10);
            space.Add(hull);
            // Make it visible too.
            // Physics engine require to not change the information about Model he store 
            // or if changed he will not reqoqnized of the model
            //models.Add(new ModelGraphics(Leve1, hull.WorldTransform));
            StaticModel m = new StaticModel(Content.Load<Model>("Models/Level1/playground"), hull.WorldTransform, game);
            
            //-----------------------------
            //--container
            //-----------------------------
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices2;
            int[] indices2;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/container"), out vertices2, out indices2);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh3 = new StaticMesh(vertices2, indices2, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices2, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/container"), hull.WorldTransform));


            //-----------------------------
            //--chair
            //-----------------------------
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices3;
            int[] indices3;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/chair"), out vertices3, out indices3);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh4 = new StaticMesh(vertices3, indices3, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices3, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/chair"), hull.WorldTransform));


            //-----------------------------
            //--chair2
            //-----------------------------
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices4;
            int[] indices4;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/chair2"), out vertices4, out indices4);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh5 = new StaticMesh(vertices4, indices4, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices4, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/chair2"), hull.WorldTransform));


            //-----------------------------
            //--sphere
            //-----------------------------
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices5;
            int[] indices5;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/sphere"), out vertices5, out indices5);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh6 = new StaticMesh(vertices5, indices5, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices5, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/sphere"), hull.WorldTransform));

            //-----------------------------
            //--stairs
            //-----------------------------
            //Create a physical environment from a triangle mesh.
            //First, collect the the mesh data from the model using a helper function.
            //This special kind of vertex inherits from the TriangleMeshVertex and optionally includes
            //friction/bounciness data.
            //The StaticTriangleGroup requires that this special vertex type is used in lieu of a normal TriangleMeshVertex array.
            Vector3[] vertices6;
            int[] indices6;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/stairs"), out vertices6, out indices6);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh7 = new StaticMesh(vertices6, indices6, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices6, 10);
            //Add it to the space!
            space.Add(hull);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/stairs"), hull.WorldTransform));

            // Intialize the Chrachter Controller
            cci = new CharacterControllerInput(space, camera);
            cci.Activate();

            cci.CharacterController.HorizontalMotionConstraint.Speed *= 10;
            cci.CharacterController.HorizontalMotionConstraint.CrouchingSpeed *= 10;
            cci.CharacterController.HorizontalMotionConstraint.MaximumForce = 2500;
            cci.CharacterController.HorizontalMotionConstraint.MaximumAirForce = 2500;
            cci.CharacterController.StepManager.MaximumStepHeight = 100;

            // Add some entities to space
            for (int i = 1; i < 10; i++) {
                space.Add(new Box(new Vector3(0, (i * 10) + 40, 0), 5, 5, 0.5f, 1));
                space.Add(new Sphere(new Vector3(2, (i * 10) + 100, 101), 1, 1));
            }

            foreach (Entity e in space.Entities){
                ModelDrawer.Add(e);
            }

            space.ForceUpdater.Gravity = new Vector3(0, -40.81f, 0);
        }

        public void Update(GameTime gameTime, KeyboardState KeyboardInputt, KeyboardState PreviousKeyboardInputt)
        {

            cci.Update((float)gameTime.ElapsedGameTime.TotalSeconds, PreviousKeyboardInputt, KeyboardInputt);

            ModelDrawer.Update();

            space.Update();
        }



        public void Draw(Matrix View , Matrix projection) {

            graphicsDevice.RasterizerState = RasterizerState.CullClockwise;

            foreach(ModelGraphics modelll in this.models)
            {
                modelll.Draw(View, projection);
            }


            //AM_GraphicsModelGraphics.Draw(ModelDrawer, View, projection);

        }
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

dose I have to update the transform matrix used to offset the model every time I draw the model with convex hull ?
The physics engine has no awareness of graphics. Nothing will update in response to the changes unless explicitly told to do so. So yes, the graphics must be told to move if the physics move.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Re: Charachter controller

Post by mohammadAdnan »

Ok , Norbo

I post the full Modelmanager.cs class , would you pls tell me what is wrong in it ? the convex hull not response . and I pass the hull.worldTransform for my graphics drawer to offset the graphics.

Code: Select all

            Vector3[] vertices2;
            int[] indices2;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/container"), out vertices2, out indices2);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh3 = new StaticMesh(vertices2, indices2, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(-200, 0, 0)));

            // Add hull
            hull = new ConvexHull(vertices2, 10);

            //Add it to the space!
            space.Add(hull);

            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/container"), hull.WorldTransform));
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

I post the full Modelmanager.cs class , would you pls tell me what is wrong in it ?
Sorry, graphics is a bit out of scope for this forum.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Re: Charachter controller

Post by mohammadAdnan »

ok Norbo :)

what to do with the convex hull after create it for the mesh ? ( general strategy pls )

1 : hull = new ConvexHull(vertices3, 10);
//Add it to the space!
space.Add(hull);

2 : send hull.wordltransform to my graphics drawer

3 : any furthermore steps Norbo ?

the main question is : Dose I have to send the hull.worldTransform to my graphics drawer each frame , or just pass it once.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

any furthermore steps Norbo ?
Assuming the simulation is running correctly (objects are created, added to the space, space is updated), there's not really anything else. The physics simulation is totally and completely isolated from the graphics.
Dose I have to send the hull.worldTransform to my graphics drawer each frame , or just pass it once.
The entity.WorldTransform changes over time as the object bounces around. If your graphics are not aware of the current position/orientation, they will not reflect the correct transform. In that case, there has to be some way for the graphics to get the new transform data. There are many ways to do it; the physics engine doesn't care which way is used.
mohammadAdnan
Posts: 48
Joined: Sat Jan 26, 2013 5:54 pm

Re: Charachter controller

Post by mohammadAdnan »

Hello Norbo :) , my team and I will never forgot all your help

I follow your steps for convex hull and now it works fine :) , I just send the hull entity created with each static mesh :) to the draw method like this :

Code: Select all

        public ModelGraphics(Model model,ConvexHull hul , Matrix transform)
        {
            this.model = model;
            this.Transform = transform;
            this.hull = hul;

            //Collect any bone transformations in the model itself.
            //The default cube model doesn't have any, but this allows the StaticModel to work with more complicated shapes.
            boneTransforms = new Matrix[model.Bones.Count];
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                }
            }
        }

        public void Draw(Camera camera)
        {
            model.CopyAbsoluteBoneTransformsTo(boneTransforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = boneTransforms[mesh.ParentBone.Index] * hull.WorldTransform;
                    effect.View = camera.ViewMatrix;
                    effect.Projection = camera.projection;
                }
                mesh.Draw();
            }
        }
that's it as you said I have to update the convex hull entity for each model :)

Code: Select all

   
             // Level 1
            Vector3[] vertices6;
            int[] indices6;
            TriangleMesh.GetVerticesAndIndicesFromModel(Content.Load<Model>("Models/Level1/stairs"), out vertices6, out indices6);
            //Give the mesh information to a new StaticMesh.  
            //Give it a transformation which scoots it down below the kinematic box entity we created earlier.
            var mesh7 = new StaticMesh(vertices6, indices6, new AffineTransform(Matrix3X3.CreateScale(2), new Vector3(0, 200, 0)));
            // Add hull
            ConvexHull hull6 = new ConvexHull(vertices6, 10);
            //Add it to the space!
            space.Add(hull6);
            // Make it visible to
            models.Add(new ModelGraphics(Content.Load<Model>("Models/Level1/stairs"), hull6, hull6.WorldTransform));
and while doing this I face problem , as with each Model there is the same model drawn beside it and I found that the problem was from :

Code: Select all

            foreach (Entity e in space.Entities){
                ModelDrawer.Add(e);
            }
as I did not know that Hull is an entity !!!

Norbo , my first question is do you advice my to delete the ModelDrawer calss from my project and just used my own drawer class ? or it's not problem to use both at the same time like this :

Code: Select all

        public void Draw(Matrix View , Matrix projection) {

            graphicsDevice.RasterizerState = RasterizerState.CullClockwise;

            foreach(ModelGraphics model in this.models)
            {
                model.Draw(camera);
            }

            ModelDrawer.Draw(camera.ViewMatrix, camera.projection);
        }
    }
2 : if I delete the ModelDrawer.Draw(camera.ViewMatrix, camera.projection); , then the textures of models dose not appear(even they are drawn with another drawer class separated from ModelDrawer of BEPU) , but the model still colliode with my charachter !!

3 : I feel that while I am walking my charachter dose not walking normally ( wide steps ) and very large with respect the level models ?
Last edited by mohammadAdnan on Thu Feb 21, 2013 9:14 pm, edited 2 times in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

The BEPUphysicsDrawer is just a simple debug visualizer. If you want to test your own graphics implementation against one that is known to work, keeping the BEPUphysicsDrawer around is a good idea. Having them both running at the same time can be an effective debug tool. That's part of the reason it exists.

However, the BEPUphysicsDrawer is terrible when it comes to doing anything but visualizing multicolored entities and physics environments. It is not suitable for use as a game's main final graphics system.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Charachter controller

Post by Norbo »

2 : if I delete the ModelDrawer.Draw(camera.ViewMatrix, camera.projection); , then the textures of models dose not appear but the model still colliode with my charachter !!
This is a strictly graphical issue; I can't provide much help here.
3 : I feel that while I am walking my charachter dose not walking normally ( wide steps ) and very large with respect the level models ?
I'm not sure of the complete context, but it sounds like the character is just large relative to the environment. Scale up the environment or shrink the character.
Post Reply