How to update physiscs/collision body

Think you found a bug ? This is where to go...

Moderator: Brume Dev Team

How to update physiscs/collision body

Postby Bartman on Wed Sep 05, 2007 7:35 am

Hi

In my program I change the size of an object (cube) which has a physics body (obj.HasPhysicsAndCollisions = true). When the size has changed I need to update the physics system but I can't see how. I've tried:

Code: Select all
                obj.HasPhysicsAndCollisions = false;
                obj.HasPhysicsAndCollisions = true;


This sort of works, but bad things start to happen e.g. simulation gets slower and slower probably due to lots of generated bodies ...

Another thing; if I destroy an object with DestroyObject, it's visuals disappear, but its physics behavior remains active in the world. How should I properly destroy an object with physics and collisions.?

Thanks!
Bart

ps here's the (problematic) code

Code: Select all
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Brume;
using System.Timers;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections.Generic;

namespace BrumeTest
{
    public class BrumeTest : Brume.Brume
    {
        [DllImport("kernel32.dll")]
        static extern bool SetProcessAffinityMask(IntPtr hProcess, UIntPtr dwProcessAffinityMask);

        private bool _materialize = false;
        private System.Timers.Timer _timer = null;
        private bool _bGravReversed = false;
        private BrumeCubeColored _zombie = null;
        private Queue<BrumeCubeColored> _cubes = new Queue<BrumeCubeColored>();

        public BrumeTest()
        {
            //this.InitStates.Mode = BrumeInitParams.MODE_FULLSCREEN;
            this.InitStates.Resolution = BrumeInitParams.RESOLUTION_1024x768;
            this.InitStates.Mode = BrumeInitParams.MODE_FULLSCREEN;

            IntPtr handle = (IntPtr)Process.GetCurrentProcess().Handle;
            UIntPtr affinityMask = new UIntPtr((uint)1);
            if (!SetProcessAffinityMask(handle, affinityMask))
                MessageBox.Show("Error code: " + Marshal.GetLastWin32Error());

        }

        void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _materialize = true;
        }

        override protected void GameInit()
        {
            Camera();
            Lights();
            Mirror();
            SetupPhysicsFloor();
            Wall();

            this.GlobalAmbientLight = Color.Black;

            _timer = new System.Timers.Timer(1000);
            _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
            _timer.Start();
        }


        protected override void AfterRendering()
        {
            base.AfterRendering();
            // exit ?
            if (BrumeKeyboard.IsPressed(BrumeKey.Escape))
            {
                this.Close();
                return;
            }

        }

        protected override void RenderScene()
        {
           this.ArialFont.Reset();
           this.ArialFont.RenderStates.AmbientLight = Color.Violet;
           this.ArialFont.AddMsg(HUDX(10), HUDY(BrumeHeight - 70), "Press [Space] to fire");
           this.ArialFont.AddMsg(HUDX(10), HUDY(BrumeHeight - 50), "Press [R] to reverse gravity");

            base.RenderScene();
        }

        protected override void MoveScene(float fElapsedTime)
        {
            if (BrumeKeyboard.IsPressedDelayed(BrumeKey.Space, fElapsedTime))
            {
                Random rnd = new Random();
                BrumeSphereColored bsf2 = new BrumeSphereColored(this, "bullet", 0.5f, 20, 20, Color.Wheat);

                bsf2.Size = 1.0f;
                bsf2.Pos = this.ActiveCamera.Pos;
                bsf2.Pos.Y -= 1.0f;

                this.InitObject(bsf2);

                bsf2.HasPhysicsAndCollisions = true;
                bsf2.PhysicsBody.Density = 0.1f;

                BrumeVector ballDir = this.ActiveCamera.Dir;
                float factor = (float)rnd.Next(500, 1200);

                ballDir.X *= factor;
                ballDir.Y *= factor;
                ballDir.Z *= factor;

                bsf2.PhysicsBody.AddForce(ballDir);
            }

            if (_materialize)
            {
                Random rnd = new Random();

                BrumeCubeColored bc = new BrumeCubeColored(
                    this,
                    "cube" + (this.GetObjects().Count + 1).ToString(),
                    Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255)));

                bc.Pos.X = -5f + (float)rnd.Next(10);
                bc.Pos.Y = 15f;
                bc.HasPhysicsAndCollisions = true;

                this.InitObject(bc);
               
                _cubes.Enqueue(bc);

                _materialize = false;

                if(_cubes.Count > 0 && _zombie == null)
                    _zombie = _cubes.Dequeue();
            }

            if (BrumeKeyboard.IsPressedDelayed(BrumeKey.R, fElapsedTime))
            {
                if (_bGravReversed)
                {
                    this.PhysicsWorld.SetGravity(0f, -20f, 0f);
                    _bGravReversed = false;
                }
                else
                {
                    // reverse gravity :-)
                    this.PhysicsWorld.SetGravity(0f, 0.3f, 0f);
                    _bGravReversed = true;
                }
            }

            BrumeFPSCamera camera = (BrumeFPSCamera)this.ActiveCamera;
            if (camera != null)
                camera.FPSOrient((float)this.MouseDeltaX / (float)2, (float)this.MouseDeltaY / (float)2);

            if (_zombie != null)
            {
                _zombie.Size = Math.Max(0, _zombie.Size - 0.05f);
               
                // 'update' physics...
                _zombie.HasPhysicsAndCollisions = false;
                _zombie.HasPhysicsAndCollisions = true;

                if (_zombie.Size == 0)
                {
                    // die
                    this.DestroyObject(_zombie);
                    _zombie = null;
                }
            }
        }

        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
       
            BrumeFileManager.AddDirForAll("../../Data/Internal");

            using (BrumeTest game = new BrumeTest())
            {
                game.Play();
            }
        }

        private void Camera()
        {
            // camera setup
            BrumeVector cameraPos = new BrumeVector(0.0f, 5.0f, -15.0f);
            BrumeVector cameraDir = new BrumeVector(0, 0.0f, 1f);
            BrumeVector cameraUp = new BrumeVector(0.0f, 1.0f, 0.0f);

            BrumeFPSCamera camera = new BrumeFPSCamera(this, "camera", cameraPos, cameraDir, cameraUp);
            camera.FrustumCulling = false;
            this.SetActiveCamera(camera);
        }

        private void Mirror()
        {
            BrumeMirror mirror = new BrumeMirror(this, "mirror", 512, 512);
            mirror.Orient(new BrumeVector(0, -1, 0), new BrumeVector(0, 0, 1));

            mirror.RenderStates.UseOwnAmbientLight = true;
            mirror.RenderStates.AmbientLight = Color.Gray;

            mirror.Size = 2000.0f;
            mirror.Pos.Y = 0f;

            this.GraphicApi.SetPixelExponentalFog(Color.DarkBlue, 0.01f);
        }

        private void SetupPhysicsFloor()
        {
            // PHYSICS & COLLISION (based on ODE)
            this.PhysicsWorld.SetGravity(0f, -20.0f, 0);

            BrumeCollisionPlane floor = new BrumeCollisionPlane(this, 0, 1, 0, .5f, null);

            floor.SufacePhysics.Bouncy = true;
            floor.SufacePhysics.BounceValue = .5f;
            floor.SufacePhysics.MinimumBounceVelocity = 0.1f;
            floor.SufacePhysics.Friction = float.MaxValue;
            floor.SufacePhysics.Slip = 0.0f;
        }

        private void Lights()
        {
            BrumeLight light = new BrumeDirectionalLight(
                this,
                "light",
                new BrumeVector(0.0f, 0.0f, 1.0f),
                new BrumeVector(1.0f, 1.0f, 0.0f),
                Color.Yellow);

            light.Specular = Color.FromArgb(255, 255, 255, 255);
            light.Enabled = true;
            light.Update();
        }

        private void Wall()
        {
            Random rnd = new Random();
            for (int x = 0; x < 10; ++x)
            {
                for (int y = 0; y < 6; ++y)
                {
                    BrumeCubeColored bc = new BrumeCubeColored(
                        this,
                        "cube" + x.ToString() + y.ToString(),
                        Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255)));

                    bc.Pos.X = 1.2f * (float)(-5 + x);
                    bc.Pos.Y = 1.7f + (float)(y);

                    bc.RenderStates.UseOwnAmbientLight = false;
                    bc.HasPhysicsAndCollisions = true;

                    this.InitObject(bc);
                    _cubes.Enqueue(bc);

                    bc.PhysicsBody.Density = 1.0f;
                }
            }
        }
    }
}
User avatar
Bartman
Brume user
 
Posts: 23
Joined: Wed Oct 11, 2006 7:01 am
Location: The Netherlands

Re: How to update physiscs/collision body

Postby Silmaryls on Thu Sep 06, 2007 9:15 pm

Hi Bart,

You are using the good method to update physics and collision shapes.
I checked the source code and I am removing and disposing the physic body but collision shapes are missing the Dispose call.
There must be a memory leak there.

For DestroyObject I had to add the same source code you are using (I forgot it there sorry !) so as a workaround you can just add the line after the call yourself:
Code: Select all
obj.HasPhysicsAndCollisions = false;

But you will still get the memory/slowdown problem.

I think you can also try a workaround for this : try to call the GetCollisionShapes method on your object and then to destroy the shapes yourself with something like that :
Code: Select all
foreach (BrumeCollisionShape shape in obj.GetCollisionShapes())
{
   shape.CollisionShape.Enabled = false;
   shape.CollisionShape.Dispose();
}
obj.HasPhysicsAndCollisions = false;
obj.HasPhysicsAndCollisions = true;


I'm transferring your post to the bug forum in order to fix the problem.

Silmaryls
User avatar
Silmaryls
Brume Team Member
 
Posts: 340
Joined: Tue Feb 21, 2006 10:09 pm
Location: Paris - France


Return to Bugs In English

Who is online

Users browsing this forum: No registered users and 1 guest

cron