public unsafe static void GetGraphicsWorldTrans(this DefaultMotionState obj, out OpenTK.Matrix4 value) { fixed(OpenTK.Matrix4 *valuePtr = &value) { *(BulletSharp.Math.Matrix *)valuePtr = obj.GraphicsWorldTrans; } }
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; } }
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; } }
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; }
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; }
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 }
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; }
/// <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; }
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); }
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(); } }
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); }
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); } } } } }
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); }
/// <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; }
/// <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); }
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); }
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; }