Repository navigation
Usability fixes from a demolition demo - #13
Merged
Merged
Conversation
The remarks on Explode read "Only spheres, capsules and hulls respond." In this API Box and ConvexHull are different types, so that reads as "boxes do not", and a user building a demolition demo built every crate from eight corners with ConvexHull.FromPoints to get around a limitation that does not exist: AddBox makes a hull through b3MakeBoxHull, and a hull is what Box3D pushes. The remarks now say that boxes respond because they are hulls, and why meshes, height fields and compounds do not. b3World_Explode queries only the dynamic-body tree, and those three can only be attached to static bodies; b3GetShapeProjectedArea would also give them no area. The same query is why kinematic bodies are not pushed, which is now stated too. AddBox and ShapeType.Hull say that a box reports ShapeType.Hull, so reading Shape.Type back is not another surprise. ExplosionTests is new and pins each claim: boxes, spheres and capsules are pushed; kinematic bodies and bodies out of reach are not; a sleeping body is woken; and the filter is compared with shape categories. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A demolition demo hung a ball of about 33 kg from a chain of spherical joints whose links weighed about 0.02 kg, and the links flew off. Nothing in the library is wrong there: the solver resolves joints iteratively, and a light body between an anchor and a heavy one barely moves the heavy one, so the error never converges. But nothing said to avoid it either. Reproduced before writing it down, with ten spherical joints: at about 1450:1 the fastest link reaches 427 m/s and the last joint stretches by 0.66 m; at about 20:1 the fastest link moves at 3.1 m/s and the joint holds to 3 mm. The guide gets a callout recommending 10:1 to 20:1 or less, the measurement behind it, and a note that the ratio that matters is the one across each joint rather than the chain's total mass. The chain sample says the same where its links are created, since that is the code people copy. The measurement is not a test: it pins solver behaviour, which is Box3D's to change, not this binding's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Changing one material property on a shape definition took two nested with
expressions:
ShapeDefinition.Default with { Material = PhysicsMaterial.Default with { Friction = 0.7f } }
ShapeDefinition.Friction and Restitution are init properties that read and
write Material, so the same thing is ShapeDefinition.Default with
{ Friction = 0.7f }.
Properties rather than WithFriction(float) methods, because nothing in this
API builds values through methods: every definition is a record with init
properties, adjusted with with, and a shortcut that did not work inside a
with expression would sit beside every other property as the one exception.
Shape already exposes Friction and Restitution as shortcuts for its material
at run time, so the definition now matches the handle.
Only these two. Every PhysicsMaterial property could get a shortcut, but
friction and restitution are the ones a game tunes per shape; the rest are
rarer, and duplicating the whole material would give ShapeDefinition two
ways to say everything.
The properties have no backing field, so equality and hashing are
unchanged: a definition built with a shortcut equals one built the nested
way, which ShapeDefinitionTests checks, along with initializer order and
that the values reach the native shape. The change is additive, so package
validation against the previous release is unaffected.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Explode takes ulong filter = ulong.MaxValue and assigns it to b3ExplosionDef.maskBits, while every query takes a QueryFilter?. The name suggests the latter, and the documentation, "which shape categories are affected", did not say how. b3World_Explode passes the mask to the dynamic tree, which compares it with each proxy's category bits. That is the job QueryFilter.CollidesWith does in a query, but a query also requires the shape's own mask to accept the query's categories (b3ShouldQueryCollide checks both directions), and an explosion does not. The parameter now says all of this, and a test shows a shape whose CollidesWith is zero is still pushed. The parameter keeps its name: renaming it would break anyone passing it as filter: in source. There is no QueryFilter overload either. It would have to drop QueryFilter.Categories on the floor, and an overload that silently ignores half its argument is worse than a mask parameter whose documentation is clear. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four points found while building a demolition demo on Box3D.NET 0.5.0. Two are documentation, two are API ergonomics. All changes are additive; package validation against the previous release passes with and without the iOS target.
Explodesaid "only spheres, capsules and hulls respond", which reads as "boxes do not". Boxes are hulls and do respond. The remarks now say so, and explain, fromb3World_Explode, why meshes, height fields and compounds never respond: they are static-only and the blast queries only the dynamic tree. They also say that kinematic bodies are not pushed and that sleeping ones are woken.AddBoxandShapeType.Hullnote that a box reportsShapeType.Hull. NewExplosionTests.docs/guides/joints.mdgets a callout with the measurement, and thechainsample has a comment where its links are created.ShapeDefinition.Friction/Restitution:initshortcuts overMaterial, instead ofWith…methods, since the API is built entirely fromwithexpressions andShapealready has the same shortcuts. There is no backing field, so equality is unchanged. NewShapeDefinitionTests.Explode'sfilteris documented as a category mask that is checked in one direction only. It is not renamed, which would break callers passing it by name. NoQueryFilteroverload was added, because it would have to silently ignoreCategories.Local: 378/378 tests, 0 warnings,
dotnet formatclean, 16/16 samples,api-coverage -Checkup to date.