45 std::array<int32_t, 4>
MultiplyQuaternion(
const std::array<int32_t, 4>& a,
const std::array<int32_t, 4>& b) {
46 const auto product = [](int32_t x, int32_t y) {
47 return (int64_t)x * y;
49 const int64_t x = product(a[3], b[0]) + product(a[0], b[3]) + product(a[1], b[2]) - product(a[2], b[1]);
50 const int64_t y = product(a[3], b[1]) - product(a[0], b[2]) + product(a[1], b[3]) + product(a[2], b[0]);
51 const int64_t z = product(a[3], b[2]) + product(a[0], b[1]) - product(a[1], b[0]) + product(a[2], b[3]);
52 const int64_t w = product(a[3], b[3]) - product(a[0], b[0]) - product(a[1], b[1]) - product(a[2], b[2]);
54 return {(int32_t)(x >> 30), (int32_t)(y >> 30), (int32_t)(z >> 30), (int32_t)(w >> 30)};
58 std::array<int32_t, 4>
AxisRotation(uint32_t axis, uint32_t angle) {
59 const FxSinCos halfAngle = FxSinCosTurn32(angle / 2);
60 std::array<int32_t, 4> rotation{0, 0, 0, halfAngle.cosine};
61 rotation[axis] = halfAngle.sine;
80 constexpr int64_t INNER_HALF = 3 *
METER / 2;
81 constexpr int64_t THICK_HALF =
METER / 10;
82 constexpr int64_t HEIGHT_HALF = 3 *
METER / 2;
83 constexpr int64_t OFFSET = INNER_HALF + THICK_HALF;
84 constexpr int64_t LONG_HALF = INNER_HALF + 2 * THICK_HALF;
86 const std::array<PhysicsSceneBody, 4> walls{{
87 {.halfExtent = {THICK_HALF, HEIGHT_HALF, LONG_HALF}, .position = {OFFSET, HEIGHT_HALF, 0}},
88 {.halfExtent = {THICK_HALF, HEIGHT_HALF, LONG_HALF}, .position = {-OFFSET, HEIGHT_HALF, 0}},
89 {.halfExtent = {LONG_HALF, HEIGHT_HALF, THICK_HALF}, .position = {0, HEIGHT_HALF, OFFSET}},
90 {.halfExtent = {LONG_HALF, HEIGHT_HALF, THICK_HALF}, .position = {0, HEIGHT_HALF, -OFFSET}},
94 scene.
bodies.push_back(wall);
96 scene.
bodies[scene.
bodies.size() - 4].removeTick = removeTick;
101 std::array<int64_t, 3> sideMillimeters{};
102 for (uint32_t axis = 0; axis < 3; ++axis)
103 sideMillimeters[axis] = 250 + FxRandomBelow(FxHash64(seed, axis, index,
PURPOSE_SIZE), 751);
105 const bool isRock = FxRandomBelow(FxHash64(seed, 0, index,
PURPOSE_DENSITY), 2) == 1;
106 const uint64_t densityKgPerCubicMeter = isRock ? 2700 : 300;
107 const auto volumeCubicMillimeters = (uint64_t)(sideMillimeters[0] * sideMillimeters[1] *
112 constexpr std::array<std::array<int64_t, 2>, 4> COLUMNS{{{1, 1}, {-1, -1}, {-1, 1}, {1, -1}}};
113 const auto& column = COLUMNS[index % 4];
114 const auto jitter = [&](uint32_t axis) {
115 return (int64_t)FxRandomBelow(FxHash64(seed, axis, index,
PURPOSE_JITTER), (uint32_t)(
METER / 10)) -
123 .massMilligrams = densityKgPerCubicMeter * volumeCubicMillimeters / 1000,
124 .position = {column[0] * 7 *
METER / 10 + jitter(0), 7 *
METER, column[1] * 7 *
METER / 10 + jitter(2)},