LCOV - code coverage report
Current view: top level - src/simlab - WorldHasher.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 91 91
Test Date: 2026-04-10 19:03:25 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2025 aeml
       3              :  *
       4              :  * This program is free software: you can redistribute it and/or modify
       5              :  * it under the terms of the GNU General Public License as published by
       6              :  * the Free Software Foundation, either version 3 of the License, or
       7              :  * (at your option) any later version.
       8              :  *
       9              :  * This program is distributed in the hope that it will be useful,
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12              :  * GNU General Public License for more details.
      13              :  *
      14              :  * You should have received a copy of the GNU General Public License
      15              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      16              :  */
      17              : 
      18              : #include "simlab/WorldHasher.hpp"
      19              : 
      20              : #include "ecs/World.hpp"
      21              : 
      22              : #include <algorithm>
      23              : #include <cstring>
      24              : 
      25              : namespace simlab
      26              : {
      27              : 
      28      2827178 :     void WorldHasher::HashBytes(std::uint64_t& h, const void* data, std::size_t len) const noexcept
      29              :     {
      30      2827178 :         const unsigned char* bytes = static_cast<const unsigned char*>(data);
      31     14135890 :         for (std::size_t i = 0; i < len; ++i)
      32              :         {
      33     11308712 :             h ^= static_cast<std::uint64_t>(bytes[i]);
      34     11308712 :             h *= kPrime;
      35              :         }
      36      2827178 :     }
      37              : 
      38           20 :     std::uint64_t WorldHasher::HashBodies(const std::vector<physics::TransformComponent>& transforms,
      39              :                                           const std::vector<physics::RigidBodyComponent>& bodies) const noexcept
      40              :     {
      41           20 :         std::uint64_t h = kOffset;
      42           20 :         const std::size_t count = std::min(transforms.size(), bodies.size());
      43           60 :         for (std::size_t i = 0; i < count; ++i)
      44              :         {
      45           40 :             const auto& t = transforms[i];
      46           40 :             const auto& b = bodies[i];
      47           40 :             HashBytes(h, &t.x, sizeof(t.x));
      48           40 :             HashBytes(h, &t.y, sizeof(t.y));
      49           40 :             HashBytes(h, &t.rotation, sizeof(t.rotation));
      50           40 :             HashBytes(h, &b.vx, sizeof(b.vx));
      51           40 :             HashBytes(h, &b.vy, sizeof(b.vy));
      52           40 :             HashBytes(h, &b.angularVelocity, sizeof(b.angularVelocity));
      53           40 :             HashBytes(h, &b.mass, sizeof(b.mass));
      54           40 :             HashBytes(h, &b.invMass, sizeof(b.invMass));
      55           40 :             HashBytes(h, &b.inertia, sizeof(b.inertia));
      56           40 :             HashBytes(h, &b.invInertia, sizeof(b.invInertia));
      57           40 :             HashBytes(h, &b.restitution, sizeof(b.restitution));
      58           40 :             HashBytes(h, &b.friction, sizeof(b.friction));
      59              :         }
      60           20 :         return h;
      61              :     }
      62              : 
      63            3 :     std::uint64_t WorldHasher::HashAABBs(const std::vector<physics::AABBComponent>& aabbs) const noexcept
      64              :     {
      65            3 :         std::uint64_t h = kOffset;
      66            9 :         for (const auto& box : aabbs)
      67              :         {
      68            6 :             HashBytes(h, &box.minX, sizeof(box.minX));
      69            6 :             HashBytes(h, &box.minY, sizeof(box.minY));
      70            6 :             HashBytes(h, &box.maxX, sizeof(box.maxX));
      71            6 :             HashBytes(h, &box.maxY, sizeof(box.maxY));
      72              :         }
      73            3 :         return h;
      74              :     }
      75              : 
      76         1465 :     std::uint64_t WorldHasher::HashWorld(const ecs::World& world) const noexcept
      77              :     {
      78         1465 :         std::uint64_t h = kOffset;
      79              : 
      80         1465 :         if (const auto* transforms = world.GetStorage<physics::TransformComponent>())
      81              :         {
      82         1465 :             const auto& entities = transforms->GetEntities();
      83         1465 :             const auto& data = transforms->GetData();
      84       117270 :             for (std::size_t i = 0; i < data.size(); ++i)
      85              :             {
      86       115805 :                 HashBytes(h, &entities[i], sizeof(entities[i]));
      87       115805 :                 HashBytes(h, &data[i].x, sizeof(data[i].x));
      88       115805 :                 HashBytes(h, &data[i].y, sizeof(data[i].y));
      89       115805 :                 HashBytes(h, &data[i].rotation, sizeof(data[i].rotation));
      90              :             }
      91              :         }
      92              : 
      93         1465 :         if (const auto* bodies = world.GetStorage<physics::RigidBodyComponent>())
      94              :         {
      95         1465 :             const auto& entities = bodies->GetEntities();
      96         1465 :             const auto& data = bodies->GetData();
      97       117270 :             for (std::size_t i = 0; i < data.size(); ++i)
      98              :             {
      99       115805 :                 const auto& body = data[i];
     100       115805 :                 HashBytes(h, &entities[i], sizeof(entities[i]));
     101       115805 :                 HashBytes(h, &body.vx, sizeof(body.vx));
     102       115805 :                 HashBytes(h, &body.vy, sizeof(body.vy));
     103       115805 :                 HashBytes(h, &body.lastX, sizeof(body.lastX));
     104       115805 :                 HashBytes(h, &body.lastY, sizeof(body.lastY));
     105       115805 :                 HashBytes(h, &body.lastAngle, sizeof(body.lastAngle));
     106       115805 :                 HashBytes(h, &body.mass, sizeof(body.mass));
     107       115805 :                 HashBytes(h, &body.invMass, sizeof(body.invMass));
     108       115805 :                 HashBytes(h, &body.inertia, sizeof(body.inertia));
     109       115805 :                 HashBytes(h, &body.invInertia, sizeof(body.invInertia));
     110       115805 :                 HashBytes(h, &body.restitution, sizeof(body.restitution));
     111       115805 :                 HashBytes(h, &body.friction, sizeof(body.friction));
     112       115805 :                 HashBytes(h, &body.angularVelocity, sizeof(body.angularVelocity));
     113       115805 :                 HashBytes(h, &body.torque, sizeof(body.torque));
     114       115805 :                 HashBytes(h, &body.angularFriction, sizeof(body.angularFriction));
     115       115805 :                 HashBytes(h, &body.angularDrag, sizeof(body.angularDrag));
     116              :             }
     117              :         }
     118              : 
     119         1465 :         if (const auto* aabbs = world.GetStorage<physics::AABBComponent>())
     120              :         {
     121         1084 :             const auto& entities = aabbs->GetEntities();
     122         1084 :             const auto& data = aabbs->GetData();
     123        26026 :             for (std::size_t i = 0; i < data.size(); ++i)
     124              :             {
     125        24942 :                 HashBytes(h, &entities[i], sizeof(entities[i]));
     126        24942 :                 HashBytes(h, &data[i].minX, sizeof(data[i].minX));
     127        24942 :                 HashBytes(h, &data[i].minY, sizeof(data[i].minY));
     128        24942 :                 HashBytes(h, &data[i].maxX, sizeof(data[i].maxX));
     129        24942 :                 HashBytes(h, &data[i].maxY, sizeof(data[i].maxY));
     130              :             }
     131              :         }
     132              : 
     133         1465 :         if (const auto* circles = world.GetStorage<physics::CircleColliderComponent>())
     134              :         {
     135         1463 :             const auto& entities = circles->GetEntities();
     136         1463 :             const auto& data = circles->GetData();
     137        91604 :             for (std::size_t i = 0; i < data.size(); ++i)
     138              :             {
     139        90141 :                 HashBytes(h, &entities[i], sizeof(entities[i]));
     140        90141 :                 HashBytes(h, &data[i].radius, sizeof(data[i].radius));
     141        90141 :                 HashBytes(h, &data[i].offsetX, sizeof(data[i].offsetX));
     142        90141 :                 HashBytes(h, &data[i].offsetY, sizeof(data[i].offsetY));
     143              :             }
     144              :         }
     145              : 
     146         1465 :         if (const auto* joints = world.GetStorage<physics::DistanceJointComponent>())
     147              :         {
     148          722 :             const auto& entities = joints->GetEntities();
     149          722 :             const auto& data = joints->GetData();
     150         5782 :             for (std::size_t i = 0; i < data.size(); ++i)
     151              :             {
     152         5060 :                 HashBytes(h, &entities[i], sizeof(entities[i]));
     153         5060 :                 HashBytes(h, &data[i].entityA, sizeof(data[i].entityA));
     154         5060 :                 HashBytes(h, &data[i].entityB, sizeof(data[i].entityB));
     155         5060 :                 HashBytes(h, &data[i].targetDistance, sizeof(data[i].targetDistance));
     156         5060 :                 HashBytes(h, &data[i].compliance, sizeof(data[i].compliance));
     157              :             }
     158              :         }
     159              : 
     160         1465 :         return h;
     161              :     }
     162              : }
        

Generated by: LCOV version 2.0-1