chore(controller): three-player-controller als Ordner statt Submodul

Das Submodul zeigte auf GitHub, der eingetragene Stand 028c652 lag aber nur
lokal vor: GitHub-Master ac39682 plus Showcase mit Figuren und launch.json.
Frische Klone konnten den Controller deshalb nicht laden. Jetzt liegt dieser
Stand als normaler Ordner im Repo, ohne Verweis auf GitHub.

dist/ und node_modules/ im Controller bleiben ignoriert und werden wie bisher
lokal gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Opus 5 committed 2026-09-15 21:27:03 +02:00
1 parent 780e246fe5
commit fb38652e7f
153 files changed
+42561 -4

No files matched your search

@@ -0,0 +1,56 @@
import type { ContactManifold } from "../contacts/ContactManifold";
import type { ImpulseBody } from "./ImpulseBody";
import { solveFrictionConstraint, warmStartFriction } from "./frictionConstraint";
import {
prepareNormalConstraint,
solveNormalConstraint,
warmStartNormal,
} from "./normalConstraint";
/**
* 共享接触冲量求解器:法向 + 摩擦锥,可选热启动。
* 人物胶囊不走此核(位置推出);轮悬架 / 轮胎仍在车辆模块。
*/
export class ContactImpulseSolver {
velocityIterations = 8; // 速度迭代次数
warmStart = true; // 是否复用上一帧冲量做热启动
/**
* 对单个刚体与一组流形做速度级求解。
* 顺序:准备 bias → 热启动 → 交替解法向 / 摩擦。
*/
solveVelocity(
body: ImpulseBody,
manifolds: ContactManifold[],
dt: number,
): void {
if (!manifolds.length) return;
// 写入弹性与穿透修正用的 biasVelocity
for (const manifold of manifolds) {
for (const point of manifold.contacts) {
prepareNormalConstraint(body, manifold, point, dt);
}
}
// 先施加缓存冲量,减少 resting 抖动
if (this.warmStart) {
for (const manifold of manifolds) {
for (const point of manifold.contacts) {
warmStartNormal(body, manifold, point);
warmStartFriction(body, point);
}
}
}
// PGS:每轮先法向后摩擦
for (let i = 0; i < this.velocityIterations; i++) {
for (const manifold of manifolds) {
for (const point of manifold.contacts) {
solveNormalConstraint(body, manifold, point);
solveFrictionConstraint(body, manifold, point);
}
}
}
}
}