Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
physics_world.h
Go to the documentation of this file.
1// physics_world.h — 整数の AVBD(08 §2。T-0016 研究 R-PHYS-1)の CPU の世界。GPU(T-0090、shaders/sim/physics_step.hlsl)のリファレンス。
2// 物ごと・組ごと・接触点ごとの手順と構造体は shaders/common/physics_step.hlsli(GPU と共通)にあり、ここは呼ぶ順番
3// (活性 → 接触の生成と引き継ぎ → β → 硬さの引き継ぎ → 物の初期化 → 線形化 → 彩色 → 反復(途中で接触の探し直し)→ 速度 → 位置の仕上げ)と、
4// 刻みをまたいで残す接触(組ごと)を持つ。組は std::map で (小さい番号, 大きい番号) の順に持つ(GPU は持ち主の物の枠。順番に依存しない理由は physics_step.hlsli)。
5//
6// データの流れ: PhysicsScene(整数の場面)→ PhysicsWorld → Step() を繰り返す → Bodies()・Stats()・StateHash()
7#pragma once
8
9#include <cstdint>
10#include <map>
11#include <utility>
12#include <vector>
13
14#include "common/physics_push.hlsli"
15#include "common/physics_step.hlsli"
16#include "sim/physics_scene.h"
17
18namespace bicameral::sim {
19
20 using PhysicsBody = physics::PxBody;
21 using PhysicsContactPoint = physics::PxContactPoint;
22 using PhysicsManifold = physics::PxManifold;
23
24 // HLSL の構造化バッファと同じ並び(physics_step.hlsli の約束。変えたら GPU のテストも確かめる)
25 static_assert(sizeof(PhysicsBody) == 448);
26 static_assert(sizeof(PhysicsContactPoint) == 368);
27 static_assert(sizeof(PhysicsManifold) == 3016);
28 static_assert(sizeof(physics::PxParameters) == 96);
29
30 // 場面の 1 つの物から、刻みを始める前の物を作る
31 [[nodiscard]] PhysicsBody MakePhysicsBody(const PhysicsSceneBody& source, int64_t rate);
32
33 // 刻みごとの量と、値の幅の記録(研究 R-PHYS-1: 各量の最大のビット数)
35 int64_t maxPenetration = 0; // 刻みの初めの接触の最大の食い込み(2^-20 m)
36 uint32_t contactCount = 0;
37 uint32_t colorCount = 0;
38 uint32_t colorRounds = 0; // 彩色の回数(GPU の回数の上限を決める材料)
39 uint32_t solveFailures = 0; // 6×6 の分解で対角が 0 以下になった回数
40
41 // --- 最大のビット数(符号を除く)---
42 uint32_t solveBits = 0; // 6×6 の途中の解(Q62)
43 uint32_t lhsBits = 0; // H の要素
44 uint32_t rhsBits = 0; // 勾配
45 uint32_t penaltyBits = 0; // 硬さ
46 uint32_t lambdaBits = 0; // λ
47 uint32_t deltaBits = 0; // 変位・回転(2^-32)
48 };
49
51 public:
52 PhysicsWorld(const PhysicsScene& scene, const physics::PxParameters& parameters);
53
54 void Step();
55
56 // 光線(原点 2^-20 m・向き Q1.30 の長さ 1)で押す(T-0098。common/physics_push.hlsli)。刻みと刻みの間に呼ぶ。
57 // 押した物の番号(動く物に当たらなければ UINT32_MAX)
58 uint32_t Push(const physics::PxVec3& origin, const physics::PxVec3& direction,
59 uint32_t impulseMillinewtonSeconds);
60
61 [[nodiscard]] const std::vector<PhysicsBody>& Bodies() const { return m_bodies; }
62 [[nodiscard]] const PhysicsStepStats& Stats() const { return m_stats; }
63 [[nodiscard]] const std::map<std::pair<uint32_t, uint32_t>, PhysicsManifold>& Manifolds() const {
64 return m_manifolds;
65 }
66 [[nodiscard]] uint64_t Tick() const { return m_tick; }
67
68 // 全部の物の位置・向き・速度のハッシュ(2 回の実行の一致・GPU との一致に使う)
69 [[nodiscard]] uint64_t StateHash() const;
70
71 private:
72 void Substep();
73 void UpdateActivity();
74 void UpdateContacts();
75 void UpdateBetas();
76 void WarmStart();
77 void InitializeBodies();
78 void Linearize();
79 void ColorBodies();
80 [[nodiscard]] std::vector<std::vector<uint32_t>> DynamicNeighbors() const;
81 [[nodiscard]] std::vector<uint32_t> ChooseLocalMaxima(
82 const std::vector<std::vector<uint32_t>>& neighbors) const;
83 void AssignSmallestColor(uint32_t index, const std::vector<uint32_t>& neighbors);
84 void RecollideMidStep();
85 void SolveColor(int32_t color, int64_t alphaQ16);
86 void SolveBody(uint32_t index, int64_t alphaQ16);
87 void RecordSystemBits(const physics::PxBodySystem& system);
88 void UpdateDuals(int64_t alphaQ16);
89 void RecordPointBits(const PhysicsContactPoint& point);
90 void UpdateVelocities();
91 void Finish();
92
94 physics::PxParameters m_parameters;
95 int64_t m_rate = 0; // 1 秒あたりの小刻みの数
96 std::vector<PhysicsBody> m_bodies;
97 std::map<std::pair<uint32_t, uint32_t>, PhysicsManifold> m_manifolds;
98 std::vector<std::vector<std::pair<const PhysicsManifold*, bool>>>
99 m_bodyManifolds; // 物ごとの接触(true = 物が A)
100 int32_t m_colorCount = 0;
101 uint64_t m_tick = 0;
103 };
104
105} // namespace bicameral::sim
std::vector< uint32_t > ChooseLocalMaxima(const std::vector< std::vector< uint32_t > > &neighbors) const
void UpdateDuals(int64_t alphaQ16)
std::vector< std::vector< uint32_t > > DynamicNeighbors() const
void SolveBody(uint32_t index, int64_t alphaQ16)
void AssignSmallestColor(uint32_t index, const std::vector< uint32_t > &neighbors)
uint32_t Push(const physics::PxVec3 &origin, const physics::PxVec3 &direction, uint32_t impulseMillinewtonSeconds)
void SolveColor(int32_t color, int64_t alphaQ16)
PhysicsWorld(const PhysicsScene &scene, const physics::PxParameters &parameters)
void RecordPointBits(const PhysicsContactPoint &point)
physics::PxParameters m_parameters
std::map< std::pair< uint32_t, uint32_t >, PhysicsManifold > m_manifolds
const std::map< std::pair< uint32_t, uint32_t >, PhysicsManifold > & Manifolds() const
void RecordSystemBits(const physics::PxBodySystem &system)
std::vector< std::vector< std::pair< const PhysicsManifold *, bool > > > m_bodyManifolds
const std::vector< PhysicsBody > & Bodies() const
std::vector< PhysicsBody > m_bodies
const PhysicsStepStats & Stats() const
physics::PxContactPoint PhysicsContactPoint
PhysicsBody MakePhysicsBody(const PhysicsSceneBody &source, int64_t rate)
physics::PxManifold PhysicsManifold
physics::PxBody PhysicsBody