public unsafe static void GetGraphicsWorldTrans(this DefaultMotionState obj, out OpenTK.Matrix4 value)
 {
     fixed(OpenTK.Matrix4 *valuePtr = &value)
     {
         *(BulletSharp.Math.Matrix *)valuePtr = obj.GraphicsWorldTrans;
     }
 }
Beispiel #2
0
        public Physics()
        {
            // collision configuration contains default setup for memory, collision setup
            collisionConf = new DefaultCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(collisionConf);

            Broadphase = new DbvtBroadphase();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, null, collisionConf);
            World.Gravity = new Vector3(0, -10, 0);

            CollisionShapes = new List<CollisionShape>();

            // create the ground
            CollisionShape groundShape = new BoxShape(50, 1, 50);
            CollisionShapes.Add(groundShape);
            CollisionObject ground = LocalCreateRigidBody(0, Matrix.Identity, groundShape);
            ground.UserObject = "Ground";

            // create a few dynamic rigidbodies
            float mass = 1.0f;

            CollisionShape colShape = new BoxShape(1);
            CollisionShapes.Add(colShape);
            Vector3 localInertia = colShape.CalculateLocalInertia(mass);

            float start_x = StartPosX - ArraySizeX / 2;
            float start_y = StartPosY;
            float start_z = StartPosZ - ArraySizeZ / 2;

            int k, i, j;
            for (k = 0; k < ArraySizeY; k++)
            {
                for (i = 0; i < ArraySizeX; i++)
                {
                    for (j = 0; j < ArraySizeZ; j++)
                    {
                        Matrix startTransform = Matrix.CreateTranslation(
                            new Vector3(
                                2*i + start_x,
                                2*k + start_y,
                                2*j + start_z
                                )
                            );

                        // using motionstate is recommended, it provides interpolation capabilities
                        // and only synchronizes 'active' objects
                        DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
                        RigidBodyConstructionInfo rbInfo =
                            new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
                        RigidBody body = new RigidBody(rbInfo);

                        // make it drop from a height
                        body.Translate(new Vector3(0, 20, 0));

                        World.AddRigidBody(body);
                    }
                }
            }
        }
 public unsafe static void SetStartWorldTrans(this DefaultMotionState obj, ref OpenTK.Matrix4 value)
 {
     fixed(OpenTK.Matrix4 *valuePtr = &value)
     {
         obj.StartWorldTrans = *(BulletSharp.Math.Matrix *)valuePtr;
     }
 }
Beispiel #4
0
        private void AddVertexGraph(VertexGraph graph)
        {
            Individual = graph.Vertices.Select(vertex =>
            {
                var mass = 10000;
                var motionState = new DefaultMotionState();
                var collisionShape = new BoxShape(1);

                var info = new RigidBodyConstructionInfo(mass, motionState, collisionShape);
                var rigidBody = new VertexBoundRigidBody(vertex, info);

                return rigidBody;
            }).ToList();

            foreach (var body in Individual)
            {
                // Select the 3 nearest vertices, excluding this one
                var nearest = Individual.OrderBy(a => a.Binding.DistanceTo(body.Binding))
                                         .Where(a => a != body)
                                         .Take(3);
                foreach (var other in nearest)
                {
                    // TODO: What are these matrices supposed to be?
                    var frameInA = body.MotionState.WorldTransform;
                    var frameInB = other.MotionState.WorldTransform;

                    // TODO: How do you specify the spring's springiness?
                    var constraint = new Generic6DofSpringConstraint(body, other, frameInA, frameInB, true);

                    // TODO: Now how do I apply this to the bodies?
                    body.AddConstraintRef(constraint);
                    other.AddConstraintRef(constraint);
                }
            }
        }
 public unsafe static void GetCenterOfMassOffset(this DefaultMotionState obj, out OpenTK.Matrix4 value)
 {
     fixed(OpenTK.Matrix4 *valuePtr = &value)
     {
         *(BulletSharp.Math.Matrix *)valuePtr = obj.CenterOfMassOffset;
     }
 }
Beispiel #6
0
        public Prop(CollisionShape shape, float mass, Matrix4 start)
        {
            Physics physics = Game.Instance.Physics;

            Shape = shape;
            IsDynamic = (mass != 0.0f);
            physics.Props.Add(this);
            Vector3 inertia = Vector3.Zero;
            if (IsDynamic) shape.CalculateLocalInertia(mass, out inertia);
            DefaultMotionState motionState = new DefaultMotionState(start);
            RigidBody.RigidBodyConstructionInfo info = new RigidBody.RigidBodyConstructionInfo(mass, motionState, shape, inertia);
            Body = new RigidBody(info);
            physics.World.AddRigidBody(Body);
        }
        protected RigidBody LocalCreateRigidBody(float mass, Matrix startTransform, CollisionShape shape)
        {
            bool isDynamic = (mass != 0.0f);

            Vector3 localInertia = Vector3.Zero;
            if (isDynamic)
                shape.CalculateLocalInertia(mass, out localInertia);

            DefaultMotionState myMotionState = new DefaultMotionState(startTransform);

            RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
            body = new RigidBody(rbInfo);
            
            return body;
        }
	BulletSharp.RigidBody createRigidBody (BulletSharp.CollisionShape shape, UnityEngine.Transform transform, float mass)
	{
		Matrix4x4 unityMatrix = Matrix4x4.TRS (transform.position, transform.rotation, UnityEngine.Vector3.one);
		BulletSharp.Matrix bulletMatrix = new BulletSharp.Matrix (
			unityMatrix.m00, unityMatrix.m10, unityMatrix.m20, unityMatrix.m30, 
			unityMatrix.m01, unityMatrix.m11, unityMatrix.m21, unityMatrix.m31, 
			unityMatrix.m02, unityMatrix.m12, unityMatrix.m22, unityMatrix.m32, 
			unityMatrix.m03, unityMatrix.m13, unityMatrix.m23, unityMatrix.m33);
		
		BulletSharp.MotionState motionState = new BulletSharp.DefaultMotionState (bulletMatrix);
		BulletSharp.Vector3 inertia = new BulletSharp.Vector3 (0f, 0f, 0f);
		if (!Mathf.Approximately (mass, 0f)) {
			shape.CalculateLocalInertia (mass, out inertia);
		}
		BulletSharp.RigidBodyConstructionInfo myRigidBodyCI = new BulletSharp.RigidBodyConstructionInfo (mass, motionState, shape, inertia);
		BulletSharp.RigidBody myRigidBody = new BulletSharp.RigidBody (myRigidBodyCI);
		myRigidBodyCI.Dispose ();
		return myRigidBody;
	}
Beispiel #9
0
	        public RigidBody LocalCreateRigidBody(float mass, Matrix startTransform, CollisionShape shape)
            {
                //rigidbody is dynamic if and only if mass is non zero, otherwise static
                bool isDynamic = (mass != 0.0f);

                Vector3 localInertia = Vector3.Zero;
                if (isDynamic)
                    shape.CalculateLocalInertia(mass, out localInertia);

                //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
                DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
                RigidBody body;
                using (var rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia))
                {
                    body = new RigidBody(rbInfo);
                }

                ownerWorld.AddRigidBody(body);

                return body;
            }
Beispiel #10
0
        public static void TR_GenRoom(int roomIndex, Room room, World world, Level tr)
        {
            var trRoom = tr.Rooms[roomIndex];

#region Room properties

            room.ID = (uint) roomIndex;
            room.Active = true;
            room.Frustum = new List<Frustum>();
            room.Flags = trRoom.Flags;
            room.LightMode = trRoom.LightMode;
            room.ReverbInfo = (byte) trRoom.ReverbInfo;
            room.WaterScheme = trRoom.WaterScheme;
            room.AlternateGroup = (byte) trRoom.AlternateGroup;

            room.Transform = new Transform();
            room.Transform.SetIdentity();
            room.Transform.Origin = trRoom.Offset.ToVector3();
            room.AmbientLighting = new float[3];
            room.AmbientLighting[0] = trRoom.LightColor.R * 2;
            room.AmbientLighting[1] = trRoom.LightColor.G * 2;
            room.AmbientLighting[2] = trRoom.LightColor.B * 2;
            room.Self = new EngineContainer();
            room.Self.Room = room;
            room.Self.Object = room;
            room.Self.ObjectType = OBJECT_TYPE.RoomBase;
            room.NearRoomList = new List<Room>();
            room.OverlappedRoomList = new List<Room>();

            room.GenMesh(world, (uint) roomIndex, tr);

            room.BtBody = null;
            // let's load static room meshes
            room.StaticMesh = new List<StaticMesh>();

#endregion

#region Static meshes

            Loader.StaticMesh trStatic;

            for (var i = 0; i < trRoom.StaticMeshes.Length; i++)
            {
                var trsm = trRoom.StaticMeshes[i];
                trStatic = tr.FindStaticMeshById(trsm.ObjectID);
                if (trStatic.Equals(default(Loader.StaticMesh)))
                {
                    continue;
                }
                var rStatic = new StaticMesh();
                rStatic.Self = new EngineContainer();
                rStatic.Self.Room = room;
                rStatic.Self.Object = rStatic;
                rStatic.Self.ObjectType = OBJECT_TYPE.StaticMesh;
                rStatic.ObjectID = trsm.ObjectID;
                rStatic.Mesh = world.Meshes[(int) tr.MeshIndices[trStatic.Mesh]];
                rStatic.Position = trsm.Position.ToVector3();
                rStatic.Rotation = new Vector3(trsm.Rotation, 0.0f, 0.0f);
                rStatic.Tint[0] = trsm.Tint.R * 2;
                rStatic.Tint[1] = trsm.Tint.G * 2;
                rStatic.Tint[2] = trsm.Tint.B * 2;
                rStatic.Tint[3] = trsm.Tint.A * 2;

                rStatic.CBBMin.X = trStatic.CollisionBox[0].X;
                rStatic.CBBMin.Y = -trStatic.CollisionBox[0].Z;
                rStatic.CBBMin.Z = trStatic.CollisionBox[1].Y;
                rStatic.CBBMax.X = trStatic.CollisionBox[1].X;
                rStatic.CBBMax.Y = -trStatic.CollisionBox[1].Z;
                rStatic.CBBMax.Z = trStatic.CollisionBox[0].Y;

                rStatic.VBBMin.X = trStatic.VisibilityBox[0].X;
                rStatic.VBBMin.Y = -trStatic.VisibilityBox[0].Z;
                rStatic.VBBMin.Z = trStatic.VisibilityBox[1].Y;

                rStatic.VBBMax.X = trStatic.VisibilityBox[1].X;
                rStatic.VBBMax.Y = -trStatic.VisibilityBox[1].Z;
                rStatic.VBBMax.Z = trStatic.VisibilityBox[0].Y;

                rStatic.OBB.Transform = rStatic.Transform;
                rStatic.OBB.Radius = rStatic.Mesh.Radius;
                rStatic.Transform.SetIdentity();
                VMath.Mat4_Translate(rStatic.Transform, rStatic.Position);
                VMath.Mat4_RotateZ(rStatic.Transform, rStatic.Rotation.X);
                rStatic.WasRendered = 0;
                rStatic.OBB.Rebuild(rStatic.VBBMin, rStatic.VBBMax);
                rStatic.OBB.DoTransform();

                rStatic.BtBody = null;
                rStatic.Hide = false;

                // Disable static mesh collision, if flag value is 3 (TR1) or all bounding box
                // coordinates are equal (TR2-5).

                if (trStatic.Flags == 3 ||
                    trStatic.CollisionBox[0].X == -trStatic.CollisionBox[0].Y &&
                    trStatic.CollisionBox[0].Y == trStatic.CollisionBox[0].Z &&
                    trStatic.CollisionBox[1].X == -trStatic.CollisionBox[1].Y &&
                    trStatic.CollisionBox[1].Y == trStatic.CollisionBox[1].Z)
                {
                    rStatic.Self.CollisionType = COLLISION_TYPE.None;
                }
                else
                {
                    rStatic.Self.CollisionType = COLLISION_TYPE.Static;
                    rStatic.Self.CollisionShape = COLLISION_SHAPE.Box;
                }

                // Set additional static mesh properties from level script override.

                Res_SetStaticMeshProperties(rStatic);

                // Set static mesh collision.

                if (rStatic.Self.CollisionType != COLLISION_TYPE.None)
                {
                    CollisionShape cshape;
                    switch (rStatic.Self.CollisionShape)
                    {
                        case COLLISION_SHAPE.Box:
                            cshape = BT_CSfromBBox(rStatic.CBBMin, rStatic.CBBMax, true, true);
                            break;

                        case COLLISION_SHAPE.BoxBase:
                            cshape = BT_CSfromBBox(rStatic.Mesh.BBMin, rStatic.Mesh.BBMax, true, true);
                            break;

                        case COLLISION_SHAPE.Trimesh:
                            cshape = BT_CSfromMesh(rStatic.Mesh, true, true, true);
                            break;

                        case COLLISION_SHAPE.TrimeshConvex:
                            cshape = BT_CSfromMesh(rStatic.Mesh, true, true, true);
                            break;

                        default:
                            cshape = null;
                            break;
                    }

                    if (cshape != null)
                    {
                        var startTransform = rStatic.Transform;
                        var motionState = new DefaultMotionState(((Matrix4) startTransform).ToBullet());
                        var localInertia = Vector3.Zero;
                        rStatic.BtBody =
                            new RigidBody(new RigidBodyConstructionInfo(0.0f, motionState, cshape, localInertia.ToBullet()));
                        BtEngineDynamicsWorld.AddRigidBody(rStatic.BtBody, CollisionFilterGroups.AllFilter,
                            CollisionFilterGroups.AllFilter);
                        rStatic.BtBody.UserObject = rStatic.Self;
                    }
                }

                room.StaticMesh.Add(rStatic);
            }

#endregion

#region Sprites

            foreach (var trs in trRoom.Sprites)
            {
                var rs = new RoomSprite();
                if (trs.Texture.IsBetween(0, world.Sprites.Count, IB.aIbE))
                {
                    rs.Sprite = world.Sprites[trs.Texture];
                    rs.Position = trRoom.Vertices[trs.Vertex].Vertex.ToVector3() + room.Transform.Origin;
                }
                room.Sprites.Add(rs);
            }

#endregion

#region Sectors

            room.SectorsX = trRoom.Num_X_Sectors;
            room.SectorsY = trRoom.Num_Z_Sectors;
            room.Sectors = new List<RoomSector>();
            room.Sectors.Resize(room.SectorsX * room.SectorsY, () => new RoomSector());

            // base sectors information loading and collisional mesh creation

            // To avoid manipulating with unnecessary information, we declare simple
            // heightmap here, which will be operated with sector and floordata parsing,
            // then vertical inbetween polys will be constructed, and Bullet collisional
            // object will be created. Afterwards, this heightmap also can be used to
            // quickly detect slopes for pushable blocks and other entities that rely on
            // floor level.

            for (var i = 0; i < room.Sectors.Count; i++)
            {
                var sector = room.Sectors[i];

                // Filling base sectors information.

                sector.IndexX = (short) (i / room.SectorsY);
                sector.IndexY = (short) (i % room.SectorsY);

                sector.Position.X = room.Transform.Origin.X + (sector.IndexX + 0.5f) * TR_METERING_SECTORSIZE;
                sector.Position.Y = room.Transform.Origin.Y + (sector.IndexY + 0.5f) * TR_METERING_SECTORSIZE;
                sector.Position.Z = 0.5f * (trRoom.Y_Bottom + trRoom.Y_Top);

                sector.OwnerRoom = room;

                if (tr.GameVersion < TRGame.TR3)
                {
                    sector.BoxIndex = trRoom.Sectors[i].Box_Index;
                    sector.Material = SectorMaterial.Stone;
                }
                else
                {
                    sector.BoxIndex = (trRoom.Sectors[i].Box_Index & 0xFFF0) >> 4;
                    sector.Material = (SectorMaterial)((uint) trRoom.Sectors[i].Box_Index & 0x000F);
                }

                if (sector.BoxIndex == 0xFFFF) sector.BoxIndex = -1;

                sector.Flags = 0; // Clear sector flags

                sector.Floor = (int) -TR_METERING_STEP * trRoom.Sectors[i].Floor;
                sector.Ceiling = (int) -TR_METERING_STEP * trRoom.Sectors[i].Ceiling;
                sector.TrigIndex = trRoom.Sectors[i].FD_Index;

                // BUILDING CEILING HEIGHTMAP.

                // Penetration config is used later to build inbetween vertical collision polys.
                // If sector's penetration config is a wall, we simply build a vertical plane to
                // isolate this sector from top to bottom. Also, this allows to trick out wall
                // sectors inside another wall sectors to be ignored completely when building
                // collisional mesh.
                // Door penetration config means that we should either ignore sector collision
                // completely (classic door) or ignore one of the triangular sector parts (TR3+).

                if (sector.Ceiling == TR_METERING_WALLHEIGHT)
                {
                    sector.CeilingPenetrationConfig = TR_PENETRATION_CONFIG.Wall;
                }
                else if (trRoom.Sectors[i].RoomAbove != 0xFF)
                {
                    sector.CeilingPenetrationConfig = TR_PENETRATION_CONFIG.Ghost;
                }
                else
                {
                    sector.CeilingPenetrationConfig = TR_PENETRATION_CONFIG.Solid;
                }

                // Reset some sector parameters to avoid garbaged memory issues.

                sector.PortalToRoom = -1;
                sector.CeilingDiagonalType = TR_SECTOR_DIAGONAL_TYPE.None;
                sector.FloorDiagonalType = TR_SECTOR_DIAGONAL_TYPE.None;

                // Now, we define heightmap cells position and draft (flat) height.
                // Draft height is derived from sector's floor and ceiling values, which are
                // copied into heightmap cells Y coordinates. As result, we receive flat
                // heightmap cell, which will be operated later with floordata.

                sector.CeilingCorners[0][0] = sector.IndexX * TR_METERING_SECTORSIZE;
                sector.CeilingCorners[0][1] = sector.IndexY * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.CeilingCorners[0][2] = sector.Ceiling;

                sector.CeilingCorners[1][0] = sector.IndexX * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.CeilingCorners[1][1] = sector.IndexY * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.CeilingCorners[1][2] = sector.Ceiling;

                sector.CeilingCorners[2][0] = sector.IndexX * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.CeilingCorners[2][1] = sector.IndexY * TR_METERING_SECTORSIZE;
                sector.CeilingCorners[2][2] = sector.Ceiling;

                sector.CeilingCorners[3][0] = sector.IndexX * TR_METERING_SECTORSIZE;
                sector.CeilingCorners[3][1] = sector.IndexY * TR_METERING_SECTORSIZE;
                sector.CeilingCorners[3][2] = sector.Ceiling;


                // BUILDING FLOOR HEIGHTMAP.

                // Features same steps as for the ceiling.

                if (sector.Floor == TR_METERING_WALLHEIGHT)
                {
                    sector.FloorPenetrationConfig = TR_PENETRATION_CONFIG.Wall;
                }
                else if (trRoom.Sectors[i].RoomBelow != 0xFF)
                {
                    sector.FloorPenetrationConfig = TR_PENETRATION_CONFIG.Ghost;
                }
                else
                {
                    sector.FloorPenetrationConfig = TR_PENETRATION_CONFIG.Solid;
                }

                sector.FloorCorners[0][0] = sector.IndexX * TR_METERING_SECTORSIZE;
                sector.FloorCorners[0][1] = sector.IndexY * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.FloorCorners[0][2] = sector.Floor;

                sector.FloorCorners[1][0] = sector.IndexX * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.FloorCorners[1][1] = sector.IndexY * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.FloorCorners[1][2] = sector.Floor;

                sector.FloorCorners[2][0] = sector.IndexX * TR_METERING_SECTORSIZE + TR_METERING_SECTORSIZE;
                sector.FloorCorners[2][1] = sector.IndexY * TR_METERING_SECTORSIZE;
                sector.FloorCorners[2][2] = sector.Floor;

                sector.FloorCorners[3][0] = sector.IndexX * TR_METERING_SECTORSIZE;
                sector.FloorCorners[3][1] = sector.IndexY * TR_METERING_SECTORSIZE;
                sector.FloorCorners[3][2] = sector.Floor;
            }

#endregion

#region Lights

            room.Lights.Resize(trRoom.Lights.Length, () => new Light());

            for (var i = 0; i < trRoom.Lights.Length; i++)
            {
                var l = room.Lights[i];
                var tl = trRoom.Lights[i];

                l.LightType = tl.LightType;

                l.Position = tl.Position.ToVector3();

                if (l.LightType == LightType.Shadow)
                {
                    l.Colour[0] = -(tl.Color.R / 255.0f) * tl.Intensity;
                    l.Colour[1] = -(tl.Color.G / 255.0f) * tl.Intensity;
                    l.Colour[2] = -(tl.Color.B / 255.0f) * tl.Intensity;
                    l.Colour[3] = 1.0f;
                }
                else
                {
                    l.Colour[0] = tl.Color.R / 255.0f * tl.Intensity;
                    l.Colour[1] = tl.Color.G / 255.0f * tl.Intensity;
                    l.Colour[2] = tl.Color.B / 255.0f * tl.Intensity;
                    l.Colour[3] = 1.0f;
                }

                l.Inner = tl.R_Inner;
                l.Outer = tl.R_Outer;
                l.Length = tl.Length;
                l.Cutoff = tl.Cutoff;

                l.Falloff = 0.001f / l.Outer;
            }

#endregion

#region Portals

            room.Portals.Resize(trRoom.Portals.Length, () => new Portal());
            for (var i = 0; i < room.Portals.Count; i++)
            {
                var trp = trRoom.Portals[i];
                var p = room.Portals[i];
                var rDest = world.Rooms[trp.AdjoiningRoom];
                p.Vertices.Resize(4); // in original TR all portals are axis aligned rectangles
                p.DestRoom = rDest;
                p.CurrentRoom = room;
                p.Vertices = trp.Vertices.Reverse().Select(x => x.ToVector3() + room.Transform.Origin).ToList();
                p.Centre = p.Vertices.Sum() / p.Vertices.Count;
                p.GenNormal();

                // Portal position fix
                // X_MIN
                if(p.Normal.Normal.X > 0.999f && (int)p.Centre.X % 2 != 0)
                {
                    p.Move(Vector3.UnitX);
                }

                // Y_MIN
                if (p.Normal.Normal.Y > 0.999f && (int)p.Centre.Y % 2 != 0)
                {
                    p.Move(Vector3.UnitY);
                }

                // Z_MAX
                if (p.Normal.Normal.Z < -0.999f && (int)p.Centre.Z % 2 != 0)
                {
                    p.Move(-Vector3.UnitZ);
                }
            }

#endregion

#region Room borders

            room.BBMin.Z = trRoom.Y_Bottom;
            room.BBMax.Z = trRoom.Y_Top;

            room.BBMin.X = room.Transform.Origin.X + TR_METERING_SECTORSIZE;
            room.BBMin.Y = room.Transform.Origin.Y + TR_METERING_SECTORSIZE;
            room.BBMax.X = room.Transform.Origin.X + TR_METERING_SECTORSIZE * room.SectorsX - TR_METERING_SECTORSIZE;
            room.BBMax.Y = room.Transform.Origin.Y + TR_METERING_SECTORSIZE * room.SectorsY - TR_METERING_SECTORSIZE;

#endregion

#region Alternate room

            // alternate room pointer calculation if one exists.
            room.AlternateRoom = null;
            room.BaseRoom = null;

            if(trRoom.AlternateRoom.IsBetween(0, tr.Rooms.Length, IB.aIbE))
            {
                room.AlternateRoom = world.Rooms[trRoom.AlternateRoom];
            }

#endregion
        }
Beispiel #11
0
        public RigidBody LocalCreateRigidBody(float mass, Matrix4 startTransform, CollisionShape shape)
        {
            bool isDynamic = (mass != 0.0f);

            Vector3 localInertia = Vector3.ZERO;
            if (isDynamic)
                shape.CalculateLocalInertia(mass, out localInertia);

            DefaultMotionState myMotionState = new DefaultMotionState(startTransform);

            RigidBody body;
            using (var rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia))
            {
                body = new RigidBody(rbInfo);
            }

            World.AddRigidBody(body);

            return body;
        }
Beispiel #12
0
        /// <summary>
        /// Creates hair into allocated hair structure, using previously defined setup and entity index.
        /// </summary>
        public bool Create(HairSetup setup, Entity parentEntity)
        {
            // No setup or parent to link to - bypass function.
            if (parentEntity == null || setup == null || setup.LinkBody >= parentEntity.Bf.BoneTags.Count ||
                parentEntity.Bt.BtBody[(int)setup.LinkBody] == null)
                return false;

            var model = EngineWorld.GetModelByID(setup.Model);

            // No model to link to - bypass function.
            if (model == null || model.MeshCount == 0) return false;

            // Setup engine container. FIXME: DOESN'T WORK PROPERLY ATM.
            Container = new EngineContainer();
            Container.Room = parentEntity.Self.Room;
            Container.ObjectType = OBJECT_TYPE.Hair;
            Container.Object = this;

            // Setup initial hair parameters.
            OwnerChar = parentEntity; // Entity to refer to.
            OwnerBody = setup.LinkBody; // Entity body to refer to.

            // Setup initial position / angles.
            var ownerBodyTransform = parentEntity.Transform * parentEntity.Bf.BoneTags[(int) OwnerBody].FullTransform;

            // Number of elements (bodies) is equal to number of hair meshes.
            Elements = new List<HairElement>();
            Elements.Resize(model.MeshCount, () => new HairElement());

            // Root index should be always zero, as it is how engine determines that it is
            // connected to head and renders it properly. Tail index should be always the
            // last element of the hair, as it indicates absence of "child" constraint.
            RootIndex = 0;
            TailIndex = (byte)(Elements.Count - 1);

            // Weight step is needed to determine the weight of each hair body.
            // It is derived from root body weight and tail body weight.
            var weightStep = (setup.RootWeight - setup.TailWeight) / Elements.Count;
            var currentWeight = setup.RootWeight;

            for (var i = 0; i < Elements.Count; i++)
            {
                // Point to corresponding mesh.
                Elements[i].Mesh = model.MeshTree[i].MeshBase;

                // Begin creating ACTUAL physical hair mesh.
                var localInertia = BulletSharp.Math.Vector3.Zero;

                // Make collision shape out of mesh.
                Elements[i].Shape = BT_CSfromMesh(Elements[i].Mesh, true, true, false);
                Elements[i].Shape.CalculateLocalInertia(currentWeight * setup.HairInertia, out localInertia);

                // Decrease next body weight to weight_step parameter.
                currentWeight -= weightStep;

                // Initialize motion state for body.
                var startTransform = ownerBodyTransform;
                var motionState = new DefaultMotionState(((Matrix4)startTransform).ToBullet());

                // Make rigid body.
                Elements[i].Body = new RigidBody(new RigidBodyConstructionInfo(currentWeight, motionState, Elements[i].Shape, localInertia));

                // Damping makes body stop in space by itself, to prevent it from continous movement.
                Elements[i].Body.SetDamping(setup.HairDamping[0], setup.HairDamping[1]);

                // Restitution and friction parameters define "bounciness" and "dullness" of hair.
                Elements[i].Body.Restitution = setup.HairRestitution;
                Elements[i].Body.Friction = setup.HairFriction;

                // Since hair is always moving with Lara, even if she's in still state (like, hanging
                // on a ledge), hair bodies shouldn't deactivate over time.
                Elements[i].Body.ForceActivationState(ActivationState.DisableDeactivation);

                // Hair bodies must not collide with each other, and also collide ONLY with kinematic
                // bodies (e. g. animated meshes), or else Lara's ghost object or anything else will be able to
                // collide with hair!
                Elements[i].Body.UserObject = Container;
                BtEngineDynamicsWorld.AddRigidBody(Elements[i].Body, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.KinematicFilter);

                Elements[i].Body.Activate();
            }

            // GENERATE CONSTRAINTS.
            // All constraints are generic 6-DOF type, as they seem perfect fit for hair.

            // Joint count is calculated from overall body amount multiplied by per-body constraint
            // count.
            Joints = new List<Generic6DofConstraint>();
            Joints.Resize(Elements.Count);

            // If multiple joints per body is specified, joints are placed in circular manner,
            // with obvious step of (SIMD_2_PI) / joint count. It means that all joints will form
            // circle-like figure.
            var currJoint = 0;

            for (var i = 0; i < Elements.Count; i++)
            {
                float bodyLength;
                var localA = new Transform();
                localA.SetIdentity();
                var localB = new Transform();
                localB.SetIdentity();

                var jointX = 0.0f;
                var jointY = 0.0f;

                RigidBody prevBody;
                if(i == 0) // First joint group
                {
                    // Adjust pivot point A to parent body.
                    localA.Origin = setup.HeadOffset + new Vector3(jointX, 0.0f, jointY);
                    Helper.SetEulerZYX(ref localA.Basis, setup.RootAngle.X, setup.RootAngle.Y, setup.RootAngle.Z);
                    // Stealing this calculation because I need it for drawing
                    OwnerBodyHairRoot = localA;

                    localB.Origin = new Vector3(jointX, 0.0f, jointY);
                    Helper.SetEulerZYX(ref localB.Basis, 0, -HalfPI, 0);

                    prevBody = parentEntity.Bt.BtBody[(int) OwnerBody]; // Previous body is parent body.
                }
                else
                {
                    // Adjust pivot point A to previous mesh's length, considering mesh overlap multiplier.
                    bodyLength = Math.Abs(Elements[i - 1].Mesh.BBMax.Y - Elements[i - 1].Mesh.BBMin.Y) *
                                 setup.JointOverlap;

                    localA.Origin = new Vector3(jointX, bodyLength, jointY);
                    Helper.SetEulerZYX(ref localA.Basis, 0, -HalfPI, 0);

                    // Pivot point B is automatically adjusted by Bullet.
                    localB.Origin = new Vector3(jointX, 0.0f, jointY);
                    Helper.SetEulerZYX(ref localB.Basis, 0, -HalfPI, 0);

                    prevBody = Elements[i - 1].Body; // Previous body is preceding hair mesh.
                }

                // Create 6DOF constraint.
                Joints[currJoint] = new Generic6DofConstraint(prevBody, Elements[i].Body, ((Matrix4) localA).ToBullet(),
                    ((Matrix4) localB).ToBullet(), true);

                // CFM and ERP parameters are critical for making joint "hard" and link
                // to Lara's head. With wrong values, constraints may become "elastic".
                for (var axis = 0; axis < 6; axis++)
                {
                    Joints[currJoint].SetParam(ConstraintParam.StopCfm, setup.JointCfm, axis);
                    Joints[currJoint].SetParam(ConstraintParam.StopErp, setup.JointErp, axis);
                }

                Joints[currJoint].LinearLowerLimit = BulletSharp.Math.Vector3.Zero;
                Joints[currJoint].LinearUpperLimit = BulletSharp.Math.Vector3.Zero;

                if(i == 0)
                {
                    // First joint group should be more limited in motion, as it is connected
                    // right to the head. NB: Should we make it scriptable as well?
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(-HalfPI, 0.0f, -HalfPI * 0.4f);
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(-HalfPI * 0.3f, 0.0f, HalfPI * 0.4f);

                    // Increased solver iterations make constraint even more stable.
                    Joints[currJoint].OverrideNumSolverIterations = 100;
                }
                else
                {
                    // Normal joint with more movement freedom.
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(-HalfPI * 0.5f, 0.0f, -HalfPI * 0.5f);
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(HalfPI * 0.5f, 0.0f, HalfPI * 0.5f);
                }

                Joints[currJoint].DebugDrawSize = 5.0f; // Draw constraint axes.

                // Add constraint to the world.
                BtEngineDynamicsWorld.AddConstraint(Joints[currJoint], true);

                currJoint++; // Point to the next joint.
            }

            createHairMesh(model);

            return true;
        }
Beispiel #13
0
        public static void Res_GenRoomCollision(World world)
        {
            foreach (var room in world.Rooms)
            {
                // Inbetween polygons array is later filled by loop which scans adjacent
                // sector heightmaps and fills the gaps between them, thus creating inbetween
                // polygon. Inbetweens can be either quad (if all four corner heights are
                // different), triangle (if one corner height is similar to adjacent) or
                // ghost (if corner heights are completely similar). In case of quad inbetween,
                // two triangles are added to collisional trimesh, in case of triangle inbetween,
                // we add only one, and in case of ghost inbetween, we ignore it.

                // Most difficult task with converting floordata collision to trimesh collision is
                // building inbetween polygons which will block out gaps between sector heights.   
                var roomTween = Res_Sector_GenTweens(room);

                // Final step is sending actual sectors to Bullet collision model. We do it here.

                var cshape = BT_CSfromHeightmap(room.Sectors, roomTween, true, true);

                if(cshape != null)
                {
                    var localInertia = Vector3.Zero;
                    var motionState = new DefaultMotionState(((Matrix4) room.Transform).ToBullet());
                    room.BtBody = new RigidBody(new RigidBodyConstructionInfo(0.0f, motionState, cshape, localInertia.ToBullet()));
                    BtEngineDynamicsWorld.AddRigidBody(room.BtBody, CollisionFilterGroups.AllFilter, CollisionFilterGroups.AllFilter);
                    room.BtBody.UserObject = room.Self;
                    room.BtBody.Restitution = 1.0f;
                    room.BtBody.Friction = 1.0f;
                    room.Self.CollisionType = COLLISION_TYPE.Static; // meshtree
                    room.Self.CollisionShape = COLLISION_SHAPE.Trimesh;
                }
            }
        }
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new DefaultCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new DbvtBroadphase();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, null, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);

            // create the ground
            CollisionShape groundShape = new BoxShape(20, 50, 10);
            CollisionShapes.Add(groundShape);
            CollisionObject ground = LocalCreateRigidBody(0,
                Matrix.RotationAxis(new Vector3(0, 0, 1), (float)Math.PI * 0.03f) * Matrix.Translation(0, -50, 0),
                groundShape);
            ground.Friction = 1;
            ground.RollingFriction = 1;
            ground.UserObject = "Ground";

            groundShape = new BoxShape(100, 50, 100);
            CollisionShapes.Add(groundShape);
            ground = LocalCreateRigidBody(0, Matrix.Translation(0, -54, 0), groundShape);
            ground.Friction = 1;
            ground.RollingFriction = 1;
            ground.UserObject = "Ground";

            // create a few dynamic rigidbodies
            const int NUM_SHAPES = 10;
            CollisionShape[] colShapes = new CollisionShape[NUM_SHAPES] {
                new SphereShape(1),
                new CapsuleShape(0.5f,1),
                new CapsuleShapeX(0.5f,1),
                new CapsuleShapeZ(0.5f,1),
                new ConeShape(0.5f,1),
                new ConeShapeX(0.5f,1),
                new ConeShapeZ(0.5f,1),
                new CylinderShape(new Vector3(0.5f,1,0.5f)),
                new CylinderShapeX(new Vector3(1,0.5f,0.5f)),
                new CylinderShapeZ(new Vector3(0.5f,0.5f,1)),
            };
            foreach (var collisionShape in colShapes)
            {
                CollisionShapes.Add(collisionShape);
            }

            const float mass = 1.0f;

            CollisionShape colShape = new BoxShape(1);
            CollisionShapes.Add(colShape);
            Vector3 localInertia = colShape.CalculateLocalInertia(mass);

            const float start_x = StartPosX - ArraySizeX / 2;
            const float start_y = StartPosY;
            const float start_z = StartPosZ - ArraySizeZ / 2;

            int shapeIndex = 0;
            int k, i, j;
            for (k = 0; k < ArraySizeY; k++)
            {
                for (i = 0; i < ArraySizeX; i++)
                {
                    for (j = 0; j < ArraySizeZ; j++)
                    {
                        Matrix startTransform = Matrix.Translation(
                            2 * i + start_x,
                            2 * k + start_y + 20,
                            2 * j + start_z
                        );
                        shapeIndex++;

                        // using motionstate is recommended, it provides interpolation capabilities
                        // and only synchronizes 'active' objects
                        DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
                        RigidBodyConstructionInfo rbInfo =
                            new RigidBodyConstructionInfo(mass, myMotionState, colShapes[shapeIndex % NUM_SHAPES], localInertia);
                        RigidBody body = new RigidBody(rbInfo);
                        rbInfo.Dispose();

                        body.Friction = 1;
                        body.RollingFriction = 0.3f;
                        body.SetAnisotropicFriction(colShape.AnisotropicRollingFrictionDirection, AnisotropicFrictionFlags.AnisotropicRollingFriction);

                        World.AddRigidBody(body);
                    }
                }
            }
        }
 public static void SetStartWorldTrans(this DefaultMotionState obj, OpenTK.Matrix4 value)
 {
     SetStartWorldTrans(obj, ref value);
 }
Beispiel #16
0
        public static void PrimaryMouseDown()
        {
            var cont = new EngineContainer();
            var dbgR = 128.0f;
            var v = EngineCamera.Position;
            var dir = EngineCamera.ViewDirection;
            var localInertia = BulletSharp.Math.Vector3.Zero;

            var cshape = new SphereShape(dbgR);
            cshape.Margin = COLLISION_MARGIN_DEFAULT;

            var startTransform = new Transform();
            startTransform.SetIdentity();
            var newPos = v;
            startTransform.Origin = newPos;
            cshape.CalculateLocalInertia(12.0f, out localInertia);
            var motionState = new DefaultMotionState(((Matrix4)startTransform).ToBullet());
            var body = new RigidBody(new RigidBodyConstructionInfo(12.0f, motionState, cshape, localInertia));
            BtEngineDynamicsWorld.AddRigidBody(body);
            body.LinearVelocity = (dir * 6000).ToBullet();
            cont.Room = Room.FindPosCogerrence(newPos, EngineCamera.CurrentRoom);
            cont.ObjectType = OBJECT_TYPE.BulletMisc; // bullet have to destroy this user pointer
            body.UserObject = cont;
            body.CcdMotionThreshold = dbgR; // disable tunneling effect
            body.CcdSweptSphereRadius = dbgR;
        }
        /*private void MyTickCallBack(ManifoldPoint cp, CollisionObjectWrapper colobj0wrap, int partid0, int index0, CollisionObjectWrapper colobj1wrap, int partid1, int index1)
        {
            Debug.WriteLine("MyTickCallBack");
            int numManifolds = BtWorld.Dispatcher.NumManifolds;
            RigidBodyImp myRb;
            //Debug.WriteLine("numManifolds: " + numManifolds);
            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = BtWorld.Dispatcher.GetManifoldByIndexInternal(i);
                int numContacts = contactManifold.NumContacts;
                if (numContacts > 0)
                {
                    CollisionObject obA = (CollisionObject) contactManifold.Body0;
                    CollisionObject obB = (CollisionObject) contactManifold.Body1;

                   // Debug.WriteLine(numContacts);
                    var pnA = obA.UserObject;

                    for (int j = 0; j < numContacts; j++)
                    {
                        ManifoldPoint pt = contactManifold.GetContactPoint(j);

                    }
                }
            }
        }*/
        public IRigidBodyImp AddRigidBody(float mass, float3 worldTransform, float3 orientation, ICollisionShapeImp colShape/*, float3 intertia*/)
        {
            // Use bullet to do what needs to be done:

             var btMatrix = Matrix.RotationX(orientation.x)
                                    * Matrix.RotationY(orientation.y)
                                    * Matrix.RotationZ(orientation.z)
                                    * Matrix.Translation(worldTransform.x, worldTransform.y, worldTransform.z);

             var btMotionState = new DefaultMotionState(btMatrix);

            var shapeType = colShape.GetType().ToString();

            CollisionShape btColShape;

            var isStatic = false;
            switch (shapeType)
            {
                //Primitives
                case "Fusee.Engine.BoxShapeImp":
                    var box = (BoxShapeImp) colShape;
                    var btBoxHalfExtents = Translater.Float3ToBtVector3(box.HalfExtents);
                    btColShape = new BoxShape(btBoxHalfExtents);
                    break;
                case "Fusee.Engine.CapsuleShapeImp":
                    var capsule = (CapsuleShapeImp) colShape;
                    btColShape = new CapsuleShape(capsule.Radius, capsule.HalfHeight);
                    break;
                case "Fusee.Engine.ConeShapeImp":
                    var cone = (ConeShapeImp) colShape;
                    btColShape = new ConeShape(cone.Radius, cone.Height);
                    break;
                case "Fusee.Engine.CylinderShapeImp":
                    var cylinider = (CylinderShapeImp) colShape;
                    var btCylinderHalfExtents = Translater.Float3ToBtVector3(cylinider.HalfExtents);
                    btColShape = new CylinderShape(btCylinderHalfExtents);
                    break;
                case "Fusee.Engine.MultiSphereShapeImp":
                    var multiSphere = (MultiSphereShapeImp) colShape;
                    var btPositions = new Vector3[multiSphere.SphereCount];
                    var btRadi = new float[multiSphere.SphereCount];
                    for (int i = 0; i < multiSphere.SphereCount; i++)
                    {
                        var pos = Translater.Float3ToBtVector3(multiSphere.GetSpherePosition(i));
                        btPositions[i] = pos;
                        btRadi[i] = multiSphere.GetSphereRadius(i);
                    }
                    btColShape = new MultiSphereShape(btPositions, btRadi);
                    break;
                case "Fusee.Engine.SphereShapeImp":
                    var sphere = (SphereShapeImp) colShape;
                    var btRadius = sphere.Radius;
                    btColShape = new SphereShape(btRadius);
                    break;

                //Misc
                case "Fusee.Engine.CompoundShapeImp":
                    var compShape = (CompoundShapeImp) colShape;
                    btColShape = new CompoundShape(true);
                    btColShape = compShape.BtCompoundShape;
                    break;
                case "Fusee.Engine.EmptyShapeImp":
                    btColShape = new EmptyShape();
                    break;

                //Meshes
                case "Fusee.Engine.ConvexHullShapeImp":
                    var convHull = (ConvexHullShapeImp) colShape;
                    var btPoints= new Vector3[convHull.GetNumPoints()];
                    for (int i = 0; i < convHull.GetNumPoints(); i++)
                    {
                        var point = convHull.GetScaledPoint(i);
                        btPoints[i] = Translater.Float3ToBtVector3(point);
                    }
                    btColShape = new ConvexHullShape(btPoints);
                    //btColShape.LocalScaling = new Vector3(3,3,3);
                    break;
                case "Fusee.Engine.StaticPlaneShapeImp":
                    var staticPlane = (StaticPlaneShapeImp) colShape;
                    Debug.WriteLine("staticplane: " + staticPlane.Margin);
                    var btNormal = Translater.Float3ToBtVector3(staticPlane.PlaneNormal);
                    btColShape = new StaticPlaneShape(btNormal, staticPlane.PlaneConstant);
                    isStatic = true;
                    //btColShape.Margin = 0.04f;
                    //Debug.WriteLine("btColshape" + btColShape.Margin);
                    break;
                case "Fusee.Engine.GImpactMeshShapeImp":
                    var gImpMesh = (GImpactMeshShapeImp)colShape;
                    gImpMesh.BtGImpactMeshShape.UpdateBound();
                    var btGimp = new GImpactMeshShape(gImpMesh.BtGImpactMeshShape.MeshInterface);

                    btGimp.UpdateBound();
                    btColShape = btGimp;

                    break;
                //Default
                default:
                    Debug.WriteLine("defaultImp");
                    btColShape = new EmptyShape();
                    break;
            }

            var btLocalInertia = btColShape.CalculateLocalInertia(mass);
               // btLocalInertia *= (10.0f*10);
            RigidBodyConstructionInfo btRbcInfo = new RigidBodyConstructionInfo(mass, btMotionState, btColShape,
                btLocalInertia);

            var btRigidBody = new RigidBody(btRbcInfo);
            btRigidBody.Restitution = 0.2f;
            btRigidBody.Friction = 0.2f;
            btRigidBody.CollisionFlags = CollisionFlags.CustomMaterialCallback;

            BtWorld.AddRigidBody(btRigidBody);
            btRbcInfo.Dispose();
            var retval = new RigidBodyImp();
            retval._rbi = btRigidBody;
            btRigidBody.UserObject = retval;
            return retval;
        }
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new DefaultCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new DbvtBroadphase();

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, null, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);

            GImpactCollisionAlgorithm.RegisterAlgorithm(Dispatcher);

            string bulletFile;
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length == 1)
            {
                bulletFile = "testFile.bullet";
            }
            else
            {
                bulletFile = args[1];
            }

            fileLoader = new CustomBulletWorldImporter(World);
            if (!fileLoader.LoadFile(bulletFile))
            {
                CollisionShape groundShape = new BoxShape(50);
                CollisionShapes.Add(groundShape);
                RigidBody ground = LocalCreateRigidBody(0, Matrix.Translation(0, -50, 0), groundShape);
                ground.UserObject = "Ground";

                // create a few dynamic rigidbodies
                float mass = 1.0f;

                Vector3[] positions = new Vector3[2] { new Vector3(0.1f, 0.2f, 0.3f), new Vector3(0.4f, 0.5f, 0.6f) };
                float[] radi = new float[2] { 0.3f, 0.4f };

                CollisionShape colShape = new MultiSphereShape(positions, radi);

                //CollisionShape colShape = new CapsuleShapeZ(1, 1);
                //CollisionShape colShape = new CylinderShapeZ(1, 1, 1);
                //CollisionShape colShape = new BoxShape(1);
                //CollisionShape colShape = new SphereShape(1);
                CollisionShapes.Add(colShape);

                Vector3 localInertia = colShape.CalculateLocalInertia(mass);

                float start_x = StartPosX - ArraySizeX / 2;
                float start_y = StartPosY;
                float start_z = StartPosZ - ArraySizeZ / 2;

                int k, i, j;
                for (k = 0; k < ArraySizeY; k++)
                {
                    for (i = 0; i < ArraySizeX; i++)
                    {
                        for (j = 0; j < ArraySizeZ; j++)
                        {
                            Matrix startTransform = Matrix.Translation(
                                2 * i + start_x,
                                2 * k + start_y,
                                2 * j + start_z
                            );

                            // using motionstate is recommended, it provides interpolation capabilities
                            // and only synchronizes 'active' objects
                            DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
                            RigidBodyConstructionInfo rbInfo =
                                new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
                            RigidBody body = new RigidBody(rbInfo);
                            rbInfo.Dispose();

                            // make it drop from a height
                            body.Translate(new Vector3(0, 20, 0));

                            World.AddRigidBody(body);
                        }
                    }
                }

                DefaultSerializer serializer = new DefaultSerializer();

                serializer.RegisterNameForObject(ground, "GroundName");

                for (i = 0; i < CollisionShapes.Count; i++)
                    serializer.RegisterNameForObject(CollisionShapes[i], "name" + i.ToString());

                Point2PointConstraint p2p = new Point2PointConstraint((RigidBody)World.CollisionObjectArray[2], new Vector3(0, 1, 0));
                World.AddConstraint(p2p);

                serializer.RegisterNameForObject(p2p, "constraintje");

                World.Serialize(serializer);

                BulletSharp.DataStream data = serializer.LockBuffer();
                byte[] dataBytes = new byte[data.Length];
                data.Read(dataBytes, 0, dataBytes.Length);

                FileStream file = new FileStream("testFile.bullet", FileMode.Create);
                file.Write(dataBytes, 0, dataBytes.Length);
                file.Close();
            }
        }
Beispiel #19
0
        public RigidBody CreateRigidBody(float mass, Matrix4 startTransform, CollisionShape shape, Mesh3d reference)
        {
            bool isDynamic = (mass != 0.0f);

            Vector3 localInertia = Vector3.Zero;
            if(isDynamic)
                shape.CalculateLocalInertia(mass, out localInertia);

            DefaultMotionState myMotionState = new DefaultMotionState(startTransform);

            RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
            RigidBody body = new RigidBody(rbInfo);
            body.UserObject = reference;

            PhysicalWorld.AddRigidBody(body);

            return body;
        }
 public static OpenTK.Matrix4 GetCenterOfMassOffset(this DefaultMotionState obj)
 {
     OpenTK.Matrix4 value;
     GetCenterOfMassOffset(obj, out value);
     return(value);
 }
Beispiel #21
0
        public virtual RigidBody LocalCreateRigidBody(float mass, Matrix startTransform, CollisionShape shape, bool isKinematic = false)
        {
            //rigidbody is dynamic if and only if mass is non zero, otherwise static
            bool isDynamic = (mass != 0.0f);

            Vector3 localInertia = Vector3.Zero;
            if (isDynamic)
                shape.CalculateLocalInertia(mass, out localInertia);

            //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
            DefaultMotionState myMotionState = new DefaultMotionState(startTransform);

            RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
            RigidBody body = new RigidBody(rbInfo);
            if (isKinematic) {
                body.CollisionFlags = body.CollisionFlags | CollisionFlags.KinematicObject;
                body.ActivationState = ActivationState.DisableDeactivation;
            }
            rbInfo.Dispose();

            _world.AddRigidBody(body);

            return body;
        }
        void AddBoxes()
        {
            // create a few dynamic rigidbodies
            const float mass = 1.0f;

            BoxShape colShape = new BoxShape(1);
            CollisionShapes.Add(colShape);
            Vector3 localInertia = colShape.CalculateLocalInertia(mass);

            const float startX = StartPosX - ArraySizeX / 2;
            const float startY = StartPosY;
            const float startZ = StartPosZ - ArraySizeZ / 2;

            int k, i, j;
            for (k = 0; k < ArraySizeY; k++)
            {
                for (i = 0; i < ArraySizeX; i++)
                {
                    for (j = 0; j < ArraySizeZ; j++)
                    {
                        Matrix startTransform = Matrix.Translation(
                            3 * i + startX,
                            3 * k + startY,
                            3 * j + startZ
                        );

                        // using motionstate is recommended, it provides interpolation capabilities
                        // and only synchronizes 'active' objects
                        DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
                        using (var rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia))
                        {
                            var body = new RigidBody(rbInfo);
                            World.AddRigidBody(body);
                        }
                    }
                }
            }
        }
Beispiel #23
0
        public void GenRigidBody()
        {
            if (Bf.Animations.Model == null || Self.CollisionType == COLLISION_TYPE.None)
                return;

            Bt.BtBody.Clear();

            for(var i = 0; i < Bf.BoneTags.Count; i++)
            {
                var mesh = Bf.Animations.Model.MeshTree[i].MeshBase;
                CollisionShape cshape;
                switch(Self.CollisionShape)
                {
                    case COLLISION_SHAPE.Sphere:
                        cshape = BT_CSfromSphere(mesh.Radius);
                        break;

                    case COLLISION_SHAPE.TrimeshConvex:
                        cshape = BT_CSfromMesh(mesh, true, true, false);
                        break;

                    case COLLISION_SHAPE.Trimesh:
                        cshape = BT_CSfromMesh(mesh, true, true, true);
                        break;

                    case COLLISION_SHAPE.Box:
                    default:
                        cshape = BT_CSfromBBox(mesh.BBMin, mesh.BBMax, true, true);
                        break;
                }

                Bt.BtBody.Add(null);

                if(cshape != null)
                {
                    var localInertia = BulletSharp.Math.Vector3.Zero;
                    if (Self.CollisionShape != COLLISION_SHAPE.Trimesh)
                        cshape.CalculateLocalInertia(0.0f, out localInertia);

                    var startTransform = Transform * Bf.BoneTags[i].FullTransform;
                    var motionState = new DefaultMotionState(((Matrix4)startTransform).ToBullet());
                    Bt.BtBody[Bt.BtBody.Count - 1] = new RigidBody(new RigidBodyConstructionInfo(0.0f, motionState, cshape, localInertia));

                    var cf = CollisionFlags.None;
                    switch (Self.CollisionType)
                    {
                        case COLLISION_TYPE.Kinematic:
                            Bt.BtBody[Bt.BtBody.Count - 1].CollisionFlags |= CollisionFlags.KinematicObject;
                            break;

                        case COLLISION_TYPE.Ghost:
                            Bt.BtBody[Bt.BtBody.Count - 1].CollisionFlags |= CollisionFlags.NoContactResponse;
                            break;

                        case COLLISION_TYPE.Actor:
                        case COLLISION_TYPE.Vehicle:
                            Bt.BtBody[Bt.BtBody.Count - 1].CollisionFlags |= CollisionFlags.CharacterObject;
                            break;

                        case COLLISION_TYPE.Static:
                        default:
                            Bt.BtBody[Bt.BtBody.Count - 1].CollisionFlags |= CollisionFlags.StaticObject;
                            break;
                    }

                    BtEngineDynamicsWorld.AddRigidBody(Bt.BtBody[i], CollisionFilterGroups.KinematicFilter, CollisionFilterGroups.AllFilter);
                    Bt.BtBody.Last().UserObject = Self;
                }
            }
        }
        /// <summary>
        /// Creates a new trigger region. It automatically adds itself to the TriggerReporter's dictionary, so you don't have to do that.
        /// </summary>
        /// <param name="orientation">a degree vector</param>
        public TriggerRegion(string name, Vector3 position, Quaternion orientation, CollisionShape shape)
        {
            Name = name;
            CurrentlyCollidingWith = new HashSet<RigidBody>();

            // mogre
            var sceneMgr = LKernel.GetG<SceneManager>();

            Node = sceneMgr.RootSceneNode.CreateChildSceneNode(name);
            if (Settings.Default.EnableGlowyRegions) {
                // make a mesh for the region depending on what its type is
                switch (shape.ShapeType) {
                    case BroadphaseNativeType.BoxShape:
                        Entity = sceneMgr.CreateEntity(name, "primitives/box.mesh");
                        Node.SetScale((shape as BoxShape).HalfExtentsWithoutMargin * 2);
                        break;
                    case BroadphaseNativeType.CapsuleShape:
                        Entity = sceneMgr.CreateEntity(name, "primitives/cylinder.mesh");
                        Vector3 vec = new Vector3();
                        vec.y = (shape as CapsuleShape).HalfHeight * 2;
                        vec.x = vec.z = (shape as CapsuleShape).Radius * 2;
                        Node.SetScale(vec);
                        break;
                    case BroadphaseNativeType.CylinderShape:
                        Entity = sceneMgr.CreateEntity(name, "primitives/cylinder.mesh");
                        Vector3 vec2 = new Vector3();
                        vec2.y = (shape as CylinderShape).HalfExtentsWithoutMargin.y;
                        vec2.x = vec2.z = (shape as CylinderShape).Radius * 2;
                        Node.SetScale(vec2);
                        break;
                    case BroadphaseNativeType.SphereShape:
                        Entity = sceneMgr.CreateEntity(name, "primitives/sphere.mesh");
                        float dim = (shape as SphereShape).Radius * 2;
                        Node.SetScale(dim, dim, dim);
                        break;
                    default:
                        // for things like meshes, convex hulls, etc
                        Entity = sceneMgr.CreateEntity(name, "primitives/box.mesh");
                        break;
                }
                GlowColor = BalloonGlowColour.red;
                Entity.CastShadows = false;

                Node.AttachObject(Entity);
            }
            Node.Position = position;
            Node.Orientation = orientation;

            // physics
            Matrix4 transform = new Matrix4();
            transform.MakeTransform(position, Vector3.UNIT_SCALE, orientation);

            var motionState = new DefaultMotionState();
            motionState.WorldTransform = transform;

            // thanks to kloplop321 in #ogre3d for his help with this
             	Ghost = new GhostObject();
            Ghost.CollisionShape = shape;
            Ghost.WorldTransform = transform;
            Ghost.UserObject = new CollisionObjectDataHolder(Ghost, PonykartCollisionGroups.Triggers, name);

            Ghost.CollisionFlags |= CollisionFlags.NoContactResponse | CollisionFlags.CustomMaterialCallback;
            LKernel.GetG<PhysicsMain>().World.AddCollisionObject(Ghost, PonykartCollisionGroups.Triggers, PonykartCollidesWithGroups.Triggers);

            // then add this to the trigger reporter
            LKernel.GetG<TriggerReporter>().Regions.Add(name, this);
        }
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new DefaultCollisionConfiguration();
            Dispatcher = new CollisionDispatcher(CollisionConf);

            Broadphase = new DbvtBroadphase();
            Solver = new MultiBodyConstraintSolver();

            World = new MultiBodyDynamicsWorld(Dispatcher, Broadphase, Solver as MultiBodyConstraintSolver, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);

            // create a few basic rigid bodies
            BoxShape groundShape = new BoxShape(50, 50, 50);
            //groundShape.InitializePolyhedralFeatures();
            //CollisionShape groundShape = new StaticPlaneShape(new Vector3(0,1,0), 50);

            CollisionShapes.Add(groundShape);
            CollisionObject ground = LocalCreateRigidBody(0, Matrix.Translation(0, -50, 0), groundShape);
            ground.UserObject = "Ground";

            // create a few dynamic rigidbodies
            const float mass = 1.0f;

            BoxShape colShape = new BoxShape(1);
            CollisionShapes.Add(colShape);
            Vector3 localInertia = colShape.CalculateLocalInertia(mass);

            const float start_x = StartPosX - ArraySizeX / 2;
            const float start_y = StartPosY;
            const float start_z = StartPosZ - ArraySizeZ / 2;

            int k, i, j;
            for (k = 0; k < ArraySizeY; k++)
            {
                for (i = 0; i < ArraySizeX; i++)
                {
                    for (j = 0; j < ArraySizeZ; j++)
                    {
                        Matrix startTransform = Matrix.Translation(
                            3 * i + start_x,
                            3 * k + start_y,
                            3 * j + start_z
                        );

                        // using motionstate is recommended, it provides interpolation capabilities
                        // and only synchronizes 'active' objects
                        DefaultMotionState myMotionState = new DefaultMotionState(startTransform);
                        using (var rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia))
                        {
                            var body = new RigidBody(rbInfo);
                            World.AddRigidBody(body);
                        }
                    }
                }
            }

            var settings = new MultiBodySettings()
            {
                BasePosition = new Vector3(60, 29.5f, -2) * Scaling,
                CanSleep = true,
                CreateConstraints = true,
                DisableParentCollision = true, // the self-collision has conflicting/non-resolvable contact normals
                IsFixedBase = false,
                NumLinks = 2,
                UsePrismatic = true
            };
            var multiBodyA = CreateFeatherstoneMultiBody(World as MultiBodyDynamicsWorld, settings);

            settings.NumLinks = 10;
            settings.BasePosition = new Vector3(0, 29.5f, -settings.NumLinks * 4);
            settings.IsFixedBase = true;
            settings.UsePrismatic = false;
            var multiBodyB = CreateFeatherstoneMultiBody(World as MultiBodyDynamicsWorld, settings);

            settings.BasePosition = new Vector3(-20 * Scaling, 29.5f * Scaling, -settings.NumLinks * 4 * Scaling);
            settings.IsFixedBase = false;
            var multiBodyC = CreateFeatherstoneMultiBody(World as MultiBodyDynamicsWorld, settings);

            settings.BasePosition = new Vector3(-20, 9.5f, -settings.NumLinks * 4);
            settings.IsFixedBase = true;
            settings.UsePrismatic = true;
            settings.DisableParentCollision = true;
            var multiBodyPrim = CreateFeatherstoneMultiBody(World as MultiBodyDynamicsWorld, settings);
        }
Beispiel #26
0
        /// <inheritdoc/>
        public override BulletSharp.RigidBody CreateRigidBody(float mass)
        {
            var ppm = DD.Physics.PhysicsSimulator.PPM;

            var mstate = new DefaultMotionState ();
            var shape = new BulletSharp.BoxShape (halfWidth/ppm, halfHeight/ppm, halfDepth/ppm);
            var info = new BulletSharp.RigidBodyConstructionInfo (mass, mstate, shape);

            var body = new BulletSharp.RigidBody (info);

            return body;
        }
Beispiel #27
0
        /// <inheritdoc/>
        public override BulletSharp.RigidBody CreateRigidBody(float mass)
        {
            var ppm = DD.Physics.PhysicsSimulator.PPM;

               var mstate = new DefaultMotionState ();
               var shape = new BulletSharp.CapsuleShape (radius/ppm, halfHeight/ppm);
               var info = new BulletSharp.RigidBodyConstructionInfo (mass, mstate, shape);

               return new BulletSharp.RigidBody (info);
        }
Beispiel #28
0
        private RigidBody CreateRigidBody(float mass, Matrix4 startTransform, CollisionShape shape)
        {
            bool isDynamic = (mass != 0.0f);

            Vector3 localInertia = Vector3.Zero;
            if(isDynamic)
                shape.CalculateLocalInertia(mass, out localInertia);

            DefaultMotionState myMotionState = new DefaultMotionState(startTransform);

            RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
            RigidBody body = new RigidBody(rbInfo);


            body.SetSleepingThresholds(0, 0);
            body.ContactProcessingThreshold = 0;
            body.CcdMotionThreshold = 0;

            //World.AddRigidBody(body);

            return body;
        }
        protected override void OnInitializePhysics()
        {
            // collision configuration contains default setup for memory, collision setup
            CollisionConf = new DefaultCollisionConfiguration();

            // Use the default collision dispatcher. For parallel processing you can use a diffent dispatcher.
            Dispatcher = new CollisionDispatcher(CollisionConf);

            VoronoiSimplexSolver simplex = new VoronoiSimplexSolver();
            MinkowskiPenetrationDepthSolver pdSolver = new MinkowskiPenetrationDepthSolver();

            Convex2DConvex2DAlgorithm.CreateFunc convexAlgo2d = new Convex2DConvex2DAlgorithm.CreateFunc(simplex, pdSolver);

            Dispatcher.RegisterCollisionCreateFunc(BroadphaseNativeType.Convex2DShape, BroadphaseNativeType.Convex2DShape, convexAlgo2d);
            Dispatcher.RegisterCollisionCreateFunc(BroadphaseNativeType.Box2DShape, BroadphaseNativeType.Convex2DShape, convexAlgo2d);
            Dispatcher.RegisterCollisionCreateFunc(BroadphaseNativeType.Convex2DShape, BroadphaseNativeType.Box2DShape, convexAlgo2d);
            Dispatcher.RegisterCollisionCreateFunc(BroadphaseNativeType.Box2DShape, BroadphaseNativeType.Box2DShape, new Box2DBox2DCollisionAlgorithm.CreateFunc());

            Broadphase = new DbvtBroadphase();

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

            World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf);
            World.Gravity = new Vector3(0, -10, 0);

            // create a few basic rigid bodies
            CollisionShape groundShape = new BoxShape(150, 7, 150);
            CollisionShapes.Add(groundShape);
            RigidBody ground = LocalCreateRigidBody(0, Matrix.Identity, groundShape);
            ground.UserObject = "Ground";

            // create a few dynamic rigidbodies
            // Re-using the same collision is better for memory usage and performance
            float u = 0.96f;
            Vector3[] points = { new Vector3(0, u, 0), new Vector3(-u, -u, 0), new Vector3(u, -u, 0) };
            ConvexShape childShape0 = new BoxShape(1, 1, Depth);
            ConvexShape colShape = new Convex2DShape(childShape0);
            ConvexShape childShape1 = new ConvexHullShape(points);
            ConvexShape colShape2 = new Convex2DShape(childShape1);
            ConvexShape childShape2 = new CylinderShapeZ(1, 1, Depth);
            ConvexShape colShape3 = new Convex2DShape(childShape2);

            CollisionShapes.Add(colShape);
            CollisionShapes.Add(colShape2);
            CollisionShapes.Add(colShape3);

            CollisionShapes.Add(childShape0);
            CollisionShapes.Add(childShape1);
            CollisionShapes.Add(childShape2);

            colShape.Margin = 0.03f;

            float mass = 1.0f;
            Vector3 localInertia = colShape.CalculateLocalInertia(mass);

            Matrix startTransform;

            Vector3 x = new Vector3(-ArraySizeX, 8, -20);
            Vector3 y = Vector3.Zero;
            Vector3 deltaX = new Vector3(1, 2, 0);
            Vector3 deltaY = new Vector3(2, 0, 0);

            int i, j;
            for (i = 0; i < ArraySizeY; i++)
            {
                y = x;
                for (j = 0; j < ArraySizeX; j++)
                {
                    startTransform = Matrix.Translation(y - new Vector3(-10, 0, 0));

                    //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
                    DefaultMotionState myMotionState = new DefaultMotionState(startTransform);

                    RigidBodyConstructionInfo rbInfo;
                    switch (j % 3)
                    {
                        case 0:
                            rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
                            break;
                        case 1:
                            rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape3, localInertia);
                            break;
                        default:
                            rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape2, localInertia);
                            break;
                    }
                    RigidBody body = new RigidBody(rbInfo);
                    rbInfo.Dispose();
                    //body.ActivationState = ActivationState.IslandSleeping;
                    body.LinearFactor = new Vector3(1, 1, 0);
                    body.AngularFactor = new Vector3(0, 0, 1);

                    World.AddRigidBody(body);

                    y += deltaY;
                }
                x += deltaX;
            }
        }
 public static OpenTK.Matrix4 GetStartWorldTrans(this DefaultMotionState obj)
 {
     OpenTK.Matrix4 value;
     GetStartWorldTrans(obj, out value);
     return(value);
 }
 public static void SetCenterOfMassOffset(this DefaultMotionState obj, OpenTK.Matrix4 value)
 {
     SetCenterOfMassOffset(obj, ref value);
 }
Beispiel #32
0
        public RigidBody CreateRigidBody(bool forceRecreate = false)
        {
            if(PhysicalBody != null && !forceRecreate)
                return PhysicalBody;
            bool isDynamic = (Mass != 0.0f);
            var shape = GetCollisionShape();

            Vector3 localInertia = Vector3.Zero;
            if(isDynamic)
                shape.CalculateLocalInertia(Mass, out localInertia);

            DefaultMotionState myMotionState = new DefaultMotionState(Matrix4.CreateFromQuaternion(Transformation.GetOrientation()) * Matrix4.CreateTranslation(Transformation.GetPosition()));

            RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(Mass, myMotionState, shape, localInertia);
            RigidBody body = new RigidBody(rbInfo);
            body.UserObject = this;

            PhysicalBody = body;

            return body;
        }