public static ContentArchive GetDemosContentArchive() { using (var stream = typeof(Demos.Demos.FountainStressTestDemo).Assembly.GetManifestResourceStream("Demos.Demos.contentarchive")) { return(ContentArchive.Load(stream)); } }
public Renderer(RenderSurface surface) { Surface = surface; ContentArchive content; using (var stream = GetType().Assembly.GetManifestResourceStream("DemoRenderer.DemoRenderer.contentarchive")) { content = ContentArchive.Load(stream); } Shapes = new ShapesExtractor(looper, pool); SphereRenderer = new RayTracedRenderer <SphereInstance>(content, @"ShapeDrawing\RenderSpheres"); CapsuleRenderer = new RayTracedRenderer <CapsuleInstance>(content, @"ShapeDrawing\RenderCapsules"); CylinderRenderer = new RayTracedRenderer <CylinderInstance>(content, @"ShapeDrawing\RenderCylinders"); BoxRenderer = new BoxRenderer(content); TriangleRenderer = new TriangleRenderer(content); MeshRenderer = new MeshRenderer(Shapes.MeshCache, content); Lines = new LineExtractor(pool, looper); LineRenderer = new LineRenderer(content); Background = new BackgroundRenderer(content); CompressToSwap = new CompressToSwap(content); ImageRenderer = new ImageRenderer(content); ImageBatcher = new ImageBatcher(pool); GlyphRenderer = new GlyphRenderer(content); TextBatcher = new TextBatcher(); UILineRenderer = new UILineRenderer(content); UILineBatcher = new UILineBatcher(); OnResize(); }
private static void ListArchive(ArchiveGenerationParameters parameters) { var filename = parameters.ListInput; if (!Path.HasExtension(filename)) { filename = Path.ChangeExtension(filename, "uvarc"); } try { var archive = ContentArchive.FromArchiveFile(() => File.OpenRead(filename)); foreach (var node in archive) { ListArchive(node, 0); } } catch (FileNotFoundException) { Console.WriteLine("File not found."); } catch (DirectoryNotFoundException) { Console.WriteLine("File not found."); } }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 7, 20); camera.Yaw = 0; camera.Pitch = 0; //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); Simulation.Statics.Add(new StaticDescription(new Vector3(), new CollidableDescription(Simulation.Shapes.Add(new Box(100, 1, 100)), 0.1f))); var random = new Random(5); var shapeToDrop = new Box(1, 1, 1); shapeToDrop.ComputeInertia(1, out var shapeToDropInertia); var descriptionToDrop = BodyDescription.CreateDynamic(new Vector3(), shapeToDropInertia, new CollidableDescription(Simulation.Shapes.Add(shapeToDrop), 0.3f), new BodyActivityDescription(0.01f)); for (int i = 0; i < 128; ++i) { descriptionToDrop.Pose.Position = new Vector3(-5 + 10 * (float)random.NextDouble(), 45 + 150 * (float)random.NextDouble(), -5 + 10 * (float)random.NextDouble()); Simulation.Bodies.Add(descriptionToDrop); } //Add in a static object to test against. Note that the mesh triangles are one sided, so some of the queries whose centers are beneath the mesh do not generate any contacts. DemoMeshHelper.CreateDeformedPlane(20, 20, (x, y) => { return(new Vector3(x * 5 - 50, 3 * MathF.Sin(x) * MathF.Sin(y), y * 5 - 50)); }, Vector3.One, BufferPool, out var mesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 0, 0), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f))); }
public override void InitializeRendering(ContentArchive content, Camera camera) { foreach (var o in Objects) { o.InitializeRendering(content, camera); } }
private static void Main() { if (!false) // Run in the background { using (var simulation = new WalkerDemo()) { var start = System.DateTime.UtcNow; simulation.RunPhysics(canContinue: () => (System.DateTime.UtcNow - start).TotalSeconds < -5); // Run for a few secs } } ContentArchive content; using (var stream = typeof(Demos.DemoHarness).Assembly.GetManifestResourceStream("Demos.Demos.contentarchive")) { content = ContentArchive.Load(stream); } using (var window = new DemoEngine.Window("SharpNeat Walker", new Int2((int)(DisplayDevice.Default.Width * 0.75f), (int)(DisplayDevice.Default.Height * 0.75f)), WindowMode.Windowed)) using (var loop = new GameLoop(window)) { var harness = new DemoHarness(loop, content, customDemoSet: new DemoSet().AddOption <WalkerDemo>()); loop.Run(harness); } /*var loop = new GameLoop(window); * var demo = new DemoHarness(loop, content, customDemoSet: new DemoSet().AddOption<Walker>()); * loop.Run(demo); * loop.Dispose();*/ }
static Dictionary <int, MotionState> ExecuteSimulation(ContentArchive content, int frameCount) { var demo = new T(); demo.Initialize(content, new DemoRenderer.Camera(1, 1, 1, 1)); Console.Write("Completed frames: "); for (int i = 0; i < frameCount; ++i) { demo.Update(null, null, null, 1 / 60f); if ((i + 1) % 32 == 0) { Console.Write($"{i + 1}, "); } } var motionStates = new Dictionary <int, MotionState>(); for (int setIndex = 0; setIndex < demo.Simulation.Bodies.Sets.Length; ++setIndex) { ref var set = ref demo.Simulation.Bodies.Sets[setIndex]; if (set.Allocated) { for (int bodyIndex = 0; bodyIndex < set.Count; ++bodyIndex) { motionStates.Add(set.IndexToHandle[bodyIndex].Value, new MotionState { Pose = set.Poses[bodyIndex], Velocity = set.Velocities[bodyIndex] }); } } }
static long ExecuteSimulation(ContentArchive content, int frameCount) { var demo = new T(); demo.Initialize(content, new DemoRenderer.Camera(1, 1, 1, 1)); Console.Write("Completed frames: "); for (int i = 0; i < frameCount; ++i) { demo.Update(null, null, null, 1 / 60f); if ((i + 1) % 32 == 0) { Console.Write($"{i + 1}, "); } } long hash = 0; for (int setIndex = 0; setIndex < demo.Simulation.Bodies.Sets.Length; ++setIndex) { ref var set = ref demo.Simulation.Bodies.Sets[setIndex]; if (set.Allocated) { for (int bodyIndex = 0; bodyIndex < set.Count; ++bodyIndex) { ref var pose = ref set.Poses[bodyIndex]; ref var velocity = ref set.Velocities[bodyIndex]; var poseHash = ComputeHash(ref pose.Position, 89) + ComputeHash(ref pose.Orientation.X, 107) + ComputeHash(ref pose.Orientation.Y, 113) + ComputeHash(ref pose.Orientation.Z, 131) + ComputeHash(ref pose.Orientation.W, 149); var velocityHash = ComputeHash(ref velocity.Linear, 211) + ComputeHash(ref velocity.Angular, 397); hash += set.IndexToHandle[bodyIndex] * (poseHash + velocityHash); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 10, 40); camera.Yaw = 0; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var box = new Box(2f, 2f, 2f); var capsule = new Capsule(1f, 1f); var sphere = new Sphere(1.5f); box.ComputeInertia(1, out var boxInertia); capsule.ComputeInertia(1, out var capsuleInertia); sphere.ComputeInertia(1, out var sphereInertia); var boxIndex = Simulation.Shapes.Add(box); var capsuleIndex = Simulation.Shapes.Add(capsule); var sphereIndex = Simulation.Shapes.Add(sphere); const int width = 12; const int height = 3; const int length = 12; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { for (int k = 0; k < length; ++k) { var location = new Vector3(5, 5, 5) * new Vector3(i, j, k) + new Vector3(-width * 2.5f, 2.5f, -length * 2.5f); //CreateKinematic is just a helper function that sets the inertia to all zeroes. We'll set the inertia to the actual value in the following switch. var bodyDescription = BodyDescription.CreateKinematic(location, new CollidableDescription(default, 0.1f), new BodyActivityDescription(0.1f));
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-70, 8, 318); camera.Yaw = MathHelper.Pi * 1f / 4; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out var boxInertia); var boxIndex = Simulation.Shapes.Add(boxShape); const int pyramidCount = 120; for (int pyramidIndex = 0; pyramidIndex < pyramidCount; ++pyramidIndex) { const int rowCount = 20; for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { int columnCount = rowCount - rowIndex; for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3( (-columnCount * 0.5f + columnIndex) * boxShape.Width, (rowIndex + 0.5f) * boxShape.Height, (pyramidIndex - pyramidCount * 0.5f) * (boxShape.Length + 4)), boxInertia, new CollidableDescription(boxIndex, 0.1f), new BodyActivityDescription(0.01f))); } } } Simulation.Statics.Add(new StaticDescription(new Vector3(0, -0.5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(2500, 1, 2500)), 0.1f))); }
public static Dictionary <string, ContentElement> Load(Stream stream) { using (var reader = new BinaryReader(stream)) { try { var cache = new Dictionary <string, ContentElement>(); var contentCount = reader.ReadInt32(); for (int i = 0; i < contentCount; ++i) { var path = reader.ReadString(); var lastModifiedTimestamp = reader.ReadInt64(); var contentType = (ContentType)reader.ReadInt32(); var content = ContentArchive.Load(contentType, reader); cache.Add(path, new ContentElement { LastModifiedTimestamp = lastModifiedTimestamp, Content = content }); } return(cache); } catch (Exception e) { Console.WriteLine($"Content build cache load failed; may be corrupted. Assuming fresh build. Message:"); Console.WriteLine(e.Message); return(new Dictionary <string, ContentElement>()); } } }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 7, 20); camera.Yaw = 0; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); Simulation.Statics.Add(new StaticDescription(new Vector3(), new CollidableDescription(Simulation.Shapes.Add(new Box(100, 1, 100)), 0.1f))); var random = new Random(5); var shapeToDrop = new Box(1, 1, 1); shapeToDrop.ComputeInertia(1, out var shapeToDropInertia); var descriptionToDrop = BodyDescription.CreateDynamic(new Vector3(), shapeToDropInertia, new CollidableDescription(Simulation.Shapes.Add(shapeToDrop), 0.3f), new BodyActivityDescription(0.01f)); for (int i = 0; i < 128; ++i) { descriptionToDrop.Pose.Position = new Vector3(-5 + 10 * (float)random.NextDouble(), 45 + 150 * (float)random.NextDouble(), -5 + 10 * (float)random.NextDouble()); Simulation.Bodies.Add(descriptionToDrop); } //Add in a static object to test against. Note that the mesh triangles are one sided, so some of the queries whose centers are beneath the mesh do not generate any contacts. DemoMeshHelper.CreateDeformedPlane(20, 20, (x, y) => { return(new Vector3(x * 5 - 50, 3 * MathF.Sin(x) * MathF.Sin(y), y * 5 - 50)); }, Vector3.One, BufferPool, out var mesh); Simulation.Statics.Add(new StaticDescription(new Vector3(0, 0, 0), new CollidableDescription(Simulation.Shapes.Add(mesh), 0.1f))); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-30, 8, -60); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0; _bodyProperties = new BodyProperty <BodyProperty>(BufferPool); _events = new CollisionEvents <CollisionEventHandler>(new CollisionEventHandler(), BufferPool, ThreadDispatcher); _events.EventHandler.Pairs = new QuickList <CollidablePair>(128, BufferPool); _events.EventHandler.Simulation = Simulation; _collisionGroups = new FeeSimNarrowPhaseCallbacks <CollisionEventHandler> { Events = _events, CollisionGroups = _bodyProperties }; Simulation = Simulation.Create(BufferPool, _collisionGroups, new DefaultPoseIntegratorCallbacks(BufferPool), timestepper: new CustomPositionLastTimestepper()); var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out _boxInertia); _boxIndex = Simulation.Shapes.Add(boxShape); CreateFloors(); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-13f, 6, -13f); camera.Yaw = MathF.PI * 3f / 4; camera.Pitch = MathF.PI * 0.05f; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); { var shapeA = new Cylinder(0.5f, 1f); var poseA = new RigidPose(new Vector3(0, 0, 0)); var shapeB = new Cylinder(1f, 2f); //var positionB = new Vector3(-0.2570486f, 1.780561f, -1.033215f); //var localOrientationBMatrix = new Matrix3x3 //{ // X = new Vector3(0.9756086f, 0.1946615f, 0.101463f), // Y = new Vector3(-0.1539477f, 0.9362175f, -0.3159063f), // Z = new Vector3(-0.1564862f, 0.2925809f, 0.9433496f) //}; //var positionB = new Vector3(-1.437585f, 0.386236f, -1.124907f); var positionB = new Vector3(-0.437585f, 0.386236f, -.124907f); var localOrientationBMatrix = new Matrix3x3 { X = new Vector3(-0.7615921f, 0.001486331f, -0.648055f), Y = new Vector3(0.6341797f, 0.2075436f, -0.7448099f), Z = new Vector3(-0.1333926f, -0.9782246f, -0.1590062f) }; //var poseB = new RigidPose(new Vector3(-0.2570486f, 1.780561f, -1.033215f), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3(1, 1, 1)), MathF.PI * 0.35f)); var poseB = new RigidPose(positionB, Quaternion.CreateFromRotationMatrix(localOrientationBMatrix)); basePosition = default; shapeLines = MinkowskiShapeVisualizer.CreateLines <Cylinder, CylinderWide, CylinderSupportFinder, Cylinder, CylinderWide, CylinderSupportFinder>( shapeA, shapeB, poseA, poseB, 65536, 0.01f, new Vector3(0.4f, 0.4f, 0), 0.1f, new Vector3(0, 1, 0), default, basePosition, BufferPool);
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-10, 0, -10); camera.Yaw = MathHelper.Pi * 3f / 4; Simulation = Simulation.Create(BufferPool, new TestCallbacks()); Simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0); }
public DemoHarness(GameLoop loop, ContentArchive content, Controls?controls = null) { this.loop = loop; this.content = content; timeSamples = new SimulationTimeSamples(512, loop.Pool); if (controls == null) { this.controls = Controls.Default; } var fontContent = content.Load <FontContent>(@"Content\Carlito-Regular.ttf"); font = new Font(loop.Surface.Device, loop.Surface.Context, fontContent); timingGraph = new Graph(new GraphDescription { BodyLineColor = new Vector3(1, 1, 1), AxisLabelHeight = 16, AxisLineRadius = 0.5f, HorizontalAxisLabel = "Frames", VerticalAxisLabel = "Time (ms)", VerticalIntervalValueScale = 1e3f, VerticalIntervalLabelRounding = 2, BackgroundLineRadius = 0.125f, IntervalTextHeight = 12, IntervalTickRadius = 0.25f, IntervalTickLength = 6f, TargetHorizontalTickCount = 5, HorizontalTickTextPadding = 0, VerticalTickTextPadding = 3, LegendMinimum = new Vector2(20, 200), LegendNameHeight = 12, LegendLineLength = 7, TextColor = new Vector3(1, 1, 1), Font = font, LineSpacingMultiplier = 1f, ForceVerticalAxisMinimumToZero = true }); timingGraph.AddSeries("Total", new Vector3(1, 1, 1), 0.75f, timeSamples.Simulation); timingGraph.AddSeries("Pose Integrator", new Vector3(0, 0, 1), 0.25f, timeSamples.PoseIntegrator); timingGraph.AddSeries("Sleeper", new Vector3(0.5f, 0, 1), 0.25f, timeSamples.Sleeper); timingGraph.AddSeries("Broad Update", new Vector3(1, 1, 0), 0.25f, timeSamples.BroadPhaseUpdate); timingGraph.AddSeries("Collision Test", new Vector3(0, 1, 0), 0.25f, timeSamples.CollisionTesting); timingGraph.AddSeries("Narrow Flush", new Vector3(1, 0, 1), 0.25f, timeSamples.NarrowPhaseFlush); timingGraph.AddSeries("Solver", new Vector3(1, 0, 0), 0.5f, timeSamples.Solver); timingGraph.AddSeries("Body Opt", new Vector3(1, 0.5f, 0), 0.125f, timeSamples.BodyOptimizer); timingGraph.AddSeries("Constraint Opt", new Vector3(0, 0.5f, 1), 0.125f, timeSamples.ConstraintOptimizer); timingGraph.AddSeries("Batch Compress", new Vector3(0, 0.5f, 0), 0.125f, timeSamples.BatchCompressor); demoSet = new DemoSet(); demo = demoSet.Build(0, content, loop.Camera, loop.Surface); OnResize(loop.Window.Resolution); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(20, 10, 20); camera.Yaw = MathHelper.Pi * -1f / 4; camera.Pitch = MathHelper.Pi * 0.05f; var masks = new CollidableProperty <ulong>(); characters = new CharacterControllers(BufferPool); Simulation = Simulation.Create(BufferPool, new CharacterNarrowphaseCallbacks(characters), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var random = new Random(5); for (int i = 0; i < 8192; ++i) { ref var character = ref characters.AllocateCharacter( Simulation.Bodies.Add( BodyDescription.CreateDynamic( new Vector3(250 * (float)random.NextDouble() - 125, 2, 250 * (float)random.NextDouble() - 125), new BodyInertia { InverseMass = 1 }, new CollidableDescription(Simulation.Shapes.Add(new Capsule(0.5f, 1f)), 0.1f), new BodyActivityDescription(-1)))); character.CosMaximumSlope = .707f; character.LocalUp = Vector3.UnitY; character.MaximumHorizontalForce = 10; character.MaximumVerticalForce = 10; character.MinimumSupportContinuationDepth = -0.1f; character.MinimumSupportDepth = -0.01f; character.TargetVelocity = new Vector2(4, 0); character.ViewDirection = new Vector3(0, 0, -1); character.JumpVelocity = 4; }
private readonly ConstantsBuffer <float> constants; //alas, lack of root constants public CompressToSwap(ContentArchive content, float gamma = 2.2f) : base( content.Load <GLSLContent>(@"PostProcessing\CompressToSwap.glvs").Source, content.Load <GLSLContent>(@"PostProcessing\CompressToSwap.glfs").Source ) { Gamma = gamma; constants = new ConstantsBuffer <float>(BufferTarget.UniformBuffer, debugName: "CompressToSwap Constants"); }
void Add(List <Sponsor> sponsors, string name, string rewardImagePath, ContentArchive content, RenderSurface surface) { Sponsor sponsor; sponsor.RewardImage = CreateRewardImage(rewardImagePath, content, surface); sponsor.Name = name; sponsors.Add(sponsor); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-30, 8, -60); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DefaultNarrowPhaseCallbacks(), new DefaultPoseIntegratorCallbacks(BufferPool)); var boxShape = new Box(1, 1, 1); var baseShape = new Box(10, 1, 10); boxShape.ComputeInertia(1, out var boxInertia); var boxShapeIndex = Simulation.Shapes.Add(boxShape); var baseShapeIndex = Simulation.Shapes.Add(baseShape); var boxDescription = new BodyDescription { //Make the uppermost block kinematic to hold up the rest of the chain. LocalInertia = boxInertia, Pose = new RigidPose { Position = new Vector3(0, 2, 0), Orientation = Quaternion.Identity }, Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = .01f }, Collidable = new CollidableDescription { Shape = boxShapeIndex, SpeculativeMargin = .1f }, }; var baseDescription = new BodyDescription { //Make the uppermost block kinematic to hold up the rest of the chain. LocalInertia = new BodyInertia(), Pose = new RigidPose { Position = new Vector3(0, 0, 0), Orientation = Quaternion.Identity }, Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = .01f }, Collidable = new CollidableDescription { Shape = baseShapeIndex, SpeculativeMargin = .1f }, }; var boxIndex = Simulation.Bodies.Add(boxDescription); var baseIndex = Simulation.Bodies.Add(baseDescription); _boxReference = new BodyReference(boxIndex, Simulation.Bodies); _baseReference = new BodyReference(baseIndex, Simulation.Bodies); }
public MeshRenderer(MeshCache meshCache, ContentArchive content, int maximumInstancesPerDraw = 2048) : base( content.Load <GLSLContent>(@"ShapeDrawing\RenderMeshes.glvs").Source, content.Load <GLSLContent>(@"ShapeDrawing\RenderMeshes.glfs").Source ) { this.meshCache = meshCache; instances = new StructuredBuffer <MeshInstance>(BufferTarget.ShaderStorageBuffer, maximumInstancesPerDraw, $"Mesh Instances"); vertexConstants = new ConstantsBuffer <RasterizedVertexConstants>(BufferTarget.UniformBuffer, debugName: $"Mesh Renderer Vertex Constants"); }
public GlyphRenderer(ContentArchive content, int maximumGlyphsPerDraw = 2048) : base( content.Load <GLSLContent>(@"UI\RenderGlyphs.glvs").Source, content.Load <GLSLContent>(@"UI\RenderGlyphs.glfs").Source ) { instances = new StructuredBuffer <GlyphInstance>(BufferTarget.ShaderStorageBuffer, maximumGlyphsPerDraw, "Glyph Instances"); indices = new IndexBuffer(Helpers.GetQuadIndices(maximumGlyphsPerDraw), "Glyph Indices"); vertexConstants = new ConstantsBuffer <VertexConstants>(BufferTarget.UniformBuffer, debugName: "Glyph Renderer Vertex Constants"); }
//List<DebugStep> debugSteps; public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, -2.5f, 10); camera.Yaw = 0; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, 0, 0))); const int pointCount = 128; points = new QuickList <Vector3>(pointCount * 2, BufferPool); //points.Allocate(BufferPool) = new Vector3(0, 0, 0); //points.Allocate(BufferPool) = new Vector3(0, 0, 1); //points.Allocate(BufferPool) = new Vector3(0, 1, 0); //points.Allocate(BufferPool) = new Vector3(0, 1, 1); //points.Allocate(BufferPool) = new Vector3(1, 0, 0); //points.Allocate(BufferPool) = new Vector3(1, 0, 1); //points.Allocate(BufferPool) = new Vector3(1, 1, 0); //points.Allocate(BufferPool) = new Vector3(1, 1, 1); var random = new Random(5); for (int i = 0; i < pointCount; ++i) { points.AllocateUnsafely() = new Vector3(3 * (float)random.NextDouble(), 1 * (float)random.NextDouble(), 3 * (float)random.NextDouble()); //points.AllocateUnsafely() = new Vector3(0, 1, 0) + Vector3.Normalize(new Vector3((float)random.NextDouble() * 2 - 1, (float)random.NextDouble() * 2 - 1, (float)random.NextDouble() * 2 - 1)) * (float)random.NextDouble(); } var pointsBuffer = points.Span.Slice(0, points.Count); ConvexHullHelper.CreateShape(pointsBuffer, BufferPool, out _, out var hullShape); const int iterationCount = 100; var start = Stopwatch.GetTimestamp(); for (int i = 0; i < iterationCount; ++i) { ConvexHullHelper.CreateShape(pointsBuffer, BufferPool, out _, out var perfTestShape); perfTestShape.Dispose(BufferPool); } var end = Stopwatch.GetTimestamp(); Console.WriteLine($"Hull computation time (us): {(end - start) * 1e6 / (iterationCount * Stopwatch.Frequency)}"); hullShape.ComputeInertia(1, out var inertia); Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(0, 0, 0), inertia, new CollidableDescription(Simulation.Shapes.Add(hullShape), 10.1f), new BodyActivityDescription(0.01f))); Simulation.Statics.Add(new StaticDescription(new Vector3(-25, -5, 0), new CollidableDescription(Simulation.Shapes.Add(new Sphere(2)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(-20, -5, 0), new CollidableDescription(Simulation.Shapes.Add(new Capsule(0.5f, 2)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(-15, -5, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(2f, 2f, 2f)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(-10, -5, 5), new CollidableDescription(Simulation.Shapes.Add(new Triangle { A = new Vector3(0, 0, -10), B = new Vector3(5, 0, -10), C = new Vector3(0, 0, -5) }), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(-5, -5, 0), new CollidableDescription(Simulation.Shapes.Add(new Cylinder(1, 1)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(-5, -5, 5), new CollidableDescription(Simulation.Shapes.Add(new Cylinder(1, 1)), 0.1f))); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -5, 0), new CollidableDescription(Simulation.Shapes.Add(hullShape), 0.1f))); }
public override void InitializeRendering(ContentArchive content, Camera camera) { /*camera.Position = new Vector3(-20, 10, -20); * camera.Yaw = MathHelper.Pi * 3f / 4; * camera.Pitch = MathHelper.Pi * 0.05f;*/ camera.Position = new Vector3(-10, 5, -10); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = MathHelper.Pi * 0.1f; }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 4, -6); camera.Yaw = MathHelper.Pi; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, 0, 0))); Simulation.Bodies.Add(BodyDescription.CreateConvexKinematic(new Vector3(), Simulation.Shapes, new Box(3, 1, 4))); Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 1.1f, 0), 1, Simulation.Shapes, new Box(2, 1, 3))); }
public RasterizedRenderer(ContentArchive content, string shaderPath, int maximumInstancesPerDraw = 2048) : base( content.Load <GLSLContent>($"{shaderPath}.glvs").Source, content.Load <GLSLContent>($"{shaderPath}.glfs").Source ) { string instanceTypeName = typeof(TInstance).Name; instances = new StructuredBuffer <TInstance>(BufferTarget.ShaderStorageBuffer, maximumInstancesPerDraw, $"{instanceTypeName} Instances"); vertexConstants = new ConstantsBuffer <RasterizedVertexConstants>(BufferTarget.UniformBuffer, debugName: $"{instanceTypeName} Renderer Vertex Constants"); }
public static void Test <T>(ContentArchive content, int runCount, int warmUpFrames, int frameCount) where T : Demo, new() { var runFrameTimes = new double[runCount]; for (int runIndex = 0; runIndex < runCount; ++runIndex) { var demo = new T(); demo.Initialize(content, new DemoRenderer.Camera(1, 1, 1, 1)); GC.Collect(3, GCCollectionMode.Forced, true, true); for (int i = 0; i < warmUpFrames; ++i) { demo.Update(null, 1 / 60f); } Console.WriteLine($"Warmup {runIndex} complete"); double time = 0; int largestOverlapCount = 0; Console.Write("Completed frames: "); for (int i = 0; i < frameCount; ++i) { CacheBlaster.Blast(); var start = Stopwatch.GetTimestamp(); demo.Update(null, 1 / 60f); var end = Stopwatch.GetTimestamp(); time += (end - start) / (double)Stopwatch.Frequency; if (i % 32 == 0) { Console.Write($"{i}, "); } } Console.WriteLine(); var frameTime = time / frameCount; Console.WriteLine($"Time per frame (ms): {1e3 * frameTime}, maximum overlap count: {largestOverlapCount}"); runFrameTimes[runIndex] = frameTime; demo.Dispose(); } var min = double.MaxValue; var max = double.MinValue; var sum = 0.0; var sumOfSquares = 0.0; for (int runIndex = 0; runIndex < runCount; ++runIndex) { var time = runFrameTimes[runIndex]; min = Math.Min(time, min); max = Math.Max(time, max); sum += time; sumOfSquares += time * time; } var average = sum / runCount; var stdDev = Math.Sqrt(sumOfSquares / runCount - average * average); Console.WriteLine($"Average (ms): {average * 1e3}"); Console.WriteLine($"Min, max (ms): {min * 1e3}, {max * 1e3}"); Console.WriteLine($"Std Dev (ms): {stdDev * 1e3}"); }
RenderableImage CreateRewardImage(string rewardImagePath, ContentArchive content, RenderSurface surface) { var textureContent = content.Load <Texture2DContent>(rewardImagePath); return(new RenderableImage( #if !OPENGL surface.Device, surface.Context, #endif textureContent, debugName: Path.GetFileNameWithoutExtension(rewardImagePath) )); }
public override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(0, 10, 40); camera.Yaw = 0; camera.Pitch = 0; //Note the higher stiffness on contacts for this demo. That's not ideal for general stability at the demo timestep duration default of 60hz, but //this demo doesn't have any significant solver complexity and we want to see the CCD in action more clearly- which means more rigid contact. //Having objects bounce a bunch on impact makes it harder to see. //Also note that the PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks() { ContactSpringiness = new SpringSettings(120, 1) }, new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var shape = new Box(1, 1, 1); shape.ComputeInertia(1, out var inertia); var shapeIndex = Simulation.Shapes.Add(shape); for (int i = 0; i < 10; ++i) { for (int j = 0; j < 10; ++j) { //These two falling dynamics have pretty small speculative margins. The second one uses continuous collision detection sweeps to generate speculative contacts. Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(-4 - 2 * j, 100 + (i + j) * 2, i * 2), new BodyVelocity { Linear = new Vector3(0, -150, 0) }, inertia, new CollidableDescription(shapeIndex, 0.01f), new BodyActivityDescription(0.01f))); //The minimum progression duration parameter at 1e-3 means the CCD sweep won't miss any collisions that last at least 1e-3 units of time- so, if time is measured in seconds, //then this will capture any collision that an update rate of 1000hz would. //Note also that the sweep convergence threshold is actually pretty loose at 100hz. Despite that, it can still lead to reasonably good speculative contacts with solid impact behavior. //That's because the sweep does not directly generate contacts- it generates a time of impact estimate, and then the discrete contact generation //runs to create the actual contact manifold. That provides high quality contact positions and speculative depths. //If the ground that these boxes were smashing into was something like a mesh- which is infinitely thin- you may want to increase the sweep accuracy. Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(4 + 2 * j, 100 + (i + j) * 2, i * 2), new BodyVelocity { Linear = new Vector3(0, -150, 0) }, inertia, new CollidableDescription(shapeIndex, 0.01f, ContinuousDetectionSettings.Continuous(1e-3f, 1e-2f)), new BodyActivityDescription(0.01f))); } } rolloverInfo = new RolloverInfo(); rolloverInfo.Add(new Vector3(-12, 2, 0), "Discrete"); rolloverInfo.Add(new Vector3(12, 2, 0), "Continuous"); //Build a couple of spinners to ram into each other to showcase angular CCD. Note that the spin speeds are slightly different- that helps avoid //synchronization that makes the blades frequently miss each other, which sorta ruins a CCD demo. spinnerMotorA = BuildSpinner(new Vector3(-5, 10, -5), 53); spinnerMotorB = BuildSpinner(new Vector3(5, 10, -5), 59); rolloverInfo.Add(new Vector3(0, 12, -5), "High angular velocity continuous detection"); Simulation.Statics.Add(new StaticDescription(new Vector3(0, -5f, 0), new CollidableDescription(Simulation.Shapes.Add(new Box(300, 10, 300)), 0.1f))); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-30, 8, -60); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0; //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out var boxInertia); var boxIndex = Simulation.Shapes.Add(boxShape); const int forkCount = 20; const int blocksPerChain = 20; BodyHandle[] blockHandles = new BodyHandle[blocksPerChain]; for (int forkIndex = 0; forkIndex < forkCount; ++forkIndex) { //Build the blocks. for (int blockIndex = 0; blockIndex < blocksPerChain; ++blockIndex) { var bodyDescription = BodyDescription.CreateDynamic( new Vector3(0, 5 + blockIndex * (boxShape.Height + 1), (forkIndex - forkCount * 0.5f) * (boxShape.Length + 4)), //Make the uppermost block kinematic to hold up the rest of the chain. blockIndex == blocksPerChain - 1 ? new BodyInertia() : boxInertia, new CollidableDescription(boxIndex, .1f), new BodyActivityDescription(.01f, 32)); blockHandles[blockIndex] = Simulation.Bodies.Add(bodyDescription); } //Build the chains. for (int i = 1; i < blocksPerChain; ++i) { var ballSocket = new BallSocket { LocalOffsetA = new Vector3(0, 1f, 0), LocalOffsetB = new Vector3(0, -1f, 0), SpringSettings = new SpringSettings(30, 5) }; Simulation.Solver.Add(blockHandles[i - 1], blockHandles[i], ref ballSocket); } } Simulation.Statics.Add(new StaticDescription(new Vector3(1, -0.5f, 1), new CollidableDescription(Simulation.Shapes.Add(new Box(200, 1, 200)), 0.1f))); //Build the coin description for the ponz-I mean ICO. var coinShape = new Cylinder(1.5f, 0.2f); coinShape.ComputeInertia(1, out var coinInertia); coinDescription = BodyDescription.CreateDynamic(RigidPose.Identity, coinInertia, new CollidableDescription(Simulation.Shapes.Add(coinShape), 0.1f), new BodyActivityDescription(0.01f)); }