Connectivity Problems
2014-12-28, 21:48 (This post was last modified: 2015-01-02, 8:16 by Willy Tschager.)
2014-12-28, 21:48 (This post was last modified: 2015-01-02, 8:16 by Willy Tschager.)
Hi Y'all,
I've been playing with the idea of connectivity for a while now, and picked it up again after poking around Moc Builder recently. The main features I'd like to support in Bricksmith with connectivity data are:
- Easy assembling of models (by having Bricksmith know how parts want to "snap" together)
- Easy manipulation of irregular shapes (e.g. hinges at odd angles and technic assemblies) by letting Bricksmith understand how an entire sub-assembly rotates around an arbitrary hinge. (This would make irrelevant the part origin or META commands to "fix" the origin - the connectivity information would specify how a given part can rotate.)
- In an ideal world, Bricksmith would be able to figure out what the "actions" of a given model are. E.g. if you make a car and the doors open, the hood can pop up, and the trunk opens, ideally Bricksmith can, from the connectivity information, derive some kind of higher level "playability" data that describes what the model does. (This goal is much harder than the first two.)
I did some experiments with LDD and found that it goes very far in most of these directions. However, it also hits limits sometimes. For example, I downloaded an LDD build of 70165 (ultra agents HQ) and found that LDD couldn't figure out that the linear assembly of ball joints effectively form a hinge. As a result, the truck walls could not be "opened". LDD does seem to understand complex technic assemblies (at least sometimes) but sometimes moves the model all over the place trying to solve the system of multiple independent hinges.
Anyway, starting with the usual straw man of connector meta-data on parts (e.g. plugs and sockets or receptors modeled after things like stud, hole for stud, technic hole, technic axle, etc.) there are a few problems I'm not quite sure what to do about. This is sort of a brain dump of where I'm at in the design.
1. Friction: ignoring wear-and-tear on your real bricks, the friction of a given hinged connection varies by part. For example, 1x4 brick hinges tend to be very "floppy" and we can almost always assume that if they've been left hanging free, it was the intention of the modeler to make an opening door, moving part, etc. By comparison, 1x2 brick hinges are relatively stiff* and can be used to simply build at a 45 degree angle, or they can show intended motion. (See also 1x2 brick hinges used in place of a 1x2 brick with studs on side before we had SNOT bricks.)
I'm not sure how to determine what is intended "playability" and what is not. One solution is to treat everything that can move as playable, but the result would be that complex bar and clip assemblies (like the carefully modeled bogies that serious train nerds build) would be interpreted as incredibly complex moving parts, when they're really supposed to just sit there looking nice.
2. Movement limits: both MocBuilder and LDD support AABB collision testing on bricks, which helps solve the "it can't rotate any more because it bonks itself" problem. But it would still be nice to get -exact- rotation limits out of a given system. E.g. every 1x2 brick can rotate 0 to 90 degrees at most. To determine this from AABB, we'd be forced to build very complex AABB models of the hinge itself. Ideally an LDraw client would be able to determine some rotation information while punting on collision detection, or be able to operate even if the entire LDraw library wasn't correctly AABB modeled. (Realistically I think we could get partial connectivity implemented relatively quickly for a subset of parts, but having an AABB on every single part is a huge undertaking.)
3. Complex movement. A series of hinged assemblies may define a single play movement because of limits to interaction between moving parts. For example, consider a train with working steam pistons. A low level analysis of connectivity would reveal a number of sub-assemblies with relationships: a linear relationship between the piston and its housing, 1-degree rotational hinges on the various piston rod assemblies, and a one-degree rotational relationship on the axle to the axle bearings.
But the net result of all of those train parts moving is a -single- movement. For example, any given orientation of the axle relative to the train itself fully defines where all of the parts will end up, and if you drive the axle in an animation, all of the parts have to move along specific paths to keep connectivity.
I don't even know how you would begin to go from low level connectivity to complex movement, but I'd like to have a connectivity spec that does not omit any needed information to be able to someday solve this problem.
Anyway, that's the end of my brain dump - if anyone is already doing this stuff in-app, I'd be curious how the problems were solved.
thanks!
Ben
* as a kid I vaguely remember a huge range of stickiness among my hinges, and having to pick the right hinge for the job due to differences in friction.
I've been playing with the idea of connectivity for a while now, and picked it up again after poking around Moc Builder recently. The main features I'd like to support in Bricksmith with connectivity data are:
- Easy assembling of models (by having Bricksmith know how parts want to "snap" together)
- Easy manipulation of irregular shapes (e.g. hinges at odd angles and technic assemblies) by letting Bricksmith understand how an entire sub-assembly rotates around an arbitrary hinge. (This would make irrelevant the part origin or META commands to "fix" the origin - the connectivity information would specify how a given part can rotate.)
- In an ideal world, Bricksmith would be able to figure out what the "actions" of a given model are. E.g. if you make a car and the doors open, the hood can pop up, and the trunk opens, ideally Bricksmith can, from the connectivity information, derive some kind of higher level "playability" data that describes what the model does. (This goal is much harder than the first two.)
I did some experiments with LDD and found that it goes very far in most of these directions. However, it also hits limits sometimes. For example, I downloaded an LDD build of 70165 (ultra agents HQ) and found that LDD couldn't figure out that the linear assembly of ball joints effectively form a hinge. As a result, the truck walls could not be "opened". LDD does seem to understand complex technic assemblies (at least sometimes) but sometimes moves the model all over the place trying to solve the system of multiple independent hinges.
Anyway, starting with the usual straw man of connector meta-data on parts (e.g. plugs and sockets or receptors modeled after things like stud, hole for stud, technic hole, technic axle, etc.) there are a few problems I'm not quite sure what to do about. This is sort of a brain dump of where I'm at in the design.
1. Friction: ignoring wear-and-tear on your real bricks, the friction of a given hinged connection varies by part. For example, 1x4 brick hinges tend to be very "floppy" and we can almost always assume that if they've been left hanging free, it was the intention of the modeler to make an opening door, moving part, etc. By comparison, 1x2 brick hinges are relatively stiff* and can be used to simply build at a 45 degree angle, or they can show intended motion. (See also 1x2 brick hinges used in place of a 1x2 brick with studs on side before we had SNOT bricks.)
I'm not sure how to determine what is intended "playability" and what is not. One solution is to treat everything that can move as playable, but the result would be that complex bar and clip assemblies (like the carefully modeled bogies that serious train nerds build) would be interpreted as incredibly complex moving parts, when they're really supposed to just sit there looking nice.
2. Movement limits: both MocBuilder and LDD support AABB collision testing on bricks, which helps solve the "it can't rotate any more because it bonks itself" problem. But it would still be nice to get -exact- rotation limits out of a given system. E.g. every 1x2 brick can rotate 0 to 90 degrees at most. To determine this from AABB, we'd be forced to build very complex AABB models of the hinge itself. Ideally an LDraw client would be able to determine some rotation information while punting on collision detection, or be able to operate even if the entire LDraw library wasn't correctly AABB modeled. (Realistically I think we could get partial connectivity implemented relatively quickly for a subset of parts, but having an AABB on every single part is a huge undertaking.)
3. Complex movement. A series of hinged assemblies may define a single play movement because of limits to interaction between moving parts. For example, consider a train with working steam pistons. A low level analysis of connectivity would reveal a number of sub-assemblies with relationships: a linear relationship between the piston and its housing, 1-degree rotational hinges on the various piston rod assemblies, and a one-degree rotational relationship on the axle to the axle bearings.
But the net result of all of those train parts moving is a -single- movement. For example, any given orientation of the axle relative to the train itself fully defines where all of the parts will end up, and if you drive the axle in an animation, all of the parts have to move along specific paths to keep connectivity.
I don't even know how you would begin to go from low level connectivity to complex movement, but I'd like to have a connectivity spec that does not omit any needed information to be able to someday solve this problem.
Anyway, that's the end of my brain dump - if anyone is already doing this stuff in-app, I'd be curious how the problems were solved.
thanks!
Ben
* as a kid I vaguely remember a huge range of stickiness among my hinges, and having to pick the right hinge for the job due to differences in friction.