Connectivity Part 50: Travel Limits

Connectivity Part 50: Travel Limits
#1
Hi Y'all,

I have attached a picture of a few hinges to illustrate one of the problems I am still fighting with re: a connectivity spec.

Mario posted an update to his connection model and the resulting discussion covers a model for connection meta-data that is pretty complete.

The issue I want to bring up here is: how do we (and do we even bother to) specify the travel limits for connections that have degrees of freedom (E.g. hinges). Such data isn't necessary for Mario's original purpose (assisted modeling) but it might be useful (in helping to stop the user from going past the legal end of motion for a part).

The question is: can connection travel limits be specified on a per connection basis, or can the data only be determined by looking at -pairs- of connectors? In the example I built, the male/female hinge plates have been swapped with part of standard hinge brick.

The limit when the 2x4 plate is inserted into the 1x2 brick isn't the same as -either- the limits for the plate with another plate or the natural limits for the hinge brick.

I could imagine a big table with pairs of connectors and travel limits, but this seems a little bit scary...
- The data is specific to the -part-, not the -connector-, which means we have to say which connector (on a given part) we are connecting with.
- Thus the number of data points in the table is going to be pretty huge.
- It isn't clear how we'd manage such data in the library - there are two parts the data can be attached to, or it could be in a separate table, but not being able to decompose by part is not good.

Does anyone have any good (or at least not terrible) ideas on this? I can try to put together some kind of straw man proposal but I can't help but think I'm missing a concept we need.

Cheers
Ben

Attached Files Thumbnail(s)

Re: Connectivity Part 50: Travel Limits
#2
I think the info at the part level should only supply it's own absolute limits. Any additional limits resulting from collisions of attached stuff is up to the algorithm using the data.

Problem here is those local limits are usually non existent as they would be completely depended on (very detailed) bounding box information.

So in short I agree with Mario it's a huge task to prevent unrealistic placement just based on connection info.

imho it can only be done (reliably) using full collision detection and or by keeping track of occupied connections etc.
Re: Connectivity Part 50: Travel Limits
#3
Hi Roland,

Right - rotation limits would not be meant to do the job of general AABB testing.

The motivation to have rotation limits would be to get exact limits for absolute limits (e.g. a 1x4 hinge brick - it goes 0-180 degrees, end of story).

- These rotation limits could be easier for apps to access if they don't do full physics.
- These rotation limits could provide -exact- results; I'm not sure that AABB collision testing on the hinge is going to give us the precision we want.

You could argue that the whole thing should be done with AABBs, but I think that in some cases the AABB limiting the hinge itself is very 'tweaky' and would have to be significantly more precise than a general "don't let the bricks totally overlap" mechanism.

cheers
Ben
Re: Connectivity Part 50: Travel Limits
#4
Ben Supnik Wrote:The motivation to have rotation limits would be to get exact limits for absolute limits (e.g. a 1x4 hinge brick - it goes 0-180 degrees, end of story).

Yes but that information is at the combined level of those two sub parts, it's basically specific joint info.

How would you go define limits in the two loose parts? Like I wrote "those local limits are usually non existent as they would be completely depended on (very detailed) bounding box information."

Or do you want to include joint info by setting up a table instead of adding info at the .dat level?
Re: Connectivity Part 50: Travel Limits
#5
Roland Melkert Wrote:Yes but that information is at the combined level of those two sub parts, it's basically specific joint info.

How would you go define limits in the two loose parts? Like I wrote "those local limits are usually non existent as they would be completely depended on (very detailed) bounding box information."

Or do you want to include joint info by setting up a table instead of adding info at the .dat level?

The short answer is, I don't know yet. :-( Here's the total set of ideas, none of which strike me as clear winners:

1. Punt and don't have connection limits. Programs can add collision data to determine limits. This is simple to implement but makes connectivity less useful and makes it a lot harder to limit joint motion (since you have to have collision data and a collision engine just to know that the 1x4 hinge has a stopping point).

2. Giant global table with a pair of parts, some specification of the connections involved, and the limits. This is flexible, but for parts with a lot of connections, specifying -which- connections- are involved might get messy. Consider the simple case of a door frame with a door snapped into it - the door's travel limits are quite different depending on which side of the frame it is snapped into. :-( Having to have a way to "globally address" which connector we are talking about adds complexity to connection specs.

3. Define a range limit on one connector from a connector pair. This works only in the case where the connection's limits are universal - e.g. it's easy for the 1x4 hinge brick (there's only one thing you can connect with that hinge in the real world and its limits are consistent) but works quite badly for, say, a locking hinge (where having the hinge on a tile or plate makes a big difference in range of motion).

4. Defining a range limit on the part level. This has all of the weaknesses of proposal 2 -and- proposal 3! :-(

Quick aside: for -rotational limits- I'm stuck with the above limits. For -translational- limits, I think there's a pretty easy trick: define the translation limit based on the length of the translation connector. This is sort of like (3) except less likely to get us in trouble.

I suppose you could argue that (3) should only be used for rotation when the rotation limit is _part of_ the hinge itself and not the result of some -other- part of the brick crashing into something else.

Similarly, if two parts can translate over a given distance (based on the actual joint) but some other area of a large, complex part has a collision, it would be up to AABB to capture that.

I think when it comes to (3), I am not sure how much value capturing hinge rotation limits is when we only capture the case where the hinge is -guaranteed- to be limited...my fear is that the answer is "not much value here".

(I think capturing the 'grid snapping' of hinges is easier and probably pretty useful.)

cheers
Ben
Re: Connectivity Part 50: Travel Limits
#6
I agree with Mario on the editor side of things. And as software interested in physics probably needs to go the collision detection route anyway I'm gravitating towards it's not worth the effort.

That said we could decide to apply a variant of method 3 but only on the more simple parts like brick hinges and doors etc. For example with the doorframe you could at -90..0 and 0..90 for the front/back points. The door itself has full 360 (the default). So whenever a connection is made the engine just applies the inner join of the female and male limits.

All other parts use the default 360 freedom (The editor preserves current rotation, and only forces the alignment etc) and let the end user to the final check/corrections.
Re: Connectivity Part 50: Travel Limits
#7
Roland Melkert Wrote:I agree with Mario on the editor side of things. And as software interested in physics probably needs to go the collision detection route anyway I'm gravitating towards it's not worth the effort.

That said we could decide to apply a variant of method 3 but only on the more simple parts like brick hinges and doors etc. For example with the doorframe you could at -90..0 and 0..90 for the front/back points. The door itself has full 360 (the default). So whenever a connection is made the engine just applies the inner join of the female and male limits.

All other parts use the default 360 freedom (The editor preserves current rotation, and only forces the alignment etc) and let the end user to the final check/corrections.

Hi Roland,

I think you're right, bott re: the door limit being made to work, and rapidly diminishing returns. If I had to make a call for a spec right now, I'd probably do this:

- Connection instances (that is, placements of connection types via meta directives in a part or primitive) can specify range limitations.
- Hinges would have about as much range limit mechanics as sliders get, but no more, e.g. let's not go crazy trying to solve rotation issues.
- An intrepid part author could solve the 'door' problem because the connections can be put directly on the doors (and not on a -highly- reused part like "stud").
- Such "lucky limitations" where a hinge can be sanely limited in its range would be rare as a percent of the library, but perhaps not so rare as a percent of used bricks, weighted by what are interesting to modelers.

Cheers
Ben
Re: Connectivity Part 50: Travel Limits
#8
I quite like the idea of limiting hinges to what's possible in real life, but I think this has to be incorporated by the programmer programming the editor. I don't think something like that really benefits from being included in the library.

Reason for that is that there's very little use of the limited hinges without other "physics" anyway. For example, if I add a few bricks onto the hinge, the limit in real life would change. In a editor without physics other than the limited hinges, the limited hinge feature already becomes useless.

I think it's best to include nothing more than connection data and bounding boxes in a part. That way, there's nothing really specific like hinge limits and there's enough information for editors to do with it whatever they like.
Re: Connectivity Part 50: Travel Limits
#9
Hi Merlijn,

I don't think I agree with this...let me try to explain why:

Merlijn Wissink Wrote:I quite like the idea of limiting hinges to what's possible in real life, but I think this has to be incorporated by the programmer programming the editor. I don't think something like that really benefits from being included in the library.

I think the benefit of "range" being in the library is to avoid duplicate work. If (1) connectivity is in the library and (2) range is included in connectivity and (3) more than just Bricksmith uses this info then...
- While I am working I decide to set the range limits on a part I am using (a door or a hinge).
- I then submit this to the part tracker as a part update.
- If approved, any other apps using range limits pick this up for free.

In other words, I think the LDraw library is the best coordination medium between apps; I'd like to be able to recycle range data and not have every app that does physics have to rebuild this data by hand.

Let me also argue why non-physics apps might want this:

Quote:Reason for that is that there's very little use of the limited hinges without other "physics" anyway. For example, if I add a few bricks onto the hinge, the limit in real life would change. In a editor without physics other than the limited hinges, the limited hinge feature already becomes useless.

One reason why Alan asked me about connectivity in Bricksmith was that he wanted to be able to rotate groups of parts around their natural hinge point as an -editing operation-. In the attached picture, I built the classic space radar dish pointing forward because it's way, way faster to build when "on grid" - parts can be positioned rapidly on a grid without even having snapping.

But then when I want to tip the dish up, what I'd like to do is rotate a subset of parts around the hinge.

- In the current code, I have to manually enter the numeric rotate point as text. This is a giant PITA.
- With connectivity, Bricksmith would at least be able to know that the hinge has a rotation point around which to turn.
- With rotation limits, Bricksmith would also be able to know that the hinge can go from 0-90 and then must stop.

From an editing standpoint, this last case has the potentially to be a lot more user friendly: the rotation can be free and unconstrained by a grid and -still- not exceed the natural 0-90 bounds. For rotations where the user wants a tweaky weird angle (e.g. the angle is based on some trig relationship and isn't going to fall into a nice grid of every 3 degrees or 5 degrees) having the rotate be off grid but limited is the most user-friendly.

If there's a part that's going to collide, yes, AABBs are needed. But even without them I think that basic rotation limits make modeling easier.

Quote:I think it's best to include nothing more than connection data and bounding boxes in a part. That way, there's nothing really specific like hinge limits and there's enough information for editors to do with it whatever they like.

There's no question that there's no -harm- in leaving limits off the spec...the whole design assumes editors will bring additional functionality to the table. But I also think there is an opportunity cost to not including this kind of data and requiring everyone to re-invent the wheel.

Cheers
Ben

Attached Files Thumbnail(s)

Re: Connectivity Part 50: Travel Limits
#10
Has anyone looked at what they are doing for this with MOCBuilder?

Not all parts have info, but many do. It seems to work pretty good. They are using files with a .conn filename extension for each part. Here is 30179 for example:

9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000 140.000015 -0.000010 39.750000 3.750000 9.750000 30179.dat
9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000 2.250004 -0.000010 39.750000 2.000000 9.750000 30179.dat
9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000 3.625011 -0.000010 39.750000 3.375000 1.125000 30179.dat
9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 38.125004 72.000000 0.000003 1.625000 71.750000 9.750000 30179.dat
9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 -38.124996 72.000000 -0.000022 1.625000 71.750000 9.750000 30179.dat
9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 37.125000 72.000000 0.000002 2.625000 71.750000 1.125000 30179.dat
9 0 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 -37.124996 72.000000 -0.000022 2.625000 71.750000 1.125000 30179.dat
10 0 -10.000000 0.000000 -10.000000 70.000000 148.450012 10.000000 30179.dat
3 23 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 40.000004 0.000000 -9.999997 2 8 18:1:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:1:1,23:4:1,0:4:0,23:4:1,1:4:1,23:4:1,1:4:1,23:4:1,0:4:0,23:4:1,18:1:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:1:1, 30179.dat
2 22 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 40.000004 144.000000 -9.999997 2 8 22:1:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:1:1,22:2:1,15:4:2,9:4:1,15:4:1,9:4:1,15:4:1,9:4:1,15:4:2,22:2:1,22:1:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:1:1, 30179.dat
4 6 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 35.000000 135.250015 6.500001 2 30179.dat
4 6 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 -0.000000 0.000000 1.000000 -34.999996 135.250015 -6.500021 2 30179.dat
6 46 0.000000 0.000000 -1.000000 0.000000 1.000000 0.000000 1.000000 0.000000 0.000000 32.750000 70.250008 7.500001 0.000000 0.000000 0.000000 0.000000 0 30179.dat
6 46 -0.000000 0.000000 1.000000 0.000000 1.000000 0.000000 -1.000000 0.000000 -0.000000 32.750004 70.250008 -6.499999 0.000000 0.000000 0.000000 0.000000 0 30179.dat
6 46 -0.000000 0.000000 1.000000 0.000000 1.000000 0.000000 -1.000000 0.000000 -0.000000 -32.750000 70.250008 -5.500021 0.000000 0.000000 0.000000 0.000000 0 30179.dat
6 46 0.000000 0.000000 -1.000000 0.000000 1.000000 0.000000 1.000000 0.000000 0.000000 -32.750000 70.250008 6.499979 0.000000 0.000000 0.000000 0.000000 0 30179.dat
4 6 -1.000000 0.000000 -0.000000 -0.000000 -1.000000 0.000000 -0.000000 0.000000 1.000000 35.000000 5.250001 6.500001 2 30179.dat
4 6 1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 -0.000000 0.000000 1.000000 -34.999996 135.250015 6.499979 2 30179.dat
4 6 1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 -1.000000 -34.999996 5.250001 6.499979 2 30179.dat
4 6 1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 -1.000000 -34.999996 5.250001 -6.500021 2 30179.dat
4 6 -1.000000 0.000000 -0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -1.000000 35.000004 135.250015 -6.499998 2 30179.dat
4 6 -1.000000 0.000000 -0.000000 -0.000000 -1.000000 0.000000 -0.000000 0.000000 1.000000 35.000004 5.250001 -6.499998 2 30179.dat
Re: Connectivity Part 50: Travel Limits
#11
Also, here is 30179.xml from extracted from LDD for comparison.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<LEGOPrimitive versionMajor="1" versionMinor="0">
<Annotations>
<Annotation aliases="30179"/>
<Annotation designname="FRAME 1X4X6 FOR DOOR"/>
<Annotation maingroupid="225"/>
<Annotation maingroupname="FRAMES, WINDOWS, WALLS AND DOORS"/>
<Annotation platformid="200"/>
<Annotation platformname="SYSTEM"/>
<Annotation version="6"/>
</Annotations>
<Collision>
<Box sX="1.59" sY="0.15" sZ="0.39" angle="0" ax="0" ay="1" az="0" tx="1.2" ty="0.16" tz="0"/>
<Box sX="1.59" sY="0.08" sZ="0.39" angle="0" ax="0" ay="1" az="0" tx="1.2" ty="5.67" tz="0"/>
<Box sX="1.59" sY="0.135" sZ="0.045" angle="0" ax="0" ay="1" az="0" tx="1.2" ty="5.615" tz="0"/>
<Box sX="0.065" sY="2.87" sZ="0.39" angle="0" ax="0" ay="1" az="0" tx="-0.325" ty="2.88" tz="0"/>
<Box sX="0.065" sY="2.87" sZ="0.39" angle="0" ax="0" ay="1" az="0" tx="2.725" ty="2.88" tz="0"/>
<Box sX="0.105" sY="2.87" sZ="0.045" angle="0" ax="0" ay="1" az="0" tx="-0.285" ty="2.88" tz="0"/>
<Box sX="0.105" sY="2.87" sZ="0.045" angle="0" ax="0" ay="1" az="0" tx="2.685" ty="2.88" tz="0"/>
</Collision>
<Connectivity>
<Custom2DField type="23" width="8" height="2" angle="0" ax="0" ay="1" az="0" tx="-0.4" ty="5.76" tz="-0.4">
18:1:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:1:1,
23:4:1,0:4,23:4:1,1:4:1,23:4:1,1:4:1,23:4:1,0:4,23:4:1,
18:1:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:2:1,23:4:1,18:1:1
</Custom2DField>
<Custom2DField type="22" width="8" height="2" angle="0" ax="0" ay="1" az="0" tx="-0.4" ty="0" tz="-0.4">
22:1:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:1:1,
22:2:1,15:4:2,9:4:1,15:4:1,9:4:1,15:4:1,9:4:1,15:4:2,22:2:1,
22:1:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:2:1,22:1:1
</Custom2DField>
<Fixed type="6" axes="2" angle="0" ax="0" ay="1" az="0" tx="-0.2" ty="0.35" tz="0.26"/>
<Fixed type="6" axes="2" angle="180" ax="0" ay="1" az="0" tx="2.6" ty="0.35" tz="-0.26"/>
<Hinge type="46" oriented="0" angle="90" ax="0" ay="1" az="0" tx="-0.11" ty="2.95" tz="0.3"/>
<Hinge type="46" oriented="0" angle="90" ax="0" ay="-1" az="0" tx="-0.11" ty="2.95" tz="-0.26"/>
<Hinge type="46" oriented="0" angle="90" ax="0" ay="-1" az="0" tx="2.51" ty="2.95" tz="-0.22"/>
<Hinge type="46" oriented="0" angle="90" ax="0" ay="1" az="0" tx="2.51" ty="2.95" tz="0.26"/>
<Fixed type="6" axes="2" angle="180" ax="1" ay="0" az="0" tx="-0.2" ty="5.55" tz="0.26"/>
<Fixed type="6" axes="2" angle="180" ax="0" ay="1" az="0" tx="2.6" ty="0.35" tz="0.26"/>
<Fixed type="6" axes="2" angle="180" ax="0" ay="0" az="1" tx="2.6" ty="5.55" tz="0.26"/>
<Fixed type="6" axes="2" angle="180" ax="0" ay="0" az="1" tx="2.6" ty="5.55" tz="-0.26"/>
<Fixed type="6" axes="2" angle="0" ax="0" ay="1" az="0" tx="-0.2" ty="0.35" tz="-0.26"/>
<Fixed type="6" axes="2" angle="180" ax="1" ay="0" az="0" tx="-0.2" ty="5.55" tz="-0.26"/>
</Connectivity>
<PhysicsAttributes inertiaTensor="12.77819,0,0,0,4.33423,0,0,0,16.84365" centerOfMass="1.2,2.96246,0" mass="2.90000009537" frictionType="0"/>
<Bounding>
<AABB minX="-0.4" minY="0" minZ="-0.4" maxX="2.8" maxY="5.938" maxZ="0.4"/>
</Bounding>
<GeometryBounding>
<AABB minX="-0.4" minY="0" minZ="-0.4" maxX="2.8" maxY="5.938" maxZ="0.4"/>
</GeometryBounding>
</LEGOPrimitive>
Re: Connectivity Part 50: Travel Limits
#12
I looked at the code a bit when Henry first posted, but with no documentation, no comments, and a big file full of numbers, it wasn't immediately obvious how the system's -details- worked. I'm still hoping that someone involved can post a design spec for the connectivity code. It seems similar in overall design to a number of other proposed systems (there is a lot of overlap between various proposed systems, which I think is a good sign) but at this point to me the interesting part is the details.

cheers
ben
Re: Connectivity Part 50: Travel Limits
#13
I looked at the MocBuilder source code when it was first announced, but with no comments in the code and no specs for the connectivity design, I couldn't easily tell how some of the details of the design worked; there's a lot of "magic numbers" directly in the source, etc. I'm still hoping Henry or someone posts a design spec, similar to what Mario did.

The overall design appeared to be similar to a number of other proposed and implemented designs - it seems all connectivity designs converge a bit, which is a good sign. But the details are what I am most interested in.
« Next Oldest | Next Newest »

Forum Jump:

Users browsing this thread: 1 Guest(s)