public GcProfiling() { collectionCountState = Profiler.New(GcCollectionCountKey); gen0Count = GC.CollectionCount(0); gen1Count = GC.CollectionCount(1); gen2Count = GC.CollectionCount(2); collectionCountState.Begin(gen0Count, gen1Count, gen2Count); gcMemoryState = Profiler.New(GcMemoryKey); memoryPeak = lastFrameMemory = GC.GetTotalMemory(false); gcMemoryState.Begin(lastFrameMemory, lastFrameMemory, memoryPeak); }
internal void Simulate(float deltaTime) { if (collisionWorld == null) return; simulationArgs.DeltaTime = deltaTime; UpdatedRigidbodies = 0; OnSimulationBegin(simulationArgs); SimulationProfiler = Profiler.Begin(PhysicsProfilingKeys.SimulationProfilingKey); if (discreteDynamicsWorld != null) discreteDynamicsWorld.StepSimulation(deltaTime, MaxSubSteps, FixedTimeStep); else collisionWorld.PerformDiscreteCollisionDetection(); SimulationProfiler.End("Alive rigidbodies: {0}", UpdatedRigidbodies); OnSimulationEnd(simulationArgs); }
internal void CacheContacts() { contactsProfilingState = Profiler.Begin(PhysicsProfilingKeys.ContactsProfilingKey); var pastFrameContacts = frameContacts.Select(x => x.ContactPoint).ToList(); frameContacts.Clear(); var numManifolds = collisionWorld.Dispatcher.NumManifolds; for (var i = 0; i < numManifolds; i++) { var manifold = collisionWorld.Dispatcher.GetManifoldByIndexInternal(i); var numContacts = manifold.NumContacts; var bodyA = manifold.Body0; var bodyB = manifold.Body1; var colA = (PhysicsComponent)bodyA?.UserObject; var colB = (PhysicsComponent)bodyB?.UserObject; if (colA == null || colB == null) { continue; } if (!colA.ProcessCollisions && !colB.ProcessCollisions) { continue; } for (var y = 0; y < numContacts; y++) { var cp = manifold.GetContactPoint(y); if (cp.Distance > 0.0f) { continue; } var info = new ContactInfo { ColA = colA, ColB = colB }; //this can be recycled by bullet so its not very correct.. need to figure if it is really new.. comparing life times might help if (!manifoldToContact.TryGetValue(cp, out info.ContactPoint)) { info.ContactPoint = new ContactPoint { Collision = null }; info.NewContact = true; manifoldToContact[cp] = info.ContactPoint; } if (info.ContactPoint.LifeTime > cp.LifeTime || cp.LifeTime == 1) { RemoveContact(info.ContactPoint); //this is a new contact as well info.ContactPoint.Collision = null; info.NewContact = true; } info.ContactPoint.Valid = true; info.ContactPoint.LifeTime = cp.LifeTime; info.ContactPoint.Distance = cp.Distance; info.ContactPoint.Normal = cp.NormalWorldOnB; info.ContactPoint.PositionOnA = cp.PositionWorldOnA; info.ContactPoint.PositionOnB = cp.PositionWorldOnB; frameContacts.Add(info); pastFrameContacts.Remove(info.ContactPoint); } } foreach (var contact in pastFrameContacts) { RemoveContact(contact); } }
private void DrawFrame() { if (SlowDownDrawCalls && (UpdateTime.FrameCount & 1) == 1) // skip the draw call about one frame over two. return; try { // Initialized if (!profilingDraw.IsInitialized) { profilingDraw = Profiler.Begin(GameProfilingKeys.GameDrawFPS); } // Update profiling data profilingDraw.CheckIfEnabled(); if (!isExiting && GameSystems.IsFirstUpdateDone && !Window.IsMinimized) { drawTime.Update(totalDrawTime, lastFrameElapsedGameTime, singleFrameUpdateTime, drawRunningSlowly, true); if (drawTime.FramePerSecondUpdated) { // TODO: store some GameTime information as attributes in the Profiling using profilingDraw.SetAttribute(..) profilingDraw.Mark("Frame = {0}, Update = {1:0.000}ms, Draw = {2:0.000}ms, FPS = {3:0.00}", drawTime.FrameCount, updateTime.TimePerFrame.TotalMilliseconds, drawTime.TimePerFrame.TotalMilliseconds, drawTime.FramePerSecond); } using (Profiler.Begin(GameProfilingKeys.GameDraw)) { Draw(drawTime); } } } finally { lastFrameElapsedGameTime = TimeSpan.Zero; } }
/// <summary> /// Initializes the Physics engine using the specified flags. /// </summary> /// <param name="flags">The flags.</param> /// <exception cref="System.NotImplementedException">SoftBody processing is not yet available</exception> internal Simulation(PhysicsEngineFlags flags = PhysicsEngineFlags.None) { if (flags == PhysicsEngineFlags.None) { if (OnSimulationCreation != null) { flags = OnSimulationCreation(); } } simulationProfilingState = Profiler.New(SimulationProfilingKey); contactsProfilingState = Profiler.New(ContactsProfilingKey); MaxSubSteps = 1; FixedTimeStep = 1.0f / 60.0f; collisionConfiguration = new BulletSharp.DefaultCollisionConfiguration(); dispatcher = new BulletSharp.CollisionDispatcher(collisionConfiguration); broadphase = new BulletSharp.DbvtBroadphase(); //this allows characters to have proper physics behavior broadphase.OverlappingPairCache.SetInternalGhostPairCallback(new BulletSharp.GhostPairCallback()); //2D pipeline var simplex = new BulletSharp.VoronoiSimplexSolver(); var pdSolver = new BulletSharp.MinkowskiPenetrationDepthSolver(); var convexAlgo = new BulletSharp.Convex2DConvex2DAlgorithm.CreateFunc(simplex, pdSolver); dispatcher.RegisterCollisionCreateFunc(BulletSharp.BroadphaseNativeType.Convex2DShape, BulletSharp.BroadphaseNativeType.Convex2DShape, convexAlgo); //this is the ONLY one that we are actually using dispatcher.RegisterCollisionCreateFunc(BulletSharp.BroadphaseNativeType.Box2DShape, BulletSharp.BroadphaseNativeType.Convex2DShape, convexAlgo); dispatcher.RegisterCollisionCreateFunc(BulletSharp.BroadphaseNativeType.Convex2DShape, BulletSharp.BroadphaseNativeType.Box2DShape, convexAlgo); dispatcher.RegisterCollisionCreateFunc(BulletSharp.BroadphaseNativeType.Box2DShape, BulletSharp.BroadphaseNativeType.Box2DShape, new BulletSharp.Box2DBox2DCollisionAlgorithm.CreateFunc()); //~2D pipeline //default solver var solver = new BulletSharp.SequentialImpulseConstraintSolver(); if (flags.HasFlag(PhysicsEngineFlags.CollisionsOnly)) { collisionWorld = new BulletSharp.CollisionWorld(dispatcher, broadphase, collisionConfiguration); } else if (flags.HasFlag(PhysicsEngineFlags.SoftBodySupport)) { //mSoftRigidDynamicsWorld = new BulletSharp.SoftBody.SoftRigidDynamicsWorld(mDispatcher, mBroadphase, solver, mCollisionConf); //mDiscreteDynamicsWorld = mSoftRigidDynamicsWorld; //mCollisionWorld = mSoftRigidDynamicsWorld; throw new NotImplementedException("SoftBody processing is not yet available"); } else { discreteDynamicsWorld = new BulletSharp.DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); collisionWorld = discreteDynamicsWorld; } if (discreteDynamicsWorld != null) { solverInfo = discreteDynamicsWorld.SolverInfo; //we are required to keep this reference, or the GC will mess up dispatchInfo = discreteDynamicsWorld.DispatchInfo; solverInfo.SolverMode |= BulletSharp.SolverModes.CacheFriendly; //todo test if helps with performance or not if (flags.HasFlag(PhysicsEngineFlags.ContinuosCollisionDetection)) { canCcd = true; solverInfo.SolverMode |= BulletSharp.SolverModes.Use2FrictionDirections | BulletSharp.SolverModes.RandomizeOrder; dispatchInfo.UseContinuous = true; } } }