Design notes
Moved to Software Architecture Ideas/Game Loop
Thoughts on APIs and C++
One annoyance with C++ is the lack of any accepted standard for 'name mangling', the algorithm that the compiler uses to generate names of things in object code. These are the symbols used by a linker to knit together object files and libraries to make an executable file.
Names were simpler in C due to a lack of scope constructs in the language, and C compilers followed a very few, simple conventions for 'name mangling'. The conventions were so simple that nobody even thought much about it, and usually all compilers for a given platform (UNIX, DOS, etc.) would use the same conventions. (A typical standard was to prepend an underscore on function names.) This meant that object modules created by different C compilers could be easily linked together.
Alas, in C++, this is not so. For instance, I tried using the Comeau compiler to build our DirectX test program. This compiler uses a different name mangling method than VC++, and I strongly suspect that this was the cause of the problems that ended my Comeau experiments -- DirectX includes C++ APIs, which are hard not to use because they include things like binary arithmetic operators for DirectX data types, such as matrices and quaternions.
TBC
Misc. To Do
- Hook up DX8 front-end to psim with some objects to test it.
- Drive psim steps in render loop.
- Take each object's transforms from psim.
- Add mechanism to apply forces.
- Glue viewpoint to an object.
- Write up something on units of measure for SDx. Figure out physical extents for psims.
- Consider multi-level psims.
- Figure out how to unit test psim. Need to to define tolerances allowed for numerical results, because small changes in numerical methods differ in accuracy and drift.
- Consider building an interactive front-end with three orthogonal 2D projections of psim.
- DLL builds -- necessary?
On hold:
- Note updates to MinGW dev environment. Make it easier for others to get started with it.
- STLport hack for -fvtable-thunks
- DX8 SDK, MinGW-compatible import libs.
- Update psim and psimtest sources, prolly on John's FTP site.
- Understand Jam "grist" better, and how Boost.Build uses it.
- Talk to John re setting up Subversion instead of CVS. Agreed that it's wise to wait until Subversion can use a pre-built version of Apache. In the meantime, CVS.'
Dev Env notes
BJam was a bit frustrating to get started with. I'm re-using most of the toolset configurations from Boost. They seem generic enough.
One odd problem: The Jam system used by Boost is very clever. It defines a toolset-independent 'feature' for every build variation -- debug symbols included/excluded, profiling on/off, etc. It puts the binaries in a subdirectory tree that represents a branching path through these selections, where the objects go in a leaf directory. Since there are so many variations, the tree is quite deep. Too deep for XP, apparently, when I used my default home directory (My Documents). So I had to move my work root up high on my disk directory hierarchy. :-)
GARRR. Spent half of my weekend trying to grok MTL, finally punting. Just discovered uBLAS, now I'm trying that. (See Interesting Links/Development Libraries.) Easier to grasp, but it's pre-release, and the docs are also sparse. (Though not nearly so bad as MTL.) It's all overkill for what I'm trying to do at the moment, but a good matrix/vector library will save us time down the road.
Physics Engine notes
What physics need to be simulated for a space simulation? How much of this needs to be gathered into an 'engine'?
- Simulation of relative position of objects, to support rendering, AI, collision detection.
- Velocities needed in order to determine subsequent positions.
- Possible exception: keyframed motion (applications? needed? ask Dave re pros & cons of dynamic modelling (via scripts and forces) vs. keyframed motion)
- Possible exception: static objects if any (in a space sim, everything tends to be in motion except things that can be designated as distant background)
- Accelerations usually needed to determine subsequent positions.
- Forces and masses are needed if:
- that's a reasonable way to determine acceleration
- complex object interactions are needed - cf. rigid body dynamics, joints
- Grouping of primitive geometries into objects is essential for efficiency and understanding.
- N-level hierarchies useful?
- Object forces needs to be modifiable by code outside the physics engine
- Disallow direct updates of position.
- Would be a headache for collision detection.
- Would cause warping.
- For dead reckoning corrections, try to come up with 'corrective force' instead, leading to smooth updates (but more prolonged disagreement between realities among nodes).
- Maybe disallow direct updates of velocity.
- Updates to forces can come from: scripts, user input, network code, physics engine
- Disallow direct updates of position.
Issues
- Discrete-step physics simulator needs to cycle frequently for accuracy, usually more physics cycles than rendering cycles.
- To prevent memory thrashing in low-memory situations (and to improve CPU cache coherency), it's desirable to have the parameters that are handled by the physics loop in contiguous memory. Can design for this without requiring it at this point.
- Stability and repeatability.
- Network code should probably work under the assumption that 100% repeatability is not achievable. This will also allow physics simulation step size to vary among machines. Size of discrepancies between machines has to be controlled, however, and perhaps taken into account by collision detection and AI code.
- Stability is a big deal. Other libraries go to great lengths to come up with mathematical algorithms that balance stability and performance. Borrow liberally from other work where possible.
- Sliding zones: Would be nice if a player's ship could be kept central at (0,0,0). If not, then periodic adjustments are needed to recenter the sliding zone.
ODE looks good, but the latest sources are not compilable under MinGW (no alloca.h).
I'm working on writing a simulator from scratch. The basic structure of these simulators is interesting. The body state variables (e.g. position, velocity) get gathered into one long vector of doubles -- a total state vector for the system. Likewise, the derivatives of the body state variables (e.g. velocity, acceleration) get copied to another long vector (same length as first). These two state vectors and the time delta are used to calculate a new state vector, which is scattered back to the body objects. This basic structure doesn't change even if you add additional state, such as rotational kinematics. The function that computes the next state doesn't care how many state variables are involved; it just operates on mondo total-system vectors. It should be possible to arrange things so as to avoid data copying back an forth, instead just updating a pointer in the bodies to index into a new system state vector.
Need feedback from Frank on what he needs from the simulator interfaces. For instance:
- Given a point relative to a body's own coordinate system, provide that point's position in simulator coordinates. (For translating polygon vertices to physical position.)
- Probably will also need the orientation (rotation) at that point?
Fun things to look forward to:
- collision detection
- composite bodies
- splitting composite bodies. (Disconnect missile from ship -- figure out new ship & missile state. Ought to be fun to watch!)
- merging bodies into a composite. (Docking maneuvers!)
Dimensions of interest
; Persistence: Persistent objects are stored in a database when not being actively simulated. ; Identity: How an object is uniquely identified. ; Access authorization: Most objects can be accessed and simulated by anyone. Owners can actively modify the state of the object. ; Distribution: Can the object be simulated on multiple nodes simultaneously? Which nodes can 'own' an object? ; Structure: Notes on apparent structure of contained data.
Physical simulation
- Persistence: none
- Identity: physical location (simulation region center)
- Access: Player nodes should only be able to simulate regions centered on active objects that they own. Server nodes can simulate any region.
- Distribution: Contained objects are distributed. Registers an interest with parent node(s).
- Structure: Contains simulated objects in that region.
Physical objects generally 'simulate themselves' based on their current state and requests for updates from their owning simulation. Active objects have input interfaces which vary by the type of object. These input interfaces are only accessible to authorized clients.
Physical object
- Persistence: varies by type
- Identity: ??? Managing global IDs could be a bottleneck, and we have some physical objects that exist only implicitly via seeded random generators. OTOH, some means is required to identify objects in communications. Perhaps identitification in that context is connection-specific?
- Access: varies by type
- Distribution: All physical objects can be distributed, i.e. simulated by any interested node. Ability for a node to 'own' a node varies.
- Structure: varies by type
Persistent physical object
- Persistence: varies
- Identity: varies
- Access: varies
- Distribution: Ownership can vary over time for an object that is being simulated! Possible strong implications for implementation.