[forum知見] Thyme で物理機構を構築・制御

medaka 返信: 0件 2ヶ月前
  • Algodoo Forum http://www.algodoo.com/forum/ の会話ログから、codex (GPT-5.6 Sol) に抜粋させた
  • 単なるシーン紹介やコンテスト投稿は除外し、API の使い方、動作確認、失敗例、開発者回答を優先した。
  • 確度は次の意味で付けた。
  • 確認済み: 開発者回答、複数投稿での照合、または質問者による動作確認がある。
  • 有力: 実働コードまたは熟練ユーザーの説明があるが、バージョン横断の確認が弱い。
  • 要検証: 古い版限定、既知バグ、提案段階、または投稿間で矛盾する。

まず押さえるべき結論

  1. 車輪や可動リンクは、形を重ねるだけでは接続されない。Scene.addHinge に実在する 2 つの geomID と接続位置を渡す必要がある。
  2. ジョイントには geom0pos / geom1pos または pos を必ず指定する。ID だけのヒンジは古い版でクラッシュ原因にもなった。
  3. glued := true 単独は生成時に効かなかった例がある。背景固定の確実な旧来手法は body := 0、または背景との Scene.addFixjoint。
  4. entityID、geomID、body を保存済みオブジェクトから丸ごとコピーして生成コードに残すと、誤結合・接着・Bad body not in scene の原因になる。生成テンプレートは必要な属性だけに絞る。
  5. materialVelocity は物体そのものの速度ではなく、接触面の搬送速度である。接触と摩擦がなければ駆動しない。
  6. 高速車輪の震えは、真円を使う、ヒンジを legacyMode := 0 にする、密度や sim.frequency を上げる、という順で切り分ける。

1. geometry / body / entity の識別と生成

1.1 最小限の属性だけで生成する

Scene.addCircle、Scene.addBox、Scene.addPolygon の {} 内に必要な属性だけを書く。省略した属性にはシーン既定値が入る。生成時の代入には := を使う。イベント内で = を使うと、生成元オブジェクトの属性を変更してしまうことがある。

wheel := Scene.addCircle({
  pos := [-1.5, 0.5];
  radius := 0.45;
  density := 2.0;
  friction := 1.0;
  restitution := 0.0;
  collideSet := 1
})
  • 根拠: topic 11146, post 80566 は主要属性と := / = の違いを説明。
  • 照合: topic 9966, posts 68471/68483 はコピーした entityID や body が「勝手に接着する」原因になり得るため、不要属性を除くよう勧告。
  • 確度: 確認済み
  • バージョン注意: 2.1.0 のシリアライズ出力には多数の読み取り専用・派生属性が含まれる。保存データ全体を生成テンプレートとして再利用しない。

1.2 body は「接着・固定で一体化した剛体グループ」

フォーラムの変数表では body は「この geometry が属する、互いに固定された物体グループの ID」。geomID は geometry の ID、entityID は hinge や tracer を含む entity の ID と整理されている。

// 背景ボディに所属させる旧来の固定方法
Scene.addBox({pos := [0, -1]; size := [8, 0.5]; body := 0})
  • 根拠: topic 83, post 1038 の属性定義。
  • 罠: topic 10452, post 71259 ではコピーされた body / ID を持つ生成物から Bad body not in scene が出ている。
  • 確度: 確認済み
  • バージョン注意: body の数値は永続的なユーザー ID とみなさない。生成物を既存 body に結合する用途は特に 2.1 の既知問題がある。

1.3 Scene.add* の戻り値を保持して操作できる

Scene.addCircle 等は生成 entity を返し、その参照を変数に保持して属性を変更できる。

o := Scene.addCircle({pos := [0, 2]; radius := 0.2});
o.vel = [5, 0];
o.color = [1, 0, 0, 1]
  • 根拠: topic 1714, post 18686 は (scene.addBox({})).density = 2 の戻り値操作を説明。
  • 照合: topic 9033, post 66290 は scene.my.box = scene.addBox({...}) とイベント参照 e.this/e.other/e.geom を推奨。
  • 確度: 有力
  • バージョン注意: topic 3285 では動的 entity の参照を Scene.my に保存すると save/load 後に壊れるという旧版バグが報告されている。長期参照は再取得または再初期化する。

1.4 ID は save/load や undo 後に変わり得る

ハードコードした geomID / entityID をシーン再読込後も不変と仮定しない。

// entity 側の onSpawn などで、その実行時の ID を保存する案
onSpawn := (e) => { Scene.my.wheelGeom = (readable(e.this)).geomID }
  • 根拠: topic 10224, posts 69742-69787 は geomID と entityID が再読込で変化することを実測。
  • 照合: topic 2279, post 29035 は undo 後の ID 変化で動的チェーン生成が壊れると報告。
  • 確度: 確認済み
  • 矛盾: 2009-2015 年の多数の例は geomID := 1 のような指定 ID を利用する一方、topic 11146, post 85891 は 2.1 系で任意 ID の強制はできないと指摘。現在ランタイムでの実測が必要。

2. hinge / axle / motor

2.1 ヒンジ生成の最小要件

ヒンジ(UI 上の axle)は 2 つの geometry、または geometry と背景を接続する。geom0、geom1 と接続位置が必要。

Scene.addHinge({
  geom0 := chassisGeom;
  geom1 := wheelGeom;
  geom0pos := [-1.5, -0.5]; // chassis のローカル座標
  geom1pos := [0, 0];       // wheel のローカル座標
  size := 0.12;
  legacyMode := 0
})
  • 根拠: topic 83, post 3400 は 2 geometry と背景接続の両方を例示。
  • 照合: topic 12132, posts 86258/86403 は pos と size だけでは不足し、4 つの geom/pos 属性が必要だったと解決報告。
  • 座標の根拠: topic 795, post 45569 は geom0pos := [0,0] がその geometry の重心であり、ローカル接続位置だと説明。
  • 確度: 確認済み
  • バージョン注意: 古い形式では world0pos または pos でも設置できる。現行生成でどの形式を採るかはランタイムで統一して検証する。

2.2 接続位置を省略しない

Scene.addBox({geomID := 1755});
Scene.addHinge({geom0 := 1755; geom1 := 0; pos := [0, 0]})
  • 根拠: 開発者 emilk の topic 2279, post 29018 は geom0pos / geom1pos または pos を必ず指定すべきで、省略は旧版でクラッシュにつながり得たと説明。
  • 確度: 確認済み
  • バージョン注意: 上の geomID := 1755 は 1.7.4 の再現例であり、2.1 で任意 ID 指定が保証されるという意味ではない。

2.3 背景は geometry ID 0

Scene.addHinge({
  geom0 := wheelGeom;
  geom1 := 0;
  geom0pos := [0, 0];
  geom1pos := [3, 2]
})
  • 根拠: topic 83, post 3400 の「one hinged object」。
  • 照合: topic 10551, post 72228 は axle が 2 geometry または geometry と背景を結ぶと説明。
  • 確度: 確認済み
  • 注意: geom0 = 0 と geom1 = 0 の両方を指定した無効ヒンジは保存時に消される。

2.4 モーター化と単位

Scene.addHinge({
  geom0 := chassisGeom;
  geom1 := wheelGeom;
  geom0pos := [-1.5, -0.5];
  geom1pos := [0, 0];
  motor := true;
  motorSpeed := 10.0;   // rad/s
  motorTorque := 200.0; // 新しい版では Nm
  autoBrake := true
})
  • 速度: topic 795, posts 42005/42015 は motorSpeed が RPM ではなく rad/s だと照合。
  • 旧仕様: 開発者 emilk の topic 1572, posts 31384/31440 は旧 motor strength が rad/s² で、実トルクは「2 body の合成慣性 × strength」だったと説明。
  • 新仕様: topic 2649, post 31816 は 1.7.5 から motorTorque が真の Nm になり、旧版は同名フィールドを rad/s² と解釈すると説明。
  • 確度: 確認済み
  • バージョン注意: 1.7.5 以降で保存したシーンを 1.7.4 以前で開くとトルクが誤解釈される。現行 2.1 を対象にするなら Nm として扱い、旧シーンの移植時だけ変換を疑う。

2.5 モーター属性の動的制御

ヒンジの motorTorque や motorSpeed に {Scene.my.*} の動的式を設定し、イベント側で値を更新する方法が使われていた。

// console/init
Scene.my.driveTorque = 100.0;

// hinge property
motorTorque := {Scene.my.driveTorque}

// event
Scene.my.driveTorque = 500.0
  • 根拠: topic 3689, posts 41887/41941 は変数を宣言して hinge の motorTorque に動的式を入れる手順を説明。
  • 確度: 有力
  • バージョン注意: topic 2625, posts 31612/31861 では 1.7.5 に {Scene.my.torque} を含む Thyme 生成ヒンジの不具合があり、修正予定と回答。現行で再現しなければ歴史的注意でよい。

2.6 servo / bend のトルク関係

bendConstant == 0 ならトルクは motorTorque。非ゼロなら、おおむね「目標角との差 × bendConstant」を motorTorque で上限クリップする弾性サーボとして働く。

// 概念式
torque = clamp(bendConstant * angleDelta, -motorTorque, motorTorque)
  • 根拠: topic 10163, posts 69165/69198 の実験結果と説明。
  • 確度: 有力
  • バージョン注意: 正式仕様式ではなくユーザーのリバースエンジニアリング。符号、dead-zone、solver 依存は要実測。

2.7 既存 geometry にイベント中から joint を追加する問題

Scene.addHinge({
  geom0 := (readable(e.other)).geomID;
  geom1 := (readable(e.this)).geomID;
  geom0pos := [0, 0];
  geom1pos := [0, 0]
})
  • 根拠: topic 9597, posts 67508-82878 では上記が Couldn't find geom になり、2016 年にも未修正との回答。
  • 照合: topic 11894, posts 85767/85768 は Algodoo 2.1 で既存 geometry への接続・glue が壊れており、稀に fixate が動いても undo で壊れると報告。
  • 確度: 要検証
  • 矛盾: 1.7.x の開発者例と新規生成直後の joint は動く一方、2.1 のイベント経由・既存物接続で失敗報告がある。MCP では「形状生成 → 実 ID 取得 → 同一スクリプト/直後に joint 生成」をまず実測し、後付け接続を別テストにする。

3. fixate / glued / static

3.1 2 geometry を fixate する

Scene.addFixjoint({
  geom0 := geomA;
  geom1 := geomB;
  world0pos := [0, 0]
})
  • 根拠: topic 795, post 8014 は hinge と同じ要領で geom0 / geom1 / world0pos を指定する例を掲載。
  • 属性一覧: topic 83, post 1038 は Scene.addFixjoint の geom/world position 属性を列挙。
  • 確度: 確認済み
  • バージョン注意: 表記は addFixjoint と addFixJoint が混在する。Thyme は例で大文字小文字が混用されているが、生成コードでは Scene.addFixjoint に統一する。

3.2 背景固定は body := 0 が簡単

Scene.addCircle({pos := [0, 1]; radius := 0.2; body := 0})
  • 根拠: topic 1010, posts 9951-9995 で glued := true 単独は生成時に効かず、body := 0 は実際に背景へ glue されたと確認。
  • 照合: topic 1768, post 19193 も同じ生成例を掲載。
  • 確度: 確認済み
  • バージョン注意: 現在の保存データは body := 0; glued := true の組を持つことがある。明示したい場合は両方を設定するが、glued 単独には頼らない。

3.3 density := +inf は「固定に近い代用」で、glue と同じではない

e.this.density = +inf
  • 根拠: topic 2856, posts 33679-34876 で動作確認される一方、最終的に通常の背景 glue は body := 0; glued := true と区別。
  • 確度: 確認済み
  • 罠: 無限密度は solver、慣性、接触計算に副作用がある。背景固定の意味が必要なら body := 0 または fixjoint を使う。

3.4 static := true は確認できない

抽出コーパスの geometry 属性一覧と実働例に static フィールドは見つからなかった。Algodoo の静的物体を他エンジン風に static := true で生成できるとは仮定しない。

// 推奨
body := 0;
glued := true
  • 根拠: body / glued の複数スレッドと topic 83 の属性表。
  • 確度: 有力
  • バージョン注意: MCP 側で独自に static を変換する場合は別だが、Thyme の生属性としては要検証。

4. spring

4.1 旧来の直接生成

2 geometry の ID、両端の位置、必要なら length、constant、dampingFactor を指定する。

Scene.addSpring({
  geom0 := geomA;
  geom1 := geomB;
  world0pos := [0, 2];
  world1pos := [2, 2];
  length := 1.5;
  constant := 100.0;
  dampingFactor := 0.2
})
  • 根拠: topic 795, post 8014 の生成例と属性説明。
  • 照合: topic 83, post 3400 は背景接続と 2 geometry 接続の要件を説明。
  • 確度: 確認済み(旧 API)
  • バージョン注意: geom0pos/geom1pos と world0pos/world1pos の意味・対応は版により混乱がある。生成後に端点位置を目視検証する。

4.2 1.9 以降の LineEndPoint 形式

新しい保存形式では spring 本体と 2 つの LineEndPoint が別 entity になり、spring が endpoint の entity ID を参照する。

ep0 := Scene.addLineEndPoint({geom := geomA; relPoint := [0, 0]});
ep1 := Scene.addLineEndPoint({geom := geomB; relPoint := [0, 0]});
Scene.addSpring({
  lineEndPoint0 := (readable(ep0)).entityID;
  lineEndPoint1 := (readable(ep1)).entityID;
  length := 1.0;
  constant := 100.0;
  dampingFactor := 0.2;
  legacyMode := 3
})
  • 根拠: topic 4036, post 46053 は 1.9.4 spring が spring + 2 endpoint になったと報告。
  • 2.1 例: topic 12675, post 87550 の保存コードは Scene.addLineEndPoint 2 個と Scene.addSpring { lineEndPoint0; lineEndPoint1; ... } を使用。
  • 確度: 有力
  • バージョン注意: 上の (readable(ep)).entityID 取得形はコーパス内で直接動作確認されていない合成例。2.1 の実 ID 取得をランタイムで検証する。

4.3 Scene.addSpring の版別不具合

Scene.addSpring({
  geom0 := 0;
  geom1 := 13;
  geom0pos := [1, 1];
  geom1pos := [0, 0];
  length := 1
})
  • 根拠: topic 4442, posts 49479/49489 は 1.9.8 で戻り値は spring でも表示されない回帰を再現し、開発者が修正すると回答。
  • 確度: 確認済み(1.9.8 回帰)
  • 対応: 現行で direct API が出ない場合は endpoint 形式を試す。逆に direct API が動くなら簡潔な方を使う。

4.4 spring パラメータの安定性

constant と dampingFactor を質量に対して大きくしすぎると振動・爆発しやすい。サスペンションでは damping 最大が常に最適ではない。

// 初期値は控えめにし、実行テストで上げる
constant := 100.0;
dampingFactor := 0.2
  • 根拠: topic 2826, post 33406 の suspension ガイド。
  • 確度: 有力
  • バージョン注意: 安定限界は sim.frequency、質量、長さ、solver に依存する固定値ではない。

5. wheel / car の実装指針

5.1 最小の駆動輪

車体 box、車輪 circle、各輪を車体へ接続する motorized hinge の 3 要素が最小構成。

// 形状を作った後、実際の geomID を取得した前提
Scene.addHinge({
  geom0 := chassisGeom;
  geom1 := rearWheelGeom;
  geom0pos := [-1.4, -0.45];
  geom1pos := [0, 0];
  motor := true;
  motorSpeed := -12.0;
  motorTorque := 250.0;
  autoBrake := false;
  legacyMode := 0
})
  • 根拠: hinge/motor の上記各スレッドを組み合わせた合成例。
  • 確度: 有力
  • 最重要検証: 生成した車輪の中心とヒンジ位置が一致すること、ヒンジの両 geomID が 0 ではないことを再生前に確認する。

5.2 collision 用の真円と見た目を分離する

複雑な polygon rim は高速で不安定になりやすい。透明な真円を実際のタイヤにし、装飾 rim は低密度・no-collision にする。

// collision circle
friction := 1.0;
restitution := 0.0;
collideSet := 1;

// decorative rim
density := 0.001;
collideSet := 0

5.3 高速で車輪・ヒンジが震える場合

優先順位は次の通り。

  1. 車輪が polygon ではなく真円か確認。
  2. wheel hinge を legacyMode := 0。
  3. 車輪・接続部の密度を上げる。
  4. sim.frequency を上げる。
  5. 必要なら Sim.limitAngVel を上げるが、安全性は低い。
sim.frequency = 200;
// hinge property
legacyMode := 0

5.4 +inf motorTorque でも滑ることがある

低密度 body では hinge が solver 上「滑る」ため、無限トルクでも完全固定にならない。密度を上げる。

motorTorque := +inf;
// connected body
density := 10.0
  • 根拠: topic 3778, posts 42651-42653。
  • 確度: 有力
  • 注意: +inf は数値不安定の原因にもなるため、必要十分な有限値を優先する。

6. collision layers / self collision / water

6.1 collideSet はビット和

// A=1, B=2, C=4, D=8 ... J=512
// B + C + D
collideSet := 14;
// A-J 全部
collideSet := 1023

6.2 イベント対象の collision layer を変更する

// laser が当たった geometry
e.geom.collideSet = 2;

// 衝突相手
e.other.collideSet = 4
  • 根拠: topic 10778, posts 75779/75782/86087 は e.geom、e.laser、e.this、e.other の使い分けを説明。
  • 確度: 確認済み
  • バージョン注意: 旧 onLazerHit / onLaserHit と新 onHitByLaser の命名が混在する。どちら側の callback かで e.geom / e.laser が変わる。

6.3 self collision と水

heteroCollide := true; // 同一 collideSet 同士の扱いを変更
collideWater := false
  • 根拠: topic 11151, posts 80285/80567 と topic 83, post 1038。
  • 確度: 有力
  • 注意: heteroCollide の説明は投稿内でも紛らわしい。UI の「No self collision」と期待が一致するか、小さな 2-object テストで確認する。

6.4 Algodoo には bitwise operator がない

ランダムな collision layer 組み合わせは、各 bit の 2^i を足し上げる。

collideSet = 0;
for(10, (i) => {
  collideSet = collideSet + rand.boolean * 2^i
})

7. friction / restitution / density

7.1 2 物体間の摩擦・反発は幾何平均

2 geometry の係数を x1, x2 とすると、接触で使われる係数は sqrt(x1*x2)。

// 接触係数を 0.7 にしたい対称設定
friction := math.sqrt(0.7)
  • 摩擦: topic 11312, posts 82211/83126。
  • 反発: topic 8338, post 64823。
  • 開発者由来の照合引用: topic 3272, post 37336 は friction と restitution の両方に sqrt(r1*r2) を使用すると記録。
  • 確度: 確認済み
  • 罠: 一方だけ負値にすると平方根が NaN になり、速度や位置まで壊れる旧実装がある。通常の機構では負の摩擦・反発を使わない。

7.2 static friction は独立パラメータとして存在しない

// 疑似 static friction の一例
math.vec.len(vel) <= 0.1 ? { friction = 2.0 } : { friction = 0.5 }
  • 根拠: topic 11312, posts 82215/82225。
  • 確度: 確認済み
  • 注意: 疑似実装は速度閾値で不連続になり、solver jitter を起こし得る。

7.3 density は kg/m²、質量は面積との積

mass = area * density
  • 根拠: topic 83, post 1038 は density 単位を kg/m² と記載。
  • 照合: topic 83, posts 16858-17170 で mass は area × density と説明。
  • 確度: 確認済み
  • 機構上の含意: 同じ density でも wheel radius や chassis size を変えると質量・慣性が変わり、motorTorque や spring tuning を再調整する必要がある。

7.4 density = 0 を削除 API とみなさない

Algodoo では削除に使われた歴史があるが、Phun 5.28 ではクラッシュする既知バグだった。

// 旧 Phun の代替例
collideSet = 0;
airFrictionMult = NaN
  • 根拠: topic 1175, posts 12099-12105。
  • 確度: 確認済み(歴史的)
  • 現行注意: NaN を入れる手法も周囲を巻き込む危険がある。MCP では正式な削除/kill 操作を優先し、物理属性を壊して消さない。

8. velocity / torque / impulse / materialVelocity

8.1 直接速度を与える

Scene.addCircle({
  pos := [0, 2];
  radius := 0.2;
  vel := [10, 0];
  angvel := 5.0
})
  • 根拠: topic 5127, post 54300 は生成物の初速を vel := [10,0] で設定すると説明。angvel は topic 83, post 1038 の属性表。
  • 確度: 確認済み
  • 注意: vel の直接代入は力積を物理的に積分した結果ではなく、状態の上書き。物理応答を保ちたい制御には motor、spring、thruster を使う。

8.2 materialVelocity は conveyor surface

Scene.addBox({
  pos := [0, 0];
  size := [4, 0.2];
  materialVelocity := 2.0;
  friction := 1.0;
  body := 0
})
  • 根拠: topic 496, post 4171 は conveyor belt と説明。
  • 方向/接触: topic 3375, posts 38506/38509 は接触しないと効かず、垂直移動には垂直面が必要と説明。
  • 確度: 確認済み
  • 罠: materialVelocity は surface tangent 方向。vel の代わりではなく、摩擦を介して接触物へ力を伝える。

8.3 materialVelocity を簡易モーター代わりにする場合

接触 box の materialVelocity を速度、friction を伝達力のように使えるが、片側だけで押すとヒンジを横に引っ張り、車体が跳ねる。両側から対称に当てる。

e.geom.materialVelocity = 100;
e.geom.friction = 500
  • 根拠: topic 3689, posts 42022-42148 は実働と不安定化、その対称配置対策まで記載。
  • 確度: 有力
  • バージョン注意: topic 4094 では 1.9.4 新 solver で消失、topic 4426 では 1.9.9b で修正と記録。現行でも experimental な挙動として回帰テストする。

8.4 applyForce / externalForce はコーパス上では提案段階

// 以下は「欲しい API」として提案された形で、実装確認ではない
object.applyForce([fx, fy])
  • 根拠: topic 2472, post 29636 は機能提案。
  • 照合: topic 1734, posts 18933/38391 の externalForce も要望で、入力しても動かなかったと報告。
  • 確度: 確認済み(未実装/少なくとも当時は利用不可)
  • 推奨: 初速は vel/angvel、継続力は Scene.addThruster、回転は hinge motor、弾性は spring を使う。

8.5 正確な impulse を作るには thruster を時間積分する

Algodoo には直接 impulse API がなかったため、短時間の thruster force を sim.tick / sim.frequency で積分して目標力積へ収束させる方法が使われた。

// 概念: J = integral(F dt)
force := {Scene.my.impRelease}
  • 根拠: topic 4637, posts 51056/51064 は周波数・simulation scale に依存しにくい impulse quantizer を掲載。
  • 確度: 有力
  • 注意: 元コードは長く、半分ずつ誤差を詰める実装。通常の車両制御には過剰で、発射・打撃の再現に限定する。

8.6 hinge の実力・反力・トルクを読む

totImp3 は [Fx impulse, Fy impulse, moment impulse]。1 step 分の impulse なので sim.frequency を掛けると N / Nm 相当になる。

forceX = (readable(entity)).totImp3(0) * sim.frequency;
forceY = (readable(entity)).totImp3(1) * sim.frequency;
torque = (readable(entity)).totImp3(2) * sim.frequency

8.7 breakability は impulseLimit と distanceLimit

Scene.addHinge({
  geom0 := geomA;
  geom1 := geomB;
  pos := [0, 0];
  impulseLimit := 10.0;
  distanceLimit := 0.02
})

9. 物理機構を壊しにくくする開発・検証手順

9.1 生成と接続を分けて検証する

  1. body / wheel geometry だけ生成する。
  2. 実際に割り当てられた geomID を確認する。
  3. motor なし hinge を追加し、再生して接続だけを確認する。
  4. motor := true と低い motorSpeed/motorTorque を追加する。
  5. 速度を上げ、wobble、penetration、constraint stretch を見る。

この順序にすると「形がない」「ID が無効」「接続位置が違う」「motor が強すぎる」を分離できる。

9.2 デバッグ表示と console

App.drawBodyCenters = true;
App.drawCollisions = true
  • 根拠: topic 1019, post 10036 は body center と collision force 表示を複雑機構の診断に推奨。
  • F11 console はエラー確認に使う。同投稿および topic 10004, post 68605 は console の行番号・例外表示を具体例で説明。
  • 確度: 確認済み

9.3 solver の切り分け

薄い geometry の貫通や cam/follower の接触不良では、geometry を厚く・高密度にし、frequency を上げ、それでも必要なら direct contact solve を試す。

sim.frequency = 200;
Sim.directContactSolveAll = true
  • 根拠: topic 11006, posts 78832-78912 で実際に機構が改善。
  • 確度: 確認済み
  • 注意: global solver 設定はシーン全体の速度・互換性・break limit に影響する。最後の手段として使う。

9.4 joint spawn の歴史的な回帰を前提にテストする

  • 1.7.4: position 省略や undo 後の ID で hinge spawn 問題。
  • 1.7.5: 「rare bug with spawning joints from Thyme」を修正。
  • 1.9.8: addSpring が表示されない回帰。
  • 2.1: 既存 geometry への runtime hinge/fixate/glue 追加失敗報告。

  • 根拠: topic 2279, posts 29018/31602、topic 4442、topic 9597、topic 11894。

  • 確度: 確認済み(各版の報告)

MCP / スキルへ反映する際の推奨ルール

  1. geometry 生成後に実 ID を取得できたことを検証してから constraint を生成する。
  2. hinge/fixjoint/spring に endpoint geometry と endpoint position を必須入力として要求する。
  3. 車輪には既定で legacyMode := 0、低 restitution、適度な friction を使う。
  4. static は Thyme へそのまま渡さず、body := 0; glued := true に正規化する。
  5. serializer からコピーした entityID / geomID / body を生成テンプレートに残さない。
  6. materialVelocity を vel と混同しない型・説明にする。
  7. joint 生成後は短時間再生し、接続切れ、constraint stretch、wheel wobble を観測してから完成扱いにする。
  8. active Algodoo 2.1 で「新規生成直後の joint」と「既存 geometry への後付け joint」を別々に回帰テストする。

ログインしてください(返信一覧はログイン後に表示されます。)