bepu / bepuphysics2

Pure C# 3D real time physics simulation library, now with a higher version number.
Apache License 2.0
2.4k stars 274 forks source link

New approach to writing demos #53

Closed MuleaneEve closed 3 years ago

MuleaneEve commented 6 years ago

This is still work-in-progress, but I wanted to get some feedback from you: I have been playing around with an AI project where a 3D 4-legged creature learns to walk through the training of a neural network. The original code was written using the ODE physics engine, and I want to port it to BEPUphysics.

For this project, I wrote a demos engine with a bunch of features that I would like to also port to BEPUphysics:

  1. The simulation (Demo) is split from the simulated objects. So, it is easy to "compose" a demo by adding the relevant simulated objects (eg: The RagdollDemo can have a separate Ragdoll class. Or, some extra features can be enabled by adding extra objects, like to log statistics or for controls). And because all these objects inherit the same base class (SimulatedObject), they are easier to work with.
  2. Physics, Rendering and Input are clearly decoupled, so the demo can be run in the background (where Rendering and Input are not relevant).
  3. The demo can run on a controlled time scale (so it is not tied to the fps). It is also possible to pause the Physics only (while the Rendering and Input continue to work), so we can move the camera while time is "frozen".
  4. Any object can signal that the demo should end (relevant for background demos). The Program can specify a maximum number of time steps or give a function that triggers the end when needed.
  5. Some neat side features (like Log() and PI) that are optional.
  6. DemoSet is a bit more flexible with its "options". It makes it easy to write custom demos outside of the Demos project (like my AI project).

Another feature that I also want to add is the ability to run many demos at the same time, so there can be one foreground Demo, and many more in the background. This would be useful so my AI project can show one instance running while the neural network training is ongoing (in the background).

I have forked BEPUphysics to add these features, but for now, I kept them in a separate DemoEngine project. You can see these features being used in the SharpNeatWalker project. (There is still some work to do to better integrate this new features...) If you are open to it, I would love for them to be merged into Demos.

RossNordby commented 6 years ago

Neat project!

I'm a bit concerned about adding abstractions and (admittedly mild) complexity to the Demo type itself. Part of the goal for the demos application is for new users to be able to quickly grok everything involved with setting up the physical simulation. Minimizing features is helpful- a user looking at the PyramidDemo can navigate to the current Demo superclass and see the whole thing on (almost) a single screen. It's pretty easy to tell that there's no magic hiding there.

I can certainly see the value of the changes, but the use case sounds different enough from the main demos to warrant a separate implementation for now.

That said, there are clearly some design goals that are shared and which would be nice to eventually roll into main demos framework, though I don't know exactly how it will look yet:

  1. Separate the reusable core of the Demos framework into its own library so it can be used more easily with other demos-like applications (similar to the DemoEngine in your fork).
  2. Create an abstraction for demos that preserves the simplicity of existing demos but which permits greater opt-in control. Ideally, the kind of demos in your fork could be plugged into this without influencing the simpler educational demos. This would likely require some work on the side of the DemoHarness input management to be a little more flexible- being able to easily register custom control bindings, for example.
  3. Make headless demos more convenient. There is indeed some annoyance caused by not distinguishing physics-only logic from the input/rendering logic, and the abstractions required to fix it aren't very burdensome.

I will need some time to work out how exactly I want to deal with this, so it's probably a good idea to forge ahead with your own version for now. Hopefully you'll be able to share a bit more code over time.

MuleaneEve commented 6 years ago

I agree on the idea of having a simple demos for new users. And I wonder if the Demos project isn't already too complex for that purpose. Maybe, new users would be better served by "Hello, World"-style projects with minimal 3D features (just bootstrap SharpDX and start colliding a sphere with a plane)...

Then, people can jump into the current Demos to learn more advanced features.

I will play around with this "Hello, World" idea, and see what I can come up with.

RossNordby commented 6 years ago

That's something I tried in v1- fully self contained tutorialish applications with the absolute bare minimum of graphics and interactive features. Unfortunately, they tended to hit a very awkward midpoint: enticing to users with little/no experience in game development or related fields, but not actually better at explaining the physics engine part of things. In fact, unless enough structure was included to isolate the physics part (like the Demo class), it was more difficult for inexperienced users to tease concepts apart.

There was also a bit of a bait and switch in v1's documentation- stuff like the "Getting Started" demo made v1 appear accessible enough for a completely new developer, and then they'd run into the complexities of physics simulation and flounder (and then I'd spend time responding to forum questions, linking learning resources closer to their current skill level).

v2 makes this even worse by introducing unmanaged memory, handles, advanced language feature usage and so on. I'd rather not be responsible for getting new developers over that hump.

In other words, I'm okay with a fairly complex environment so long as it doesn't get in the way of a reasonably experienced new user quickly learning about the physics library- for example, a user doesn't need to know anything about how the DemoHarness works in order to look at the simulation setup.

That said, it's very possible to do better than I did in the v1 tutorials and I wouldn't be opposed to others trying their hand at it. But when it comes to resources targeting very new developers, I would probably just link to the resources rather than pulling them into the main respository to avoid some of the resulting questions :P

MuleaneEve commented 6 years ago

I kind of understand what you mean, and I also hope that we can figure out a good balance for all these concerns.

I think that I am exactly the type of reasonably experienced new user that you are talking about. It was indeed easy for me to get a sense of how to use the physics engine. I was also able to build my own project on top of the Demos infrastructure.

But now that I am trying to build a little tutorial app that doesn't depend on Demos, I realize just how much stuff I really need to figure out. And it is very hard to figure things out because there is so much code to go through.

As it is, the Demos project is the sandbox you use to test out all kinds of features, so it has evolved to be flexible and complex overall...

So, would you be happy with a simplified version of the demos, with far less "code behind"? If the PyramidDemo code can run (almost) as-is on that simpler back-end (let's call it TutorialEngine), then a new user would have the same first-time experience. Then, he could either use DemoEngine to write his own demos without trying to understand how it works internally, or he could dig into TutorialEngine to fully understand everything before transitioning to writing his own engine.

And TutorialEngine will stay simple as time goes while freeing you to improve DemoEngine as needed.

RossNordby commented 6 years ago

I think I might better understand where you're coming from now. If I'm not mistaken, the core difference is that I consider the graphics, input management, demo framework and everything other than the physics library as existing only to test and demonstrate the physics library. I don't intend any of the non-physics stuff as being reusable or interesting outside of the demos application. (I'm not against such reuse if someone happens to find it useful, it's just gravy.)

In other words, I expect users to ignore everything but the physics bits, so there isn't much value to me in simplifying the non-physics bits unless they get in the way of understanding the physics bits.

I certainly would be fine with the creation of third party projects that show alternative ways of handling demo-related things, but I probably wouldn't pull it into the main repo since it goes beyond the core purpose of the repo.

MuleaneEve commented 6 years ago

In practice, the graphics and input are linked to the physics. As a new user, I struggled to figure out how they interact with each others...

Anyway, I am working on that TutorialEngine. When I'm done, I will have a better understanding of all this and will be able to make more specific suggestions.

vpenades commented 5 years ago

Regarding Additional demos and tests, I would suggest to include a NUnit test that would work as a demo. I am working with a IK CCD solution system, and I've implemented a number on NUnit tests on them.

The beauty is that NUnit allows to attach a file to the outcome of the test, and the file can be inspected later. So what I did was to write two screenshots of every test, one before and one after the simulation.

So, along with the actual NUnit tests that check that the outcome is fine, no exceptions, etc, I can also visually inspect the scenes.

MuleaneEve commented 5 years ago

@vpenades Since your suggestion is different from the topic of this issue, can you please open a new issue with your idea?