public SoftRigidDynamicsWorld(Dispatcher dispatcher, BroadphaseInterface pairCache,
			ConstraintSolver constraintSolver, CollisionConfiguration collisionConfiguration,
			SoftBodySolver softBodySolver)
            : base(IntPtr.Zero)
		{
            if (softBodySolver != null) {
                _softBodySolver = softBodySolver;
                _ownsSolver = false;
            } else {
                _softBodySolver = new DefaultSoftBodySolver();
                _ownsSolver = true;
            }

            _native = btSoftRigidDynamicsWorld_new2(dispatcher._native, pairCache._native,
                (constraintSolver != null) ? constraintSolver._native : IntPtr.Zero,
                collisionConfiguration._native, _softBodySolver._native);

            _collisionObjectArray = new AlignedCollisionObjectArray(btCollisionWorld_getCollisionObjectArray(_native), this);

            _broadphase = pairCache;
			_constraintSolver = constraintSolver;
			_dispatcher = dispatcher;
            _worldInfo = new SoftBodyWorldInfo(btSoftRigidDynamicsWorld_getWorldInfo(_native), true);
            _worldInfo.Dispatcher = dispatcher;
            _worldInfo.Broadphase = pairCache;
		}
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            SoftBody sb = SoftBodyHelpers.CreateFromTriMesh(si, this.vertices, this.indices,this.randomizeContraints);
            this.SetConfig(sb);

            return sb;
        }
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            si.SparseSdf.Reset();
            SoftBody sb = SoftBodyHelpers.CreateFromConvexHull(si, this.vertices, this.randomizeContraints);
            this.SetConfig(sb);

            return sb;
        }
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            si.SparseSdf.Reset();
            SoftBody sb = SoftBodyHelpers.CreateRope(si, from, to, res,fix);
            this.SetConfig(sb);

            return sb;
        }
		public static SoftBody CreateFromConvexHull(SoftBodyWorldInfo worldInfo,
            Vector3[] vertices, bool randomizeConstraints = true)
		{
            SoftBody body = new SoftBody(btSoftBodyHelpers_CreateFromConvexHull2(
                worldInfo._native, vertices, vertices.Length, randomizeConstraints));
            body.WorldInfo = worldInfo;
            return body;
		}
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            si.SparseSdf.Reset();
            this.uvs = new float[(this.resx - 1) * (this.resy - 1) * 12];
            SoftBody sb = SoftBodyHelpers.CreatePatchUV(si, corner00, corner10, corner01, corner11, resx, resy, fix, diagonals,this.uvs);
            this.SetConfig(sb);

            return sb;
        }
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            si.SparseSdf.Reset();

            SoftBody sb = SoftBodyHelpers.CreateFromTetGenData(si, this.elements, this.faces, this.nodes,
                this.facelinks, this.tetralinks, this.facesfromtetra);

            this.SetConfig(sb);

            return sb;
        }
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            si.SparseSdf.Reset();
            SoftBody sb = SoftBodyHelpers.CreateEllipsoid(si, center, radius, res);
            this.uvs = new float[sb.Faces.Count * 6];
            int cnt = 0;
            for (int i = 0; i < sb.Faces.Count; i++)
            {
                 double div = Math.PI;
                 //arccos(x/(r sin(v pi))) ) / (2 pi)

                 Vector3 n = sb.Faces[i].N[0].X - center;
                 n.Normalize();
                 this.uvs[cnt + 1] = Convert.ToSingle((Math.Acos(n.Z) / div));
                 this.uvs[cnt] = Convert.ToSingle(Math.Acos(n.X / Math.Sin(this.uvs[cnt + 1] * div)) / (2.0 * div));

                 cnt += 2;
                 n = sb.Faces[i].N[1].X - center;
                 n.Normalize();
                 this.uvs[cnt + 1] = Convert.ToSingle((Math.Acos(n.Z) / div));
                 this.uvs[cnt] = Convert.ToSingle(Math.Acos(n.X / Math.Sin(this.uvs[cnt + 1] * div)) / (2.0 * div));

                 cnt += 2;
                 n = sb.Faces[i].N[2].X - center;
                 n.Normalize();
                 this.uvs[cnt + 1] = Convert.ToSingle((Math.Acos(n.Z) / div));
                 this.uvs[cnt] = Convert.ToSingle(Math.Acos(n.X / Math.Sin(this.uvs[cnt + 1] * div)) / (2.0 * div));

                 cnt += 2;

                /*
                 Vector3 n = sb.Faces[i].N[0].X - center;
                 n.Normalize();
                 this.uvs[cnt] = Convert.ToSingle(n.X / div + 0.5);
                 this.uvs[cnt + 1] = Convert.ToSingle(n.Y / div + 0.5);
                 cnt += 2;
                 n = sb.Faces[i].N[1].X - center;
                 n.Normalize();
                 this.uvs[cnt] = Convert.ToSingle(n.X / div + 0.5);
                 this.uvs[cnt + 1] = Convert.ToSingle(n.Y / div + 0.5);
                 cnt += 2;
                 n = sb.Faces[i].N[2].X - center;
                 n.Normalize();
                 this.uvs[cnt] = Convert.ToSingle(n.X / div + 0.5);
                 this.uvs[cnt + 1] = Convert.ToSingle(n.Y / div + 0.5);
                 cnt += 2;*/
            }

            this.SetConfig(sb);

            return sb;
        }
        public void SetUp()
        {
            conf = new SoftBodyRigidBodyCollisionConfiguration();
            dispatcher = new CollisionDispatcher(conf);
            broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000),
                new Vector3(1000, 1000, 1000));
            solver = new DefaultSoftBodySolver();
            world = new SoftRigidDynamicsWorld(dispatcher, broadphase, null, conf, solver);

            softBodyWorldInfo = new SoftBodyWorldInfo();
            softBody = new SoftBody(softBodyWorldInfo);
            world.AddSoftBody(softBody);
        }
		public static SoftBody CreateEllipsoid(SoftBodyWorldInfo worldInfo, Vector3 center, Vector3 radius, int res)
		{
            int numVertices = res + 3;
            Vector3[] vtx = new Vector3[numVertices];
            for (int i = 0; i < numVertices; i++)
            {
                float p = 0.5f, t = 0;
                for (int j = i; j > 0; j >>= 1)
                {
                    if ((j & 1) != 0)
                        t += p;
                    p *= 0.5f;
                }
                float w = 2 * t - 1;
                float a = ((1 + 2 * i) * (float)System.Math.PI) / numVertices;
                float s = (float)System.Math.Sqrt(1 - w * w);
                vtx[i] = new Vector3(s * (float)System.Math.Cos(a), s * (float)System.Math.Sin(a), w) * radius + center;
            }
            return CreateFromConvexHull(worldInfo, vtx);
		}
        protected override SoftBody CreateSoftBody(SoftBodyWorldInfo si)
        {
            SoftBody sb = new SoftBody(si,
            sb.Nodes.
                sb.Cfg.AeroModel = this.AeroModel;
            sb.Cfg.DF = this.DynamicFrictionCoefficient;
            sb.Cfg.DP = this.DampingCoefficient;
            sb.Cfg.PR = this.PressureCoefficient;
            sb.Cfg.LF = this.LiftCoefficient;
            sb.SetTotalMass(this.Mass, true);
            sb.Cfg.Collisions |= FCollisions.VFSS;// | FCollisions.CLRS | FCollisions.
            sb.Cfg.Chr = this.RigidContactHardness;
            sb.Cfg.DG = this.DragCoefficient;
            sb.Cfg.Ahr = this.AnchorHardness;
            if (this.GenerateBendingConstraints)
            {
                sb.GenerateBendingConstraints(this.BendingDistance);
            }

            return sb;
        }
        protected override void _InitializePhysicsWorld()
        {
            Debug.Log("Creating SoftRigidDynamicsWorld");
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new SoftBodyRigidBodyCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            //TODO I think this will limit collision detection to -1000 to 1000 should be configurable
            Broadphase = new AxisSweep3(new BulletSharp.Math.Vector3(-1000, -1000, -1000),
                new BulletSharp.Math.Vector3(1000, 1000, 1000), maxProxies);

            //TODO this is taken from the Bullet examples, but I don't understand why the
            // the default constraint solver.
            Solver = new SequentialImpulseConstraintSolver();

            softBodyWorldInfo = new SoftBodyWorldInfo {
                AirDensity = 1.2f,
                WaterDensity = 0,
                WaterOffset = 0,
                WaterNormal = BulletSharp.Math.Vector3.Zero,
                Gravity = UnityEngine.Physics.gravity.ToBullet(),
                Dispatcher = Dispatcher,
                Broadphase = Broadphase
            };
            softBodyWorldInfo.SparseSdf.Initialize();

            SoftRigidDynamicsWorld sw = new SoftRigidDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World = sw;
            World.Gravity = UnityEngine.Physics.gravity.ToBullet();
            World.DispatchInfo.EnableSpu = true;

            softBodyWorldInfo.SparseSdf.Reset();
            softBodyWorldInfo.AirDensity = 1.2f;
            softBodyWorldInfo.WaterDensity = 0;
            softBodyWorldInfo.WaterOffset = 0;
            softBodyWorldInfo.WaterNormal = BulletSharp.Math.Vector3.Zero;
            softBodyWorldInfo.Gravity = UnityEngine.Physics.gravity.ToBullet();
        }
Example #13
0
        public override void Run()
        {
            var softBodyWorldInfo = new SoftBodyWorldInfo();
            var softBody = new SoftBody(softBodyWorldInfo);
            var softBodyCollisionConf = new SoftBodyRigidBodyCollisionConfiguration();
            var softBodySolver = new DefaultSoftBodySolver();
            var dispatcher = new CollisionDispatcher(softBodyCollisionConf);
            var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000),
                new Vector3(1000, 1000, 1000));
            var softBodyWorld = new SoftRigidDynamicsWorld(dispatcher, broadphase, null, softBodyCollisionConf, softBodySolver);
            softBodyWorld.AddSoftBody(softBody);

            if (!object.ReferenceEquals(softBody.SoftBodySolver, softBodySolver))
            {
                Console.WriteLine("SoftBody: body and world SoftBodySolvers don't match!");
            }

            AddToDisposeQueue(softBodyWorldInfo);
            AddToDisposeQueue(softBody);
            AddToDisposeQueue(softBodyCollisionConf);
            AddToDisposeQueue(softBodySolver);
            AddToDisposeQueue(dispatcher);
            AddToDisposeQueue(broadphase);
            AddToDisposeQueue(softBodyWorld);

            softBodyWorldInfo = null;
            softBody = null;
            softBodyCollisionConf = null;
            softBodySolver = null;
            dispatcher = null;
            broadphase = null;
            softBodyWorld.Dispose();
            softBodyWorld = null;

            ForceGC();
            TestWeakRefs();
            ClearRefs();
        }
Example #14
0
        public Physics()
        {
            demos = new DemoConstructor[] { Init_Cloth, Init_Pressure, Init_Volume, Init_Ropes, Init_RopeAttach,
                Init_ClothAttach, Init_Sticks, Init_Collide, Init_Collide2, Init_Collide3, Init_Impact, Init_Aero,
                Init_Aero2, Init_Friction, Init_Torus, Init_TorusMatch, Init_Bunny, Init_BunnyMatch, Init_Cutting1,
                Init_ClusterDeform, Init_ClusterCollide1, Init_ClusterCollide2, Init_ClusterSocket, Init_ClusterHinge,
                Init_ClusterCombine, Init_ClusterCar, Init_ClusterRobot, Init_ClusterStackSoft, Init_ClusterStackMixed,
                Init_TetraCube, Init_TetraBunny
            };

            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new SoftBodyRigidBodyCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000),
                new Vector3(1000, 1000, 1000), maxProxies);

            // the default constraint solver.
            Solver = new SequentialImpulseConstraintSolver();

            softBodyWorldInfo = new SoftBodyWorldInfo();
            softBodyWorldInfo.AirDensity = 1.2f;
            softBodyWorldInfo.WaterDensity = 0;
            softBodyWorldInfo.WaterOffset = 0;
            softBodyWorldInfo.WaterNormal = Vector3.Zero;
            softBodyWorldInfo.Gravity = new Vector3(0, -10, 0);
            softBodyWorldInfo.Dispatcher = Dispatcher;
            softBodyWorldInfo.Broadphase = Broadphase;
            softBodyWorldInfo.SparseSdf.Initialize();

            World = new SoftRigidDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);
            World.DispatchInfo.EnableSpu = true;

            InitializeDemo();
        }
Example #15
0
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new SoftBodyRigidBodyCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000),
                new Vector3(1000, 1000, 1000), maxProxies);

            // the default constraint solver.
            Solver = new SequentialImpulseConstraintSolver();

            softBodyWorldInfo = new SoftBodyWorldInfo
            {
                AirDensity = 1.2f,
                WaterDensity = 0,
                WaterOffset = 0,
                WaterNormal = Vector3.Zero,
                Gravity = new Vector3(0, -10, 0),
                Dispatcher = Dispatcher,
                Broadphase = Broadphase
            };
            softBodyWorldInfo.SparseSdf.Initialize();

            World = new SoftRigidDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);
            World.DispatchInfo.EnableSpu = true;

            World.SetInternalTickCallback(PickingPreTickCallback, this, true);

            InitializeDemo();
        }
        /*
        Does not set any local variables. Is safe to use to create duplicate physics worlds for independant simulation.
        */
        public bool CreatePhysicsWorld( out CollisionWorld world, 
            out CollisionConfiguration collisionConfig,
            out CollisionDispatcher dispatcher,
            out BroadphaseInterface broadphase,
            out SequentialImpulseConstraintSolver solver,
            out SoftBodyWorldInfo softBodyWorldInfo)
        {
            bool success = true;
            if (m_worldType == WorldType.SoftBodyAndRigidBody && m_collisionType == CollisionConfType.DefaultDynamicsWorldCollisionConf)
            {
                BDebug.LogError(debugType, "For World Type = SoftBodyAndRigidBody collisionType must be collisionType=SoftBodyRigidBodyCollisionConf. Switching");
                m_collisionType = CollisionConfType.SoftBodyRigidBodyCollisionConf;
                success = false;
            }

            collisionConfig = null;
            if (m_collisionType == CollisionConfType.DefaultDynamicsWorldCollisionConf)
            {
                collisionConfig = new DefaultCollisionConfiguration();
            }
            else if (m_collisionType == CollisionConfType.SoftBodyRigidBodyCollisionConf)
            {
                collisionConfig = new SoftBodyRigidBodyCollisionConfiguration();
            }

            dispatcher = new CollisionDispatcher(collisionConfig);

            if (m_broadphaseType == BroadphaseType.DynamicAABBBroadphase)
            {
                broadphase = new DbvtBroadphase();
            }
            else if (m_broadphaseType == BroadphaseType.Axis3SweepBroadphase)
            {
                broadphase = new AxisSweep3(m_axis3SweepBroadphaseMin.ToBullet(), m_axis3SweepBroadphaseMax.ToBullet(), axis3SweepMaxProxies);
            }
            else if (m_broadphaseType == BroadphaseType.Axis3SweepBroadphase_32bit)
            {
                broadphase = new AxisSweep3_32Bit(m_axis3SweepBroadphaseMin.ToBullet(), m_axis3SweepBroadphaseMax.ToBullet(), axis3SweepMaxProxies);
            }
            else
            {
                broadphase = null;
            }
            world = null;
            softBodyWorldInfo = null;
            solver = null;
            if (m_worldType == WorldType.CollisionOnly)
            {
                world = new CollisionWorld(dispatcher, broadphase, collisionConfig);
            }
            else if (m_worldType == WorldType.RigidBodyDynamics)
            {
                world = new DiscreteDynamicsWorld(dispatcher, broadphase, null, collisionConfig);
            }
            else if (m_worldType == WorldType.MultiBodyWorld)
            {
                world = new MultiBodyDynamicsWorld(dispatcher, broadphase, null, collisionConfig);
            }
            else if (m_worldType == WorldType.SoftBodyAndRigidBody)
            {
                solver = new SequentialImpulseConstraintSolver();
                solver.RandSeed = sequentialImpulseConstraintSolverRandomSeed;
                softBodyWorldInfo = new SoftBodyWorldInfo
                {
                    AirDensity = 1.2f,
                    WaterDensity = 0,
                    WaterOffset = 0,
                    WaterNormal = BulletSharp.Math.Vector3.Zero,
                    Gravity = UnityEngine.Physics.gravity.ToBullet(),
                    Dispatcher = dispatcher,
                    Broadphase = broadphase
                };
                softBodyWorldInfo.SparseSdf.Initialize();

                world = new SoftRigidDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);

                world.DispatchInfo.EnableSpu = true;
                softBodyWorldInfo.SparseSdf.Reset();
                softBodyWorldInfo.AirDensity = 1.2f;
                softBodyWorldInfo.WaterDensity = 0;
                softBodyWorldInfo.WaterOffset = 0;
                softBodyWorldInfo.WaterNormal = BulletSharp.Math.Vector3.Zero;
                softBodyWorldInfo.Gravity = m_gravity.ToBullet();
            }
            if (world is DiscreteDynamicsWorld)
            {
                ((DiscreteDynamicsWorld)world).Gravity = m_gravity.ToBullet();
            }
            if (_doDebugDraw)
            {
                DebugDrawUnity db = new DebugDrawUnity();
                db.DebugMode = _debugDrawMode;
                world.DebugDrawer = db;
            }
            return success;
        }
        protected void Dispose(bool disposing)
        {
            if (debugType >= BDebug.DebugType.Debug) Debug.Log("BDynamicsWorld Disposing physics.");

            if (lateUpdateHelper != null)
            {
                lateUpdateHelper.m_ddWorld = null;
                lateUpdateHelper.m_world = null;
            }
            if (m_world != null)
            {
                //remove/dispose constraints
                int i;
                if (_ddWorld != null)
                {
                    if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removing Constraints {0}", _ddWorld.NumConstraints);
                    for (i = _ddWorld.NumConstraints - 1; i >= 0; i--)
                    {
                        TypedConstraint constraint = _ddWorld.GetConstraint(i);
                        _ddWorld.RemoveConstraint(constraint);
                        if (constraint.Userobject is BTypedConstraint) ((BTypedConstraint)constraint.Userobject).m_isInWorld = false;
                        if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removed Constaint {0}", constraint.Userobject);
                        constraint.Dispose();
                    }
                }

                if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removing Collision Objects {0}", _ddWorld.NumCollisionObjects);
                //remove the rigidbodies from the dynamics world and delete them
                for (i = m_world.NumCollisionObjects - 1; i >= 0; i--)
                {
                    CollisionObject obj = m_world.CollisionObjectArray[i];
                    RigidBody body = obj as RigidBody;
                    if (body != null && body.MotionState != null)
                    {
                        Debug.Assert(body.NumConstraintRefs == 0, "Rigid body still had constraints");
                        body.MotionState.Dispose();
                    }
                    m_world.RemoveCollisionObject(obj);
                    if (obj.UserObject is BCollisionObject) ((BCollisionObject)obj.UserObject).isInWorld = false;
                    if (debugType >= BDebug.DebugType.Debug) Debug.LogFormat("Removed CollisionObject {0}", obj.UserObject);
                    obj.Dispose();
                }

                if (m_world.DebugDrawer != null)
                {
                    if (m_world.DebugDrawer is IDisposable)
                    {
                        IDisposable dis = (IDisposable)m_world.DebugDrawer;
                        dis.Dispose();
                    }
                }

                m_world.Dispose();
                Broadphase.Dispose();
                Dispatcher.Dispose();
                CollisionConf.Dispose();
                _ddWorld = null;
                m_world = null;
            }

            if (Broadphase != null)
            {
                Broadphase.Dispose();
                Broadphase = null;
            }
            if (Dispatcher != null)
            {
                Dispatcher.Dispose();
                Dispatcher = null;
            }
            if (CollisionConf != null)
            {
                CollisionConf.Dispose();
                CollisionConf = null;
            }
            if (Solver != null)
            {
                Solver.Dispose();
                Solver = null;
            }
            if (softBodyWorldInfo != null)
            {
                softBodyWorldInfo.Dispose();
                softBodyWorldInfo = null;
            }
            _isDisposed = true;
            singleton = null;
        }
        public static SoftBody CreateFromTetGenData(SoftBodyWorldInfo worldInfo, string ele, string face, string node, bool faceLinks, bool tetraLinks, bool facesFromTetras)
		{
            CultureInfo culture = CultureInfo.InvariantCulture;
            char[] separator = new[] { ' ' };
            Vector3[] pos;

            using (StringReader nodeReader = new StringReader(node))
            {
                string[] nodeHeader = nodeReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries);
                int numNodes = int.Parse(nodeHeader[0]);
                //int numDims = int.Parse(nodeHeader[1]);
                //int numAttrs = int.Parse(nodeHeader[2]);
                //bool hasBounds = !nodeHeader[3].Equals("0");

                pos = new Vector3[numNodes];
                for (int n = 0; n < numNodes; n++)
                {
                    string[] nodeLine = nodeReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries);
                    pos[int.Parse(nodeLine[0])] = new Vector3(
                        float.Parse(nodeLine[1], culture),
                        float.Parse(nodeLine[2], culture),
                        float.Parse(nodeLine[3], culture));
                }
            }
            SoftBody psb = new SoftBody(worldInfo, pos.Length, pos, null);
            /*
            if (!string.IsNullOrEmpty(face))
            {
                throw new NotImplementedException();
            }
            */
            if (!string.IsNullOrEmpty(ele))
            {
                using (StringReader eleReader = new StringReader(ele))
                {
                    string[] eleHeader = eleReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries);
                    int numTetras = int.Parse(eleHeader[0]);
                    //int numCorners = int.Parse(eleHeader[1]);
                    //int numAttrs = int.Parse(eleHeader[2]);

                    for (int n = 0; n < numTetras; n++)
                    {
                        string[] eleLine = eleReader.ReadLine().Split(separator, StringSplitOptions.RemoveEmptyEntries);
                        //int index = int.Parse(eleLine[0], culture);
                        int ni0 = int.Parse(eleLine[1], culture);
                        int ni1 = int.Parse(eleLine[2], culture);
                        int ni2 = int.Parse(eleLine[3], culture);
                        int ni3 = int.Parse(eleLine[4], culture);
                        psb.AppendTetra(ni0, ni1, ni2, ni3);
                        if (tetraLinks)
                        {
                            psb.AppendLink(ni0, ni1, null, true);
                            psb.AppendLink(ni1, ni2, null, true);
                            psb.AppendLink(ni2, ni0, null, true);
                            psb.AppendLink(ni0, ni3, null, true);
                            psb.AppendLink(ni1, ni3, null, true);
                            psb.AppendLink(ni2, ni3, null, true);
                        }
                    }
                }
            }

            //Console.WriteLine("Nodes: {0}", psb.Nodes.Count);
            //Console.WriteLine("Links: {0}", psb.Links.Count);
            //Console.WriteLine("Faces: {0}", psb.Faces.Count);
            //Console.WriteLine("Tetras: {0}", psb.Tetras.Count);

            return psb;
		}
 public SoftBody GetSoftBody(SoftBodyWorldInfo si)
 {
     SoftBody body = this.CreateSoftBody(si);
     return body;
 }
		public static SoftBody CreateRope(SoftBodyWorldInfo worldInfo, Vector3 from, Vector3 to, int res, int fixeds)
		{
            // Create nodes
            int r = res + 2;
            Vector3[] x = new Vector3[r];
            float[] m = new float[r];

            for (int i = 0; i < r; i++)
            {
                Vector3.Lerp(ref from, ref to, i / (float)(r - 1), out x[i]);
                m[i] = 1;
            }

            SoftBody psb = new SoftBody(worldInfo, r, x, m);
            if ((fixeds & 1) != 0)
                psb.SetMass(0, 0);
            if ((fixeds & 2) != 0)
                psb.SetMass(r - 1, 0);

            // Create links
            for (int i = 1; i < r; i++)
            {
                psb.AppendLink(i - 1, i);
            }

            return psb;
		}
        public static SoftBody CreatePatchUV(SoftBodyWorldInfo worldInfo, Vector3 corner00, Vector3 corner10, Vector3 corner01, Vector3 corner11, int resx, int resy, int fixeds, bool gendiags, float[] texCoords)
		{
			SoftBody body = new SoftBody(btSoftBodyHelpers_CreatePatchUV2(worldInfo._native, ref corner00, ref corner10, ref corner01, ref corner11, resx, resy, fixeds, gendiags, texCoords));
            body.WorldInfo = worldInfo;
            return body;
		}
		public static SoftBody CreatePatch(SoftBodyWorldInfo worldInfo, Vector3 corner00, Vector3 corner10, Vector3 corner01, Vector3 corner11, int resx, int resy, int fixeds, bool gendiags)
		{
            // Create nodes
            if ((resx < 2) || (resy < 2))
                return null;

            int rx = resx;
            int ry = resy;
            int tot = rx * ry;
            Vector3[] x = new Vector3[tot];
            float[] m = new float[tot];

            for (int iy = 0; iy < ry; iy++)
            {
                float ty = iy / (float)(ry - 1);
                Vector3 py0, py1;
                Vector3.Lerp(ref corner00, ref corner01, ty, out py0);
                Vector3.Lerp(ref corner10, ref corner11, ty, out py1);
                for (int ix = 0; ix < rx; ix++)
                {
                    float tx = ix / (float)(rx - 1);
                    int index = rx * iy + ix;
                    Vector3.Lerp(ref py0, ref py1, tx, out x[index]);
                    m[index] = 1;
                }
            }

            SoftBody psb = new SoftBody(worldInfo, tot, x, m);

            if ((fixeds & 1) != 0)
                psb.SetMass(0, 0);
            if ((fixeds & 2) != 0)
                psb.SetMass(rx - 1, 0);
            if ((fixeds & 4) != 0)
                psb.SetMass(rx * (ry - 1), 0);
            if ((fixeds & 8) != 0)
                psb.SetMass(rx * (ry - 1) + rx - 1, 0);

            // Create links and faces
            for (int iy = 0; iy < ry; ++iy)
            {
                for (int ix = 0; ix < rx; ++ix)
                {
                    int ixy = rx * iy + ix;
                    int ix1y = ixy + 1;
                    int ixy1 = rx * (iy + 1) + ix;

                    bool mdx = (ix + 1) < rx;
                    bool mdy = (iy + 1) < ry;
                    if (mdx)
                        psb.AppendLink(ixy, ix1y);
                    if (mdy)
                        psb.AppendLink(ixy, ixy1);
                    if (mdx && mdy)
                    {
                        int ix1y1 = ixy1 + 1;
                        if (((ix + iy) & 1) != 0)
                        {
                            psb.AppendFace(ixy, ix1y, ix1y1);
                            psb.AppendFace(ixy, ix1y1, ixy1);
                            if (gendiags)
                            {
                                psb.AppendLink(ixy, ix1y1);
                            }
                        }
                        else
                        {
                            psb.AppendFace(ixy1, ixy, ix1y);
                            psb.AppendFace(ixy1, ix1y, ix1y1);
                            if (gendiags)
                            {
                                psb.AppendLink(ix1y, ixy1);
                            }
                        }
                    }
                }
            }

            return psb;
		}
 protected abstract SoftBody CreateSoftBody(SoftBodyWorldInfo si);
		public SoftBody(SoftBodyWorldInfo worldInfo)
			: base(btSoftBody_new2(worldInfo._native))
		{
            _collisionShape = new SoftBodyCollisionShape(btCollisionObject_getCollisionShape(_native));
			_worldInfo = worldInfo;
		}
        static void TestSoftBody()
        {
            var softBodyWorldInfo = new SoftBodyWorldInfo();
            var softBody = new SoftBody(softBodyWorldInfo);
            var softBodyCollisionConf = new SoftBodyRigidBodyCollisionConfiguration();
            var softBodySolver = new DefaultSoftBodySolver();
            var dispatcher = new CollisionDispatcher(softBodyCollisionConf);
            var broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000),
                new Vector3(1000, 1000, 1000));
            var softBodyWorld = new SoftRigidDynamicsWorld(dispatcher, broadphase, null, softBodyCollisionConf, softBodySolver);
            softBodyWorld.AddSoftBody(softBody);

            if (!object.ReferenceEquals(softBody.SoftBodySolver, softBodySolver))
            {
                Console.WriteLine("SoftBody: body and world SoftBodySolvers don't match!");
            }
            
            AddToDisposeQueue(softBodyWorldInfo);
            AddToDisposeQueue(softBody);
            AddToDisposeQueue(softBodyCollisionConf);
            AddToDisposeQueue(softBodySolver);
            AddToDisposeQueue(dispatcher);
            AddToDisposeQueue(broadphase);
            AddToDisposeQueue(softBodyWorld);

            softBodyWorldInfo = null;
            softBody = null;
            softBodyCollisionConf = null;
            softBodySolver = null;
            dispatcher = null;
            broadphase = null;
            softBodyWorld.Dispose();
            softBodyWorld = null;

            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            GC.WaitForPendingFinalizers();

            TestWeakRefs();
            disposeQueue.Clear();
        }
        public static SoftBody CreateFromTetGenFile(SoftBodyWorldInfo worldInfo, string elementFilename, string faceFilename, string nodeFilename, bool faceLinks, bool tetraLinks, bool facesFromTetras)
        {
            string ele = (elementFilename != null) ? File.ReadAllText(elementFilename) : null;
            string face = (faceFilename != null) ? File.ReadAllText(faceFilename) : null;

            return CreateFromTetGenData(worldInfo, ele, face, File.ReadAllText(nodeFilename), faceLinks, tetraLinks, facesFromTetras);
        }
		public SoftBody(SoftBodyWorldInfo worldInfo, int nodeCount, Vector3[] x, float[] m)
			: base(btSoftBody_new(worldInfo._native, nodeCount, x, m))
		{
            _collisionShape = new SoftBodyCollisionShape(btCollisionObject_getCollisionShape(_native));
			_worldInfo = worldInfo;
		}
		public static SoftBody CreateFromTriMesh(SoftBodyWorldInfo worldInfo, float[] vertices, int[] triangles, bool randomizeConstraints = true)
		{
            int numVertices = vertices.Length / 3;
            Vector3[] vtx = new Vector3[numVertices];
            for (int i = 0, j = 0; j < numVertices; j++, i += 3)
            {
                vtx[j] = new Vector3(vertices[i], vertices[i + 1], vertices[i + 2]);
            }
            return CreateFromTriMesh(worldInfo, vtx, triangles, randomizeConstraints);
        }
Example #29
0
        public void Create()
        {
            if (created)
            {
                this.Destroy();
            }

            this.bodyindex = 0;
            this.cstindex = 0;

            collisionConfiguration = new SoftBodyRigidBodyCollisionConfiguration();
            dispatcher = new CollisionDispatcher(collisionConfiguration);
            solver = new SequentialImpulseConstraintSolver();
            overlappingPairCache = new DbvtBroadphase();
            dynamicsWorld = new SoftRigidDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
            worldInfo = new SoftBodyWorldInfo();
            worldInfo.Gravity = dynamicsWorld.Gravity;
            worldInfo.Broadphase = overlappingPairCache;
            worldInfo.Dispatcher = dispatcher;
            worldInfo.SparseSdf.Initialize();
            this.created = true;

            if (this.WorldHasReset != null)
            {
                this.WorldHasReset();
            }
        }
        public static SoftBody CreateFromTriMesh(SoftBodyWorldInfo worldInfo, Vector3[] vertices, int[] triangles, bool randomizeConstraints = true)
        {
            int numTriangleIndices = triangles.Length;
            int numTriangles = numTriangleIndices / 3;

            int maxIndex = 0; // triangles.Max() + 1;
            for (int i = 0; i < numTriangleIndices; i++)
            {
                if (triangles[i] > maxIndex)
                {
                    maxIndex = triangles[i];
                }
            }
            maxIndex++;

            SoftBody psb = new SoftBody(worldInfo, maxIndex, vertices, null);

            BitArray chks = new BitArray(maxIndex * maxIndex);
            for (int i = 0; i < numTriangleIndices; i += 3)
            {
                int[] idx = new int[] { triangles[i], triangles[i + 1], triangles[i + 2] };
                for (int j = 2, k = 0; k < 3; j = k++)
                {
                    int chkIndex = maxIndex * idx[k] + idx[j];
                    if (!chks[chkIndex])
                    {
                        chks[chkIndex] = true;
                        chks[maxIndex * idx[j] + idx[k]] = true;
                        psb.AppendLink(idx[j], idx[k]);
                    }
                }
                psb.AppendFace(idx[0], idx[1], idx[2]);
            }

            if (randomizeConstraints)
            {
                psb.RandomizeConstraints();
            }
            return psb;
        }