Twig Physics Library v0.1 for DarkPlaces
by Urre & LordHavoc

Update 060109:
First release (NOTE: Requires the 2009 jan 06 beta release or newer of DarkPlaces to run properly!)

Thanks to:
Electro for the awesome logo!
tZork for debugging and helping find what should have been an obvious bug
frank for support, discussion and ideas
Ender for Scratch tutorials
div0 for the automatic DP SVN build script
scar3crow for help with this readme
Spike for FTEQCC

Description:
QuakeC physics-library for use in DarkPlaces powered mods and games. Currently capable of creating simple rigid objects, such as crates, barrels, hanging/dangling objects. This is how it works:

Imagine a stick. Toss the stick, and it'll bounce around happily until laying down flat to the ground. Now imagine three sticks, stuck together forming a triangle. This acts very much the same way, but resembles something with more of a shape than a line. Imagine sticking together enough sticks that they form a cube, with a stick between each and every corner of the cube, making it feel really sturdy, so it won't bend under its own weight if dropped to the ground. This obviously makes quite many sticks. Each and every side of a cube uses 4 sticks to get the square shape of the edges, and 2 sticks for a cross in the middle for extra stability. The connecting edges between sides can obviously share sticks. On top of this, there are 4 sticks in the middle of the cube, connecting the corners together. This makes 28 sticks for a cube. All this is required to make the cube feel rigid. This is the basic idea of a stick-physics-engine.

To get slightly more detailed, the sticks are actually imaginary. The physics lib is particle based, only using the "sticks" for information about how much space there should be between two given particles. Ingame, the physics lib will access the list of sticks and attempt to either push the particles further away from eachother, or pull them closer towgether, while they're bouncing around by gravity, buoyancy, collisions and other forces. Because sticks can share particles, it will end up resembling a rigid object as all the particles in an object will constantly struggle to stay away/close to eachother at the same time.

Seeing as the 8 particles forming the corners of the cube and the 28 sticks keeping the particles in check are invisible, we need something to represent the shape ingame. The lib provides the ability to attach a model to the object, by making it align with the particles, so it rotates correctly as the particles move around in the world.

To make it possible for objects to collide with eachother, they need to be made solid somehow. This physics lib solves it by having invisible BSP models attached to the particles in very much the same manner as the visible models. So when the particles of an object hit the BSP model of another object, they will bounce off, and distribute some force between the particles of the object that was hit. There's also another difference with these and the visible models, which is the fact that BSP models have a volume, making them solid throughout. So if a BSP model of an object moves over another objects particles, the physics lib will detect the particles being stuck inside a solid, and pop them out again, resulting in semi-realistic pushing.

The lib obviously has a lot of shortcomings, some from the fact that it's QC based, some because it's in very early stages. Sticks for example, don't collide in any way, so it's not uncommon to see objects intersect thin sections of geometry, with one half of the particles on one side, and the other half on the other side. Worse is when an object falls through "broken ground", because the particles are either scarce or small. Keep this in mind. Another one is that it's rather slow. Much due to the fact that QC is 6 times slower than C (which on the other hand is faster than any other VM out there), but some due to it being very unoptimized. For this release I've only concentrated on making it work as well as I can. The only optimisations I've added are velocity limiting, and object resting.

Usage:
For players there's not much to see here, really, sorry. You can try out the physics by running the mod in a map of your choice, and pressing E (impulse 20), which will throw an existing object. Clicking left mousebutton (+attack) will pick up the object you're aiming at, clicking it again will launch it forward. Hold down the mousebutton to release the object without launching. Right mousebutton (+jump) will toss a grenade which makes things bounce away from the explosion.

For developers, there's a lot to be covered, and I hope to do it properly for a later release or so, but I figured I should get you experimental ones started atleast.

The main physics loop is in phys_exec.qc, called Phys_ObjectThink, which is called by every object on a per-frame basis. Objects spawned into the game are done so by calling Phys_ObjectCreate in the same file, useful for when you want to make game-objects of the physics-objects. Currently there's nothing useful for games, it's just the physics and a simple client for walking around in the world. For things like damage, you'd probably want to do it in Phys_Force (still in phys_exec.qc), which is called whenever a particle of a physics object hits something. Also, see client.qc for (quite hacky) examples of ways to manipulate and use the physics objects (gravity gun, grenade, and object pushing).

The ingame physics-object editor works as follows: Press I (impulse 30) to get to the editor. Either pick an object to edit, or make a new empty one. Buttons are as follow:

Holding down control (button 4):
- wheelup (impulse 31): gridsize up
- wheeldown (impulse 32): gridsize down
- left mousebutton (button 0): move particle
- right mousebutton (button 2): rotate particle

NOT holding down control (button 4):
- wheelup (impulse 31): zoom in
- wheeldown (impulse 32): zooom out
- left mousebutton (button 0): switch part
- right mousebutton (button 2): switch axis

For the most part these will do fine, but there are some commands which are useful, and in some cases required, such as the save command. Commands are issued using messagemode, aka the "say" command, bound to T by default. The commands are as follow (without quotationmarks):

"particle": spawns a particle
"hitmodel": spawns a hitmodel, an invisible BSP model used for collision
"static": spawns a static model
"model *": changes the model of the selected part. Path is required, for example "model progs/grenade.mdl" will set the model to be the Quake grenade. Typing nothing will make the part invisible
"name *": will change the name of the selected part, useful for identifying particles ingame for special behavior for game-objects
"objectname *": will change the name of the object
"objectmass #": changes the mass of the object, default 50
"grid #": will set the editing grid to this value
"save *": saves the object, filename required if it's a new object
"size #": will change the size of the selected part to this value
"mass #": changes the selected particles mass-scaler to the given value, 0 mass means no movement, default 1
"bounce #": changes the selected particles bounciness to the given value, 1 means no bounce, default 1.2
"friction #": changes the selected particles friction to the given value, default 0.075
"friction_water #": changes the selected particles water friction to the given value, default 0.01
"buoyancy #": changes the selected particles buoyancy-scaler to the given value, scales the servers sv_gravity in the opposite direction, default 0.2
"stiction #": changes the selected particles stiction to the given value, determines at which speed the particles stiction kicks in, default 50

Currently the only cvar is "phys_velocitylimit", which defaults to 10000, meaning objects can't travel faster than 10000qu/s. Generally speaking, this should be fine for most stuff. The Quakeguy runs at 320qu/s, and rockets fly at 1000qu/s. You can try altering the value, and see what happens when picking up a physics object very far away, and flailing it in the air. Higher values cause more repeats of calculations to keep the constraints working without sign errors, which means it'll eat more fps.

Hardware requirements:
As long as you can run DarkPlaces, you can run this. Obviously, the more physics-objects you have ingame, the slower it will run.

Bugs:
Most have been squashed, but there are a couple left

- Force calculations are not as good as they could be, needs reworking
- Sign errors happen at somewhat rare occasions, still way too often, result in ever-spinning objects

Feel free to tell us if you spot more, or if you have ideas for fixing these!

FAQ:

Q: Why? Why not make it a proper addition written in C for the DarkPlaces engine?
A: Dunno. Seriously though, there are many reasons. One is, I simply wanted to see if it's possible to do it. Another is that it's nice to have the control provided by the fact that you can access all the physics-related stuff from the gamecode directly, without having to rely on builtins which might be too limited for the purpose you're after. The more major reason is because when I started working on it, I didn't know C at all, and the description I read on these kinds of physics sounded like it'd work just fine within the limits of QC, and I've always wanted a physics-engine for DP, so I just went and did it.

Q: Can I make vehicles with this?
A: Not really, yet. It's a planned feature for future releases.

Q: Can this be made into a sort of Garrys mod?
A: Sure! The amount of work depends on the amount of features you want to support.

Q: Can this do real ragdolls?
A: Planned feature :)

Q: What about Sagdoll? Can it align corpses to slopes?
A: Twig is very modular. It doesn't have an understanding of "corpses" per se, it's just physics. You can make a corpse have physics, which would already do more than you're asking for. The short answer is no, because aligning corpses, or the more advanced kind of alignment that Sagdoll does, is more like gamecode than physics code.

Q: Does it support Gyro/does it do stuff Gyro does?
A: Supporting, maybe. You could make particles Gyro-objects, and it should work, might even be an interesting combo. About doing the things Gyro does... Gyro does stuff which is closer to gamecode rather than physics, but more modular than say Sagdoll, so it's sort of in-between. Twig will do many of the things Gyro does, just differently. Gyro is mostly about the interaction between objects, whereas Twig is more about the single object. Interaction between objects is much closer to gamecode-related things, and thus not as interesting for the purpose of Twig. Twig will handle the more physics-heavy things such as collisions between the objects, but things like explosions pushing stuff is up for the user to code.

Q: Can you make it read .obj's for physics-object info
A: For future releases, if so.

Q: Can I use this in Nexuiz?
A: Certainly! Nexuiz' gamecode is written in QC, just like this lib.

Q: Can I use this with Frikbot?
A: Should be entirely possible, but will probably require a lot of reworking of the bots AI, to understand the objects and their properties. If you don't care about the Frikbots interacting with the objects besides perhaps colliding with them, it would work without modifying the bot.

Q: Can stick-physics be used for clients and/or monsters?
A: Theoretically, sure. Currently things like hinge-constraints and motors aren't supported, so it'd be very hard or hacky. But even if those were supported, the amount of AI-work it'd take to do it is insane, totally major graduate level AI stuff. I can totally understand the fascination about this. See Euphoria for this theory in action, and Sumotori Dreams.

Q: Can this be used clientside?
A: Surely! Some future release will be made specificly with this in mind, but if you're CSQC proficient, it's not hard to port.

Q: What's the framerate impact of a typical 'stick'?
A: Well, a single stick will probably have no impact at all, atleast very hard to measure. An easier way to see it is this: In loose terms, the constraints are the most taxing part of the operation. For every particle you add to a physics-object, you have to add sticks between all the other particles, which means more constraints to solve to keep the shape of the object ingame. Two particles means one stick, three particles means three sticks, four particles means six sticks, five particles means ten sticks, and so forth. A very simple box is, like mentioned before, eight particles, and twenty-eight sticks.

Legal:
You may use the contents of this archive in non-commercial projects as long as you credit the authors
The contents of this archive may be converted to GPL and other similar licenses
Using the contents of this archive for commercial closed-source products can be discussed

Contact:
Urre
LordHavoc

Look out for twigboy.