public override CollisionShape GetCollisionShape() { if (collisionShapePtr == null) { collisionShapePtr = new SphereShape(radius); } return collisionShapePtr; }
/// <summary> /// Starts the component. /// </summary> /// <param name="time">Time snapshot</param> protected override void OnStart(GameTime time) { base.OnStart(time); this.sphere = new BulletSharp.SphereShape(this.Radius); this.sphere.UserObject = this; }
public override CollisionShape GetCollisionShape() { if (collisionShapePtr == null) { collisionShapePtr = new SphereShape(radius); ((SphereShape)collisionShapePtr).LocalScaling = m_localScaling.ToBullet(); } return collisionShapePtr; }
public FreeCamera(float aspectRatio, float fov) { Cam = new Camera(new Vector3(20, 20, 20), new Vector3(0, 2, 0), aspectRatio, fov, 1.0f, 10000.0f); collisionShape = new SphereShape(0.8f); //collisionShape.LinearDamping = 0.5f; rigidBody = World.Root.CreateRigidBody(0.01f, Matrix4.CreateTranslation(Cam.Transformation.GetPosition()), collisionShape, null); rigidBody.SetSleepingThresholds(0, 0); rigidBody.ContactProcessingThreshold = 0; rigidBody.CcdMotionThreshold = 0; World.Root.PhysicalWorld.AddRigidBody(rigidBody); rigidBody.Gravity = Vector3.Zero; rigidBody.ApplyGravity(); rigidBody.SetDamping(0.5f, 0.01f); GLThread.OnUpdate += UpdateSterring; GLThread.OnMouseMove += OnMouseMove; }
public Person(Vector3 StartPosition) { CameraDefinition defaultCameraDefinition = new CameraDefinition() { Distance = 10, FPV = true, Offset = Vector3.UnitY, ViewAngle = Vector2.One, Style = DrawingStyle.Normal }; CameraList = new Camera[] { new FirstPersonCamera(defaultCameraDefinition), new ThirdPersonCamera(defaultCameraDefinition) }; CurrentCamera = 0; SphereShape body = new SphereShape(0.5f); CharacterBody = World.CreateRigidBody(80, Matrix4.CreateTranslation(StartPosition), body); }
public PhysicsConvexSweepTestItem(Matrix4 from, Matrix4 to, int collisionFilterGroup, int collisionFilterMask, ModeEnum mode, Sphere sphere) { this.originalFrom = from; this.originalTo = to; this.CollisionFilterGroup = collisionFilterGroup; this.CollisionFilterMask = collisionFilterMask; this.Mode = mode; transformedFrom = originalFrom; transformedTo = originalTo; Vector3 offset = sphere.Origin; if (offset != Vector3.Zero) { transformedFrom.SetTranslation(transformedFrom.GetTranslation() + offset); transformedTo.SetTranslation(transformedTo.GetTranslation() + offset); } Shape = new BulletSharp.SphereShape(sphere.Radius); ShapeAutoDispose = true; }
public FreeCamera(float aspectRatio, float fov) { Cam = new Camera(new Vector3(20, 20, 20), new Vector3(0, 2, 0), aspectRatio, fov, 0.1f, 10000.0f); Camera.MainDisplayCamera = Cam; collisionShape = new SphereShape(0.8f); //collisionShape.LinearDamping = 0.5f; rigidBody = World.Root.CreateRigidBody(0.01f, Matrix4.CreateTranslation(Cam.Transformation.GetPosition()), collisionShape, null); rigidBody.SetSleepingThresholds(0, 0); rigidBody.ContactProcessingThreshold = 0; rigidBody.CcdMotionThreshold = 0; World.Root.PhysicalWorld.AddRigidBody(rigidBody); rigidBody.Gravity = Vector3.Zero; rigidBody.ApplyGravity(); rigidBody.SetDamping(0.5f, 0.01f); GLThread.OnUpdate += UpdateSterring; GLThread.OnMouseMove += OnMouseMove; GLThread.OnKeyUp += (o, e) => { if(e.Key == OpenTK.Input.Key.P) { GravityEnabled = !GravityEnabled; if(GravityEnabled) { rigidBody.Gravity = new Vector3(0, -9.81f, 0); rigidBody.ApplyGravity(); rigidBody.SetDamping(0.8f, 0.01f); } else { rigidBody.Gravity = Vector3.Zero; rigidBody.ApplyGravity(); rigidBody.SetDamping(0.5f, 0.01f); } } }; }
/// <inheritdoc/> public override BulletSharp.RigidBody CreateRigidBody(float mass) { var ppm = DD.Physics.PhysicsSimulator.PPM; var mstate = new DefaultMotionState (); var shape = new BulletSharp.SphereShape (radius / ppm); var info = new BulletSharp.RigidBodyConstructionInfo (mass, mstate, shape); return new BulletSharp.RigidBody (info); }
public static UnityEngine.Vector3[] CreateSphere(SphereShape shape, out int[] indices) { return CreateSphere(shape.Radius, out indices); }
public static void CreateSphere(SphereShape shape, Mesh mesh) { mesh.Clear(); float radius = shape.Radius; // Longitude ||| int nbLong = 24; // Latitude --- int nbLat = 16; #region Vertices UnityEngine.Vector3[] vertices = new UnityEngine.Vector3[(nbLong + 1) * nbLat + 2]; float _pi = Mathf.PI; float _2pi = _pi * 2f; vertices[0] = UnityEngine.Vector3.up * radius; for (int lat = 0; lat < nbLat; lat++) { float a1 = _pi * (float)(lat + 1) / (nbLat + 1); float sin1 = Mathf.Sin(a1); float cos1 = Mathf.Cos(a1); for (int lon = 0; lon <= nbLong; lon++) { float a2 = _2pi * (float)(lon == nbLong ? 0 : lon) / nbLong; float sin2 = Mathf.Sin(a2); float cos2 = Mathf.Cos(a2); vertices[lon + lat * (nbLong + 1) + 1] = new UnityEngine.Vector3(sin1 * cos2, cos1, sin1 * sin2) * radius; } } vertices[vertices.Length - 1] = UnityEngine.Vector3.up * -radius; #endregion #region Normales UnityEngine.Vector3[] normales = new UnityEngine.Vector3[vertices.Length]; for (int n = 0; n < vertices.Length; n++) normales[n] = vertices[n].normalized; #endregion #region UVs Vector2[] uvs = new Vector2[vertices.Length]; uvs[0] = Vector2.up; uvs[uvs.Length - 1] = Vector2.zero; for (int lat = 0; lat < nbLat; lat++) for (int lon = 0; lon <= nbLong; lon++) uvs[lon + lat * (nbLong + 1) + 1] = new Vector2((float)lon / nbLong, 1f - (float)(lat + 1) / (nbLat + 1)); #endregion #region Triangles int nbFaces = vertices.Length; int nbTriangles = nbFaces * 2; int nbIndexes = nbTriangles * 3; int[] triangles = new int[nbIndexes]; //Top Cap int i = 0; for (int lon = 0; lon < nbLong; lon++) { triangles[i++] = lon + 2; triangles[i++] = lon + 1; triangles[i++] = 0; } //Middle for (int lat = 0; lat < nbLat - 1; lat++) { for (int lon = 0; lon < nbLong; lon++) { int current = lon + lat * (nbLong + 1) + 1; int next = current + nbLong + 1; triangles[i++] = current; triangles[i++] = current + 1; triangles[i++] = next + 1; triangles[i++] = current; triangles[i++] = next + 1; triangles[i++] = next; } } //Bottom Cap for (int lon = 0; lon < nbLong; lon++) { triangles[i++] = vertices.Length - 1; triangles[i++] = vertices.Length - (lon + 2) - 1; triangles[i++] = vertices.Length - (lon + 1) - 1; } #endregion mesh.vertices = vertices; mesh.normals = normales; mesh.uv = uvs; mesh.triangles = triangles; mesh.RecalculateBounds(); mesh.Optimize(); }
public CarScene() { Object3dInfo waterInfo = Object3dGenerator.CreateGround(new Vector2(-200, -200), new Vector2(200, 200), new Vector2(100, 100), Vector3.UnitY); var color = GenericMaterial.FromMedia("checked.png", "183_norm.JPG"); Mesh3d water = new Mesh3d(waterInfo, color); water.SetMass(0); water.Translate(0, -10, 0); water.SetCollisionShape(new BulletSharp.StaticPlaneShape(Vector3.UnitY, 0)); World.Root.Add(water); var lod1 = Object3dInfo.LoadFromRaw(Media.Get("lucy_lod1.vbo.raw"), Media.Get("lucy_lod1.indices.raw")); var mat = new GenericMaterial(new Vector4(0, 0, 1, 1f)); var dragon = new Mesh3d(lod1, mat); dragon.Transformation.Scale(2); Add(dragon); var rand = new Random(); var grasslod0 = Object3dInfo.LoadFromObjSingle(Media.Get("grasslod1.obj")); var grasslod1 = Object3dInfo.LoadFromObjSingle(Media.Get("grasslod1.obj")); var grasslod2 = Object3dInfo.LoadFromObjSingle(Media.Get("grasslod2.obj")); var grasslod3 = Object3dInfo.LoadFromObjSingle(Media.Get("grasslod3.obj")); var grasscolor = new GenericMaterial(Color.DarkGreen); var grassInstanced = new InstancedMesh3d(grasslod2, grasscolor); for(int x = -15; x < 15; x++) { for(int y = -15; y < 15; y++) { grassInstanced.Transformations.Add(new TransformationManager(new Vector3(x, 0, y), Quaternion.FromAxisAngle(Vector3.UnitY, (float)rand.NextDouble() * MathHelper.Pi), new Vector3(1, 1, 1))); grassInstanced.Instances++; } } grassInstanced.UpdateMatrix(); Add(grassInstanced); ProjectionLight redConeLight = new ProjectionLight(new Vector3(1, 25, 1), Quaternion.Identity, 5000, 5000, MathHelper.PiOver2, 1.0f, 10000.0f); redConeLight.LightColor = new Vector4(1, 1, 1, 1); redConeLight.BuildOrthographicProjection(500, 500, -100, 100); redConeLight.camera.LookAt(Vector3.Zero); LightPool.Add(redConeLight); var wheel3dInfo = Object3dInfo.LoadFromObjSingle(Media.Get("fcarwheel.obj")); var car3dInfo = Object3dInfo.LoadFromObjSingle(Media.Get("fcarbody.obj")); var car = new Mesh3d(car3dInfo, new GenericMaterial(Color.LightGreen)); car.SetMass(200); //car.Translate(0, 3.76f, 0); car.SetCollisionShape(new BoxShape(0.5f, 0.5f, 0.5f)); car.CreateRigidBody(new Vector3(0, -25, 0), true); car.PhysicalBody.SetSleepingThresholds(0, 0); car.PhysicalBody.ContactProcessingThreshold = 0; car.PhysicalBody.CcdMotionThreshold = 0; CurrentCar = car; World.Root.Add(car); GLThread.OnUpdate += (o, e) => { redConeLight.SetPosition(car.GetPosition() + new Vector3(0, 15, 0)); }; var shape = new SphereShape(0.5f); //var shape = wheel3dInfo.GetAccurateCollisionShape(); var wheelLF = new Mesh3d(wheel3dInfo, new GenericMaterial(Color.White)); wheelLF.SetMass(100); wheelLF.Translate(1.640539f, 0.48866f, -1.94906f); wheelLF.SetCollisionShape(shape); wheelLF.CreateRigidBody(); World.Root.Add(wheelLF); var wheelRF = new Mesh3d(wheel3dInfo, new GenericMaterial(Color.White)); wheelRF.SetMass(100); wheelRF.Translate(1.640539f, 0.48866f, 1.94906f); wheelRF.SetCollisionShape(shape); wheelRF.CreateRigidBody(); World.Root.Add(wheelRF); var wheelLR = new Mesh3d(wheel3dInfo, new GenericMaterial(Color.White)); wheelLR.SetMass(100); wheelLR.Translate(-1.640539f, 0.48866f, -1.94906f); wheelLR.SetCollisionShape(shape); wheelLR.CreateRigidBody(); World.Root.Add(wheelLR); var wheelRR = new Mesh3d(wheel3dInfo, new GenericMaterial(Color.White)); wheelRR.SetMass(100); wheelRR.Translate(-1.640539f, 0.48866f, 1.94906f); wheelRR.SetCollisionShape(shape); wheelRR.CreateRigidBody(); World.Root.Add(wheelRR); wheelLF.PhysicalBody.SetSleepingThresholds(0, 0); wheelLF.PhysicalBody.ContactProcessingThreshold = 0; wheelLF.PhysicalBody.CcdMotionThreshold = 0; wheelRF.PhysicalBody.SetSleepingThresholds(0, 0); wheelRF.PhysicalBody.ContactProcessingThreshold = 0; wheelRF.PhysicalBody.CcdMotionThreshold = 0; wheelLR.PhysicalBody.SetSleepingThresholds(0, 0); wheelLR.PhysicalBody.ContactProcessingThreshold = 0; wheelLR.PhysicalBody.CcdMotionThreshold = 0; wheelLR.PhysicalBody.SetSleepingThresholds(0, 0); wheelLR.PhysicalBody.ContactProcessingThreshold = 0; wheelLR.PhysicalBody.CcdMotionThreshold = 0; wheelRR.PhysicalBody.SetSleepingThresholds(0, 0); wheelRR.PhysicalBody.ContactProcessingThreshold = 0; wheelRR.PhysicalBody.CcdMotionThreshold = 0; wheelLF.PhysicalBody.Friction = 1200; wheelRF.PhysicalBody.Friction = 1200; wheelLR.PhysicalBody.Friction = 1200; wheelRR.PhysicalBody.Friction = 1200; car.PhysicalBody.SetIgnoreCollisionCheck(wheelLF.PhysicalBody, true); car.PhysicalBody.SetIgnoreCollisionCheck(wheelRF.PhysicalBody, true); car.PhysicalBody.SetIgnoreCollisionCheck(wheelLR.PhysicalBody, true); car.PhysicalBody.SetIgnoreCollisionCheck(wheelRR.PhysicalBody, true); // location left rear x -5.27709 y 1.56474 z -3.13906 // location right rear x -5.27709 y 1.56474 z 3.13906 // location left front x 5.500539 y 1.56474 z -3.13906 // location right front x 5.500539 y 1.56474 z 3.13906 //public HingeConstraint(RigidBody rigidBodyA, RigidBody rigidBodyB, Vector3 pivotInA, Vector3 pivotInB, Vector3 axisInA, Vector3 axisInB); var frontAxis = new HingeConstraint(wheelLF.PhysicalBody, wheelRF.PhysicalBody, new Vector3(1.640539f, 0.48866f, 1.94906f), new Vector3(1.640539f, 0.48866f, -1.94906f), Vector3.UnitZ, Vector3.UnitZ); var rearAxis = new HingeConstraint(wheelLR.PhysicalBody, wheelRR.PhysicalBody, new Vector3(-1.640539f, 0.48866f, 1.94906f), new Vector3(-1.640539f, 0.48866f, -1.94906f), Vector3.UnitZ, Vector3.UnitZ); var centerAxis1 = new HingeConstraint(car.PhysicalBody, wheelLF.PhysicalBody, new Vector3(1.640539f, -0.48866f, -1.94906f), new Vector3(0), Vector3.UnitZ, Vector3.UnitZ); var centerAxis2 = new HingeConstraint(car.PhysicalBody, wheelRF.PhysicalBody, new Vector3(1.640539f, -0.48866f, 1.94906f), new Vector3(0), Vector3.UnitZ, Vector3.UnitZ); var centerAxis3 = new HingeConstraint(car.PhysicalBody, wheelLR.PhysicalBody, new Vector3(-1.640539f, -0.48866f, 1.94906f), new Vector3(0), Vector3.UnitZ, Vector3.UnitZ); var centerAxis4 = new HingeConstraint(car.PhysicalBody, wheelRR.PhysicalBody, new Vector3(-1.640539f, -0.48866f, -1.94906f), new Vector3(0), Vector3.UnitZ, Vector3.UnitZ); centerAxis1.SetLimit(0, 10, 0, 0, 0); centerAxis2.SetLimit(0, 10, 0, 0, 0); centerAxis3.SetLimit(0, 10, 0, 0, 0); centerAxis4.SetLimit(0, 10, 0, 0, 0); //World.Root.PhysicalWorld.AddConstraint(frontAxis); // World.Root.PhysicalWorld.AddConstraint(rearAxis); // centerAxis1.SetLimit(0, 0.01f); // centerAxis2.SetLimit(0, 0.01f); //centerAxis3.SetLimit(0, 0.01f); //centerAxis4.SetLimit(0, 0.01f); World.Root.PhysicalWorld.AddConstraint(centerAxis1); World.Root.PhysicalWorld.AddConstraint(centerAxis2); World.Root.PhysicalWorld.AddConstraint(centerAxis3); World.Root.PhysicalWorld.AddConstraint(centerAxis4); GLThread.OnKeyDown += (object sender, OpenTK.Input.KeyboardKeyEventArgs e) => { if(e.Key == OpenTK.Input.Key.R) { car.SetOrientation(Quaternion.Identity); } if(e.Key == OpenTK.Input.Key.Space) { centerAxis1.EnableMotor = false; centerAxis2.EnableMotor = false; } if(e.Key == OpenTK.Input.Key.Up) { centerAxis1.EnableMotor = true; centerAxis1.EnableAngularMotor(true, -100.0f, 10.0f); centerAxis2.EnableMotor = true; centerAxis2.EnableAngularMotor(true, -100.0f, 10.0f); } if(e.Key == OpenTK.Input.Key.Down) { centerAxis1.EnableMotor = true; centerAxis1.EnableAngularMotor(true, 100.0f, 6.0f); centerAxis2.EnableMotor = true; centerAxis2.EnableAngularMotor(true, 100.0f, 6.0f); } if(e.Key == OpenTK.Input.Key.Left) { float angle = 0.6f / (car.PhysicalBody.LinearVelocity.Length + 1.0f); centerAxis3.SetFrames(Matrix4.CreateRotationY(angle) * Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, 1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); centerAxis4.SetFrames(Matrix4.CreateRotationY(angle) * Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, -1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); //centerAxis3.SetAxis(new Vector3(1, 0, 1)); //centerAxis4.SetAxis(new Vector3(1, 0, 1)); } if(e.Key == OpenTK.Input.Key.Right) { float angle = 0.6f / (car.PhysicalBody.LinearVelocity.Length + 1.0f); centerAxis3.SetFrames(Matrix4.CreateRotationY(-angle) * Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, 1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); centerAxis4.SetFrames(Matrix4.CreateRotationY(-angle) * Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, -1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); //centerAxis3.SetAxis(new Vector3(-1, 0, 1)); //centerAxis4.SetAxis(new Vector3(-1, 0, 1)); } }; GLThread.OnKeyUp += (object sender, OpenTK.Input.KeyboardKeyEventArgs e) => { if(e.Key == OpenTK.Input.Key.Up) { centerAxis1.EnableMotor = false; centerAxis2.EnableMotor = false; } if(e.Key == OpenTK.Input.Key.Down) { centerAxis1.EnableMotor = false; centerAxis2.EnableMotor = false; } if(e.Key == OpenTK.Input.Key.Left) { centerAxis3.SetFrames(Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, 1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); centerAxis4.SetFrames(Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, -1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); //centerAxis3.SetAxis(new Vector3(0, 0, 1)); //centerAxis4.SetAxis(new Vector3(0, 0, 1)); } if(e.Key == OpenTK.Input.Key.Right) { centerAxis3.SetFrames( Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, 1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); centerAxis4.SetFrames(Matrix4.CreateTranslation(new Vector3(-1.640539f, -0.48866f, -1.94906f)), Matrix4.CreateTranslation(new Vector3(0))); //centerAxis3.SetAxis(new Vector3(0, 0, 1)); //centerAxis4.SetAxis(new Vector3(0, 0, 1)); } }; }
public CollisionShape CreateSphereShape(float radius) { SphereShape shape = new SphereShape(radius); _allocatedCollisionShapes.Add(shape); return shape; }
protected override CollisionShape CreateShape() { CollisionShape shape = new SphereShape(this.radius); //shape.CalculateLocalInertia(this.Mass); return shape; }
public Character(uint id) : base(id) { Sphere.Margin = COLLISION_MARGIN_DEFAULT; ClimbSensor = new SphereShape(ClimbR); ClimbSensor.Margin = COLLISION_MARGIN_DEFAULT; RayCb = new BtEngineClosestRayResultCallback(Self, true); RayCb.CollisionFilterMask = (short) (CollisionFilterGroups.StaticFilter | CollisionFilterGroups.KinematicFilter); HeightInfo.Cb = RayCb; ConvexCb = new BtEngineClosestConvexResultCallback(Self, true); ConvexCb.CollisionFilterMask = (short) (CollisionFilterGroups.StaticFilter | CollisionFilterGroups.KinematicFilter); HeightInfo.Ccb = ConvexCb; DirFlag = ENT_MOVE.Stay; }
protected override void OnInitializePhysics() { // collision configuration contains default setup for memory, collision setup DefaultCollisionConstructionInfo cci = new DefaultCollisionConstructionInfo(); cci.DefaultMaxPersistentManifoldPoolSize = 32768; CollisionConf = new DefaultCollisionConfiguration(cci); Dispatcher = new CollisionDispatcher(CollisionConf); Dispatcher.DispatcherFlags = DispatcherFlags.DisableContactPoolDynamicAllocation; // the maximum size of the collision world. Make sure objects stay within these boundaries // Don't make the world AABB size too large, it will harm simulation quality and performance Vector3 worldAabbMin = new Vector3(-1000, -1000, -1000); Vector3 worldAabbMax = new Vector3(1000, 1000, 1000); HashedOverlappingPairCache pairCache = new HashedOverlappingPairCache(); Broadphase = new AxisSweep3(worldAabbMin, worldAabbMax, 3500, pairCache); //Broadphase = new DbvtBroadphase(); Solver = new SequentialImpulseConstraintSolver(); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf); World.Gravity = new Vector3(0, -10, 0); World.SolverInfo.SolverMode |= SolverModes.EnableFrictionDirectionCaching; World.SolverInfo.NumIterations = 5; if (benchmark < 5) { // create the ground CollisionShape groundShape = new BoxShape(250, 50, 250); CollisionShapes.Add(groundShape); CollisionObject ground = base.LocalCreateRigidBody(0, Matrix.Translation(0, -50, 0), groundShape); ground.UserObject = "Ground"; } float cubeSize = 1.0f; float spacing = cubeSize; float mass = 1.0f; int size = 8; Vector3 pos = new Vector3(0.0f, cubeSize * 2, 0.0f); float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; switch (benchmark) { case 1: // 3000 BoxShape blockShape = new BoxShape(cubeSize - collisionRadius); mass = 2.0f; for (int k = 0; k < 47; k++) { for (int j = 0; j < size; j++) { pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing); for (int i = 0; i < size; i++) { pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing); RigidBody cmbody = LocalCreateRigidBody(mass, Matrix.Translation(pos), blockShape); } } offset -= 0.05f * spacing * (size - 1); // spacing *= 1.01f; pos[1] += (cubeSize * 2.0f + spacing); } break; case 2: CreatePyramid(new Vector3(-20, 0, 0), 12, new Vector3(cubeSize)); CreateWall(new Vector3(-2.0f, 0.0f, 0.0f), 12, new Vector3(cubeSize)); CreateWall(new Vector3(4.0f, 0.0f, 0.0f), 12, new Vector3(cubeSize)); CreateWall(new Vector3(10.0f, 0.0f, 0.0f), 12, new Vector3(cubeSize)); CreateTowerCircle(new Vector3(25.0f, 0.0f, 0.0f), 8, 24, new Vector3(cubeSize)); break; case 3: // TODO: Ragdolls break; case 4: cubeSize = 1.5f; ConvexHullShape convexHullShape = new ConvexHullShape(); float scaling = 1; convexHullShape.LocalScaling = new Vector3(scaling); for (int i = 0; i < Taru.Vtx.Length / 3; i++) { Vector3 vtx = new Vector3(Taru.Vtx[i * 3], Taru.Vtx[i * 3 + 1], Taru.Vtx[i * 3 + 2]); convexHullShape.AddPoint(vtx * (1.0f / scaling)); } //this will enable polyhedral contact clipping, better quality, slightly slower convexHullShape.InitializePolyhedralFeatures(); for (int k = 0; k < 15; k++) { for (int j = 0; j < size; j++) { pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing); for (int i = 0; i < size; i++) { pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing); LocalCreateRigidBody(mass, Matrix.Translation(pos), convexHullShape); } } offset -= 0.05f * spacing * (size - 1); spacing *= 1.01f; pos[1] += (cubeSize * 2.0f + spacing); } break; case 5: Vector3 boxSize = new Vector3(1.5f); float boxMass = 1.0f; float sphereRadius = 1.5f; float sphereMass = 1.0f; float capsuleHalf = 2.0f; float capsuleRadius = 1.0f; float capsuleMass = 1.0f; size = 10; int height = 10; cubeSize = boxSize[0]; spacing = 2.0f; pos = new Vector3(0.0f, 20.0f, 0.0f); offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; int numBodies = 0; Random random = new Random(); for (int k = 0; k < height; k++) { for (int j = 0; j < size; j++) { pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing); for (int i = 0; i < size; i++) { pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing); Vector3 bpos = new Vector3(0, 25, 0) + new Vector3(5.0f * pos.X, pos.Y, 5.0f * pos.Z); int idx = random.Next(10); Matrix trans = Matrix.Translation(bpos); switch (idx) { case 0: case 1: case 2: { float r = 0.5f * (idx + 1); BoxShape boxShape = new BoxShape(boxSize * r); LocalCreateRigidBody(boxMass * r, trans, boxShape); } break; case 3: case 4: case 5: { float r = 0.5f * (idx - 3 + 1); SphereShape sphereShape = new SphereShape(sphereRadius * r); LocalCreateRigidBody(sphereMass * r, trans, sphereShape); } break; case 6: case 7: case 8: { float r = 0.5f * (idx - 6 + 1); CapsuleShape capsuleShape = new CapsuleShape(capsuleRadius * r, capsuleHalf * r); LocalCreateRigidBody(capsuleMass * r, trans, capsuleShape); } break; } numBodies++; } } offset -= 0.05f * spacing * (size - 1); spacing *= 1.1f; pos[1] += (cubeSize * 2.0f + spacing); } //CreateLargeMeshBody(); break; case 6: boxSize = new Vector3(1.5f, 1.5f, 1.5f); convexHullShape = new ConvexHullShape(); for (int i = 0; i < Taru.Vtx.Length / 3; i++) { Vector3 vtx = new Vector3(Taru.Vtx[i * 3], Taru.Vtx[i * 3 + 1], Taru.Vtx[i * 3 + 2]); convexHullShape.AddPoint(vtx); } size = 10; height = 10; cubeSize = boxSize[0]; spacing = 2.0f; pos = new Vector3(0.0f, 20.0f, 0.0f); offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; for (int k = 0; k < height; k++) { for (int j = 0; j < size; j++) { pos[2] = offset + (float)j * (cubeSize * 2.0f + spacing); for (int i = 0; i < size; i++) { pos[0] = offset + (float)i * (cubeSize * 2.0f + spacing); Vector3 bpos = new Vector3(0, 25, 0) + new Vector3(5.0f * pos.X, pos.Y, 5.0f * pos.Z); LocalCreateRigidBody(mass, Matrix.Translation(bpos), convexHullShape); } } offset -= 0.05f * spacing * (size - 1); spacing *= 1.1f; pos[1] += (cubeSize * 2.0f + spacing); } //CreateLargeMeshBody(); break; case 7: // TODO //CreateTest6(); //InitRays(); break; } }
public override void OnHandleInput() { Matrix xform = ghostObject.WorldTransform; Vector3 forwardDir = new Vector3(xform.M31, xform.M32, xform.M33); //Console.Write("forwardDir={0},{1},{2}\n", forwardDir[0], forwardDir[1], forwardDir[2]); Vector3 upDir = new Vector3(xform.M21, xform.M22, xform.M23); forwardDir.Normalize(); upDir.Normalize(); Vector3 pos = xform.Origin; Vector3 walkDirection = Vector3.Zero; const float walkVelocity = 1.1f * 4.0f; float walkSpeed = walkVelocity * FrameDelta * 10;// * 0.0001f; float turnSpeed = FrameDelta * 3; if (Input.KeysDown.Contains(Keys.Left)) { Matrix orn = xform; orn.set_Rows(3, new Vector4(0, 0, 0, 1)); orn *= Matrix.RotationAxis(upDir, -turnSpeed); orn.set_Rows(3, new Vector4(pos.X, pos.Y, pos.Z, 1)); ghostObject.WorldTransform = orn; } if (Input.KeysDown.Contains(Keys.Right)) { Matrix orn = xform; orn.set_Rows(3, new Vector4(0, 0, 0, 1)); orn *= Matrix.RotationAxis(upDir, turnSpeed); orn.set_Rows(3, new Vector4(pos.X, pos.Y, pos.Z, 1)); ghostObject.WorldTransform = orn; } if (Input.KeysDown.Contains(Keys.Up)) { walkDirection += forwardDir; } if (Input.KeysDown.Contains(Keys.Down)) { walkDirection -= forwardDir; } Vector3 cameraPos = pos - forwardDir * 12 + upDir * 5; //use the convex sweep test to find a safe position for the camera (not blocked by static geometry) SphereShape cameraSphere = new SphereShape(0.2f); CollisionWorld.ClosestConvexResultCallback cb = new CollisionWorld.ClosestConvexResultCallback(pos, cameraPos); cb.CollisionFilterMask = CollisionFilterGroups.StaticFilter; World.ConvexSweepTest(cameraSphere, Matrix.Translation(pos), Matrix.Translation(cameraPos), cb); cameraSphere.Dispose(); if (cb.HasHit) { cameraPos = Vector3.Lerp(pos, cameraPos, cb.ClosestHitFraction); } cb.Dispose(); Freelook.SetEyeTarget(cameraPos, pos); character.SetWalkDirection(walkDirection * walkSpeed); base.OnHandleInput(); }
public CollisionShape CopyCollisionShape() { SphereShape ss = new SphereShape(radius); ss.LocalScaling = m_localScaling.ToBullet(); return ss; }
public static TriggerRegion CreateSphereTriggerRegion(string name, TriggerReportEvent trh, float radius, Vector3 position) { var csm = LKernel.GetG<CollisionShapeManager>(); CollisionShape shape; if (!csm.TryGetShape(name, out shape)) { shape = new SphereShape(radius); csm.RegisterShape(name, shape); } var tr = new TriggerRegion(name, position, shape); tr.OnTrigger += trh; AddToDispose(tr, trh); return tr; }
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, -9.81f, 0); const bool floating = false; const bool gyro = false; const int numLinks = 1; const bool canSleep = false; const bool selfCollide = false; Vector3 linkHalfExtents = new Vector3(0.05f, 0.5f, 0.1f); Vector3 baseHalfExtents = new Vector3(0.05f, 0.5f, 0.1f); Vector3 baseInertiaDiag = Vector3.Zero; const float baseMass = 0; multiBody = new MultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep); //multiBody.UseRK4Integration = true; //multiBody.BaseWorldTransform = Matrix.Identity; //init the links Vector3 hingeJointAxis = new Vector3(1, 0, 0); //y-axis assumed up Vector3 parentComToCurrentCom = new Vector3(0, -linkHalfExtents[1], 0); Vector3 currentPivotToCurrentCom = new Vector3(0, -linkHalfExtents[1], 0); Vector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; for(int i = 0; i < numLinks; i++) { const float linkMass = 10; Vector3 linkInertiaDiag = Vector3.Zero; using (var shape = new SphereShape(radius)) { shape.CalculateLocalInertia(linkMass, out linkInertiaDiag); } multiBody.SetupRevolute(i, linkMass, linkInertiaDiag, i - 1, Quaternion.Identity, hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, false); } multiBody.FinalizeMultiDof(); (World as MultiBodyDynamicsWorld).AddMultiBody(multiBody); multiBody.CanSleep = canSleep; multiBody.HasSelfCollision = selfCollide; multiBody.UseGyroTerm = gyro; #if PENDULUM_DAMPING multiBody.LinearDamping = 0.1f; multiBody.AngularDamping = 0.9f; #else multiBody.LinearDamping = 0; multiBody.AngularDamping = 0; #endif for (int i = 0; i < numLinks; i++) { var shape = new SphereShape(radius); CollisionShapes.Add(shape); var col = new MultiBodyLinkCollider(multiBody, i); col.CollisionShape = shape; const bool isDynamic = true; CollisionFilterGroups collisionFilterGroup = isDynamic ? CollisionFilterGroups.DefaultFilter : CollisionFilterGroups.StaticFilter; CollisionFilterGroups collisionFilterMask = isDynamic ? CollisionFilterGroups.AllFilter : CollisionFilterGroups.AllFilter & ~CollisionFilterGroups.StaticFilter; World.AddCollisionObject(col, collisionFilterGroup, collisionFilterMask); multiBody.GetLink(i).Collider = col; } }
/* Mesh CreateMultiSphereShape(MultiSphereShape shape) { Mesh mesh = null; int i; for (i = 0; i < shape.SphereCount; i++) { Vector3 position = shape.GetSpherePosition(i); Mesh sphereMesh = Mesh.CreateSphere(device, shape.GetSphereRadius(i), 12, 12); if (i == 0) { Matrix[] transform = new Matrix[] { Matrix.Translation(position) }; mesh = Mesh.Concatenate(device, new Mesh[] { sphereMesh }, MeshFlags.Managed, transform, null); } else { Mesh multiSphereMeshNew; Matrix[] transform = new Matrix[] { Matrix.Identity, Matrix.Translation(position) }; multiSphereMeshNew = Mesh.Concatenate(device, new Mesh[] { mesh, sphereMesh }, MeshFlags.Managed, transform, null); mesh.Dispose(); mesh = multiSphereMeshNew; } sphereMesh.Dispose(); } complexShapes.Add(shape, mesh); return mesh; } */ ShapeData CreateSphereShape(SphereShape shape) { float radius = shape.Radius; int slices = (int)(radius * 10.0f); int stacks = (int)(radius * 10.0f); slices = (slices > 16) ? 16 : (slices < 3) ? 3 : slices; stacks = (stacks > 16) ? 16 : (stacks < 2) ? 2 : stacks; float hAngleStep = (float)Math.PI * 2 / slices; float vAngleStep = (float)Math.PI / stacks; ShapeData shapeData = new ShapeData(); shapeData.VertexCount = 2 + slices * (stacks - 1); shapeData.IndexCount = 6 * slices * (stacks - 1); Vector3[] vertices = new Vector3[shapeData.VertexCount * 2]; ushort[] indices = new ushort[shapeData.IndexCount]; int i = 0, v = 0; // Vertices // Top and bottom vertices[v++] = new Vector3(0, -radius, 0); vertices[v++] = -Vector3.UnitY; vertices[v++] = new Vector3(0, radius, 0); vertices[v++] = Vector3.UnitY; // Stacks int j, k; float angle = 0; float vAngle = -(float)Math.PI / 2; Vector3 vTemp; for (j = 0; j < stacks - 1; j++) { vAngle += vAngleStep; for (k = 0; k < slices; k++) { angle += hAngleStep; vTemp = new Vector3((float)Math.Cos(vAngle) * (float)Math.Sin(angle), (float)Math.Sin(vAngle), (float)Math.Cos(vAngle) * (float)Math.Cos(angle)); vertices[v++] = vTemp * radius; vertices[v++] = Vector3.Normalize(vTemp); } } // Indices // Top cap ushort index = 2; for (k = 0; k < slices; k++) { indices[i++] = index++; indices[i++] = 0; indices[i++] = index; } indices[i - 1] = 2; // Stacks //for (j = 0; j < 1; j++) int sliceDiff = slices * 3; for (j = 0; j < stacks - 2; j++) { for (k = 0; k < slices; k++) { indices[i] = indices[i - sliceDiff + 2]; indices[i + 1] = index++; indices[i + 2] = indices[i - sliceDiff]; i += 3; } for (k = 0; k < slices; k++) { indices[i] = indices[i - sliceDiff + 1]; indices[i + 1] = indices[i - sliceDiff]; indices[i + 2] = indices[i - sliceDiff + 4]; i += 3; } indices[i - 1] = indices[i - sliceDiff]; } // Bottom cap index--; for (k = 0; k < slices; k++) { indices[i++] = index--; indices[i++] = 1; indices[i++] = index; } indices[i - 1] = indices[i - sliceDiff]; shapeData.SetVertexBuffer(device, vertices); shapeData.SetIndexBuffer(device, indices); return shapeData; }
protected override void OnInitializePhysics() { // collision configuration contains default setup for memory, collision setup CollisionConf = new DefaultCollisionConfiguration(); Dispatcher = new CollisionDispatcher(CollisionConf); Broadphase = new AxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)); Solver = new SequentialImpulseConstraintSolver(); World = new DiscreteDynamicsWorld(Dispatcher, Broadphase, Solver, CollisionConf); World.DispatchInfo.AllowedCcdPenetration = 0.0001f; //World.Gravity = Freelook.Up * -10.0f; Matrix startTransform = Matrix.Translation(10.210098f, -1.6433364f, 16.453260f); ghostObject = new PairCachingGhostObject(); ghostObject.WorldTransform = startTransform; Broadphase.OverlappingPairCache.SetInternalGhostPairCallback(new GhostPairCallback()); const float characterHeight = 1.75f; const float characterWidth = 1.75f; ConvexShape capsule = new CapsuleShape(characterWidth, characterHeight); ghostObject.CollisionShape = capsule; ghostObject.CollisionFlags = CollisionFlags.CharacterObject; const float stepHeight = 0.35f; character = new KinematicCharacterController(ghostObject, capsule, stepHeight); BspLoader bspLoader = new BspLoader(); bspLoader.LoadBspFile("data/BspDemo.bsp"); BspConverter bsp2Bullet = new BspToBulletConverter(this); bsp2Bullet.ConvertBsp(bspLoader, 0.1f); World.AddCollisionObject(ghostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter); World.AddAction(character); convexResultCallback = new ClosestConvexResultCallback(); convexResultCallback.CollisionFilterMask = (short)CollisionFilterGroups.StaticFilter; cameraSphere = new SphereShape(0.2f); }
Mesh CreateSphere(SphereShape shape) { Mesh mesh = Mesh.CreateSphere(device, shape.Radius, 16, 16); shapes.Add(shape, mesh); return mesh; }
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; }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize // Create a axis-grid renderer var axisGrid = ToDispose(new AxisGridRenderer()); axisGrid.Initialize(this); // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("PhysicsScene1.cmo"); List <MeshRenderer> meshes = new List <MeshRenderer>(); meshes.AddRange(from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh))); foreach (var m in meshes) { m.Initialize(this); m.World = Matrix.Identity; } // Set the first animation as the current animation and start clock foreach (var m in meshes) { if (m.Mesh.Animations != null && m.Mesh.Animations.Any()) { m.CurrentAnimation = m.Mesh.Animations.First().Value; } m.Clock.Start(); } loadedMesh = Common.Mesh.LoadFromFile("SubdividedPlane.cmo"); var waterMesh = ToDispose(new MeshRenderer(loadedMesh.First())); waterMesh.Initialize(this); loadedMesh = Common.Mesh.LoadFromFile("Bataux.cmo"); List <MeshRenderer> shipMeshes = new List <MeshRenderer>(); shipMeshes.AddRange((from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh)))); foreach (var m in shipMeshes) { m.Initialize(this); m.World = Matrix.Scaling(3) * Matrix.RotationAxis(Vector3.UnitY, -1.57079f); } //var anchor = new SphereRenderer(0.05f); //anchor.Initialize(this); //var anchorWorld = Matrix.Identity; //var sphere = new SphereRenderer(); //sphere.Initialize(this); //var sphereWorld = Matrix.Identity; // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion #region Initialize physics engine CollisionConfiguration defaultConfig = new DefaultCollisionConfiguration(); ConstraintSolver solver = new SequentialImpulseConstraintSolver(); BulletSharp.Dispatcher dispatcher = new CollisionDispatcher(defaultConfig); BroadphaseInterface broadphase = new DbvtBroadphase(); DynamicsWorld world = null; Action initializePhysics = () => { RemoveAndDispose(ref world); world = ToDispose(new BulletSharp.DiscreteDynamicsWorld(dispatcher, broadphase, solver, defaultConfig)); world.Gravity = new Vector3(0, -10, 0); // For each mesh, create a RigidBody and add to "world" for simulation meshes.ForEach(m => { // We use the name of the mesh to determine the correct body if (String.IsNullOrEmpty(m.Mesh.Name)) { return; } var name = m.Mesh.Name.ToLower(); var extent = m.Mesh.Extent; BulletSharp.CollisionShape shape; #region Create collision shape if (name.Contains("box") || name.Contains("cube")) { // Assumes the box/cube has an axis-aligned neutral orientation shape = new BulletSharp.BoxShape( Math.Abs(extent.Max.Z - extent.Min.Z) / 2.0f, Math.Abs(extent.Max.Y - extent.Min.Y) / 2.0f, Math.Abs(extent.Max.X - extent.Min.X) / 2.0f); } else if (name.Contains("sphere")) { shape = new BulletSharp.SphereShape(extent.Radius); } else // use mesh vertices directly { // for each SubMesh, retrieve the vertex and index buffers // to create a TriangleMeshShape for collision detection. List <Vector3> vertices = new List <Vector3>(); List <int> indices = new List <int>(); int vertexOffset = 0; foreach (var sm in m.Mesh.SubMeshes) { vertexOffset += vertices.Count; indices.AddRange( (from indx in m.Mesh.IndexBuffers[(int)sm.IndexBufferIndex] select vertexOffset + (int)indx)); vertices.AddRange( (from v in m.Mesh .VertexBuffers[(int)sm.VertexBufferIndex] select v.Position - extent.Center)); } // Create the collision shape var iva = new BulletSharp.TriangleIndexVertexArray(indices.ToArray(), vertices.ToArray()); shape = new BulletSharp.BvhTriangleMeshShape(iva, true); } #endregion m.World = Matrix.Identity; // Reset mesh location float mass; Vector3 vec; shape.GetBoundingSphere(out vec, out mass); var body = new BulletSharp.RigidBody( new BulletSharp.RigidBodyConstructionInfo(name.Contains("static") ? 0 : mass, new MeshMotionState(m), shape, shape.CalculateLocalInertia(mass))); if (body.IsStaticObject) { body.Restitution = 1f; body.Friction = 0.4f; } // Add to the simulation world.AddRigidBody(body); }); #if DEBUG world.DebugDrawer = ToDispose(new PhysicsDebugDraw(this.DeviceManager)); world.DebugDrawer.DebugMode = DebugDrawModes.DrawAabb | DebugDrawModes.DrawWireframe; #endif }; initializePhysics(); // Newton's Cradle //var box = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.BoxShape(7, 1, 2)); //box.Position = new Jitter.LinearMath.JVector(0, 8, 0); //world.AddBody(box); //box.IsStatic = true; //var anchorBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.05f)); //anchorBody.Position = new Jitter.LinearMath.JVector(0, 4, 0); //world.AddBody(anchorBody); //anchorBody.IsStatic = true; //for (var bodyCount = -3; bodyCount < 4; bodyCount++) //{ // var testBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.501f)); // testBody.Position = new Jitter.LinearMath.JVector(bodyCount, 0, 0); // world.AddBody(testBody); // world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody, // testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Forward * 3f + Jitter.LinearMath.JVector.Down * 0.5f, // testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f }); // world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody, // testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Backward * 3f + Jitter.LinearMath.JVector.Down * 0.5f, // testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f }); // testBody.Material.Restitution = 1.0f; // testBody.Material.StaticFriction = 1.0f; //} #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position slightly behind (z) var cameraPosition = new Vector3(0, 1, 10); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); }; bool debugDraw = false; bool paused = false; var simTime = new System.Diagnostics.Stopwatch(); simTime.Start(); float time = 0.0f; float timeStep = 0.0f; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format("Rotation ({0}) (Up/Down Left/Right Wheel+-)\nView ({1}) (A/D, W/S, Shift+Wheel+-)" //+ "\nPress 1,2,3,4,5,6,7,8 to switch shaders" + "\nTime: {2:0.00} (P to toggle, R to reset scene)" + "\nPhysics debug draw: {3} (E to toggle)" + "\nBackspace: toggle between Physics and Waves", rotation, viewMatrix.TranslationVector, simTime.Elapsed.TotalSeconds, debugDraw); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; keyToggles[Keys.Back] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; var background = Color.White; var showNormals = false; var enableNormalMap = true; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) case Keys.Down: worldMatrix *= Matrix.RotationX(moveFactor); rotation += new Vector3(moveFactor, 0f, 0f); break; case Keys.Up: worldMatrix *= Matrix.RotationX(-moveFactor); rotation -= new Vector3(moveFactor, 0f, 0f); break; case Keys.Left: worldMatrix *= Matrix.RotationY(moveFactor); rotation += new Vector3(0f, moveFactor, 0f); break; case Keys.Right: worldMatrix *= Matrix.RotationY(-moveFactor); rotation -= new Vector3(0f, moveFactor, 0f); break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.B: if (background == Color.White) { background = new Color(30, 30, 34); } else { background = Color.White; } break; case Keys.G: axisGrid.Show = !axisGrid.Show; break; case Keys.P: paused = !paused; if (paused) { simTime.Stop(); } else { simTime.Start(); } // Pause or resume mesh animation meshes.ForEach(m => { if (m.Clock.IsRunning) { m.Clock.Stop(); } else { m.Clock.Start(); } }); updateText(); break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; case Keys.Z: keyToggles[Keys.Z] = !keyToggles[Keys.Z]; if (keyToggles[Keys.Z]) { context.PixelShader.Set(depthPixelShader); } else { context.PixelShader.Set(pixelShader); } break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; case Keys.N: if (!shiftKey) { showNormals = !showNormals; } else { enableNormalMap = !enableNormalMap; } break; case Keys.E: debugDraw = !debugDraw; break; case Keys.R: //world = new Jitter.World(new Jitter.Collision.CollisionSystemSAP()); initializePhysics(); if (simTime.IsRunning) { simTime.Restart(); } else { simTime.Reset(); } break; case Keys.D1: context.PixelShader.Set(pixelShader); break; case Keys.D2: context.PixelShader.Set(lambertShader); break; case Keys.D3: context.PixelShader.Set(phongShader); break; case Keys.D4: context.PixelShader.Set(blinnPhongShader); break; case Keys.Back: keyToggles[Keys.Back] = !keyToggles[Keys.Back]; break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); #region Render loop // Create and run the render loop RenderLoop.Run(Window, () => { // Update simulation, at 60fps if (!paused) { if ((float)simTime.Elapsed.TotalSeconds < time) { time = 0; timeStep = 0; } timeStep = ((float)simTime.Elapsed.TotalSeconds - time); time = (float)simTime.Elapsed.TotalSeconds; world.StepSimulation(timeStep, 7); // For how to choose the maxSubSteps see: // http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World } updateText(); // Start of frame: // Retrieve immediate context var context = DeviceManager.Direct3DContext; // Clear depth stencil view context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(RenderTargetView, background); // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = new Color(0.8f, 0.8f, 0.8f, 1.0f); var lightDir = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z); perFrame.CameraPosition = cameraPosition; perFrame.Time = (float)simTime.Elapsed.TotalSeconds; // Provide simulation time to shader context.UpdateSubresource(ref perFrame, perFrameBuffer); // Render each object var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); var perObject = new ConstantBuffers.PerObject(); // MESH if (!keyToggles[Keys.Back]) { meshes.ForEach((m) => { perObject.World = m.World * worldMatrix; // Provide the material constant buffer to the mesh renderer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } }); if (debugDraw) { perObject.World = Matrix.Identity; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); (world.DebugDrawer as PhysicsDebugDraw).DrawDebugWorld(world); context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); context.InputAssembler.InputLayout = vertexLayout; } } else { perObject.World = waterMesh.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); waterMesh.EnableNormalMap = enableNormalMap; waterMesh.PerMaterialBuffer = perMaterialBuffer; waterMesh.PerArmatureBuffer = perArmatureBuffer; context.VertexShader.Set(waterVertexShader); waterMesh.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); waterMesh.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } context.VertexShader.Set(vertexShader); foreach (var m in shipMeshes) { perObject.World = m.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); // Provide the material constant buffer to the mesh renderer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } } } perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); // AXIS GRID context.HullShader.Set(null); context.DomainShader.Set(null); context.GeometryShader.Set(null); using (var prevPixelShader = context.PixelShader.Get()) using (var prevVertexShader = context.VertexShader.Get()) { context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); perObject.World = worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); axisGrid.Render(); context.PixelShader.Set(prevPixelShader); context.VertexShader.Set(prevVertexShader); } // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion }
public static bool Cam_HasHit(BtEngineClosestConvexResultCallback cb, Transform cameraFrom, Transform cameraTo) { var cameraSphere = new SphereShape(COLLISION_CAMERA_SPHERE_RADIUS) { Margin = COLLISION_MARGIN_DEFAULT }; cb.ClosestHitFraction = 1.0f; cb.HitCollisionObject = null; BtEngineDynamicsWorld.ConvexSweepTest(cameraSphere, ((Matrix4)cameraFrom).ToBullet(), ((Matrix4)cameraTo).ToBullet(), cb); return cb.HasHit; }