LCOV - code coverage report
Current view: top level - engine/model - ragdoll.h (source / functions) Hit Total Coverage
Test: Libprimis Test Coverage Lines: 2 2 100.0 %
Date: 2024-11-22 05:07:59 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #ifndef RAGDOLL_H_
       2             : #define RAGDOLL_H_
       3             : 
       4             : /* ragdollskel defines a skeletal animation object for use by skelmodel, which
       5             :  * is able to be dynamically modified by physics (rather than by an animation file)
       6             :  *
       7             :  * ragdollskel objects are owned by skelmodel::skeleton objects and therefore there
       8             :  * is exactly one `ragdollskel` no matter how many entities use a particular model
       9             :  */
      10             : class ragdollskel final
      11             : {
      12             :     public:
      13           5 :         ragdollskel() : loaded(false), animjoints(false), eye(-1) {}
      14             : 
      15             :         bool loaded, animjoints;
      16             : 
      17             :         struct tri final
      18             :         {
      19             :             int vert[3];
      20             : 
      21             :             /**
      22             :              * @brief Determines whether two tris share any vertex indices.
      23             :              *
      24             :              * Returns true if the the passed triangle has any of the same vertex indices,
      25             :              * regardless of order (e.g. if this.vert[0] and t.vert[2] are the same, returns true)
      26             :              *
      27             :              * @param t the tri to compare to
      28             :              *
      29             :              * @return true if any indices from this are the same as any from t
      30             :              * @return false if no vertex indices match
      31             :              */
      32             :             bool shareverts(const tri &t) const;
      33             :         };
      34             :         std::vector<tri> tris;
      35             : 
      36             :         struct reljoint final
      37             :         {
      38             :             int bone, parent;
      39             :         };
      40             :         std::vector<reljoint> reljoints;
      41             : 
      42             :         struct vert final
      43             :         {
      44             :             vec pos;
      45             :             float radius, weight;
      46             :         };
      47             :         std::vector<vert> verts;
      48             : 
      49             :         struct joint final
      50             :         {
      51             :             int bone, tri, vert[3];
      52             :             float weight;
      53             :             matrix4x3 orient;
      54             :         };
      55             :         std::vector<joint> joints;
      56             : 
      57             :         struct rotlimit final
      58             :         {
      59             :             int tri[2];
      60             :             float maxangle, maxtrace;
      61             :             matrix3 middle;
      62             :         };
      63             :         std::vector<rotlimit> rotlimits;
      64             : 
      65             :         struct rotfriction final
      66             :         {
      67             :             int tri[2];
      68             :         };
      69             :         std::vector<rotfriction> rotfrictions;
      70             : 
      71             :         struct distlimit final
      72             :         {
      73             :             int vert[2];
      74             :             float mindist, maxdist;
      75             :         };
      76             :         std::vector<distlimit> distlimits;
      77             : 
      78             :         int eye;
      79             : 
      80             :         void setup();
      81             :         void addreljoint(int bone, int parent);
      82             : 
      83             :     private:
      84             :         void setupjoints();
      85             : 
      86             :         /**
      87             :          * @brief Adds indices for rotation frictions.
      88             :          *
      89             :          * For each pair of triangles in the tris vector of this object where one or more
      90             :          * vertices in those two triangles refer to the same vertex, adds a new rotfriction
      91             :          * to the rotfrictions vector with those triangles' indices within the tris vector.
      92             :          *
      93             :          * The rotfrictions vector is cleared before adding these entries; does not append
      94             :          * to existing entries that may be present.
      95             :          */
      96             :         void setuprotfrictions();
      97             : };
      98             : 
      99             : /*
     100             :  * ragdolldata defines a class corresponding to a specific instantiation of a ragdoll
     101             :  * in the context of a dynent. Many ragdolldata objects may point to the same ragdollskel
     102             :  * object.
     103             :  */
     104             : class ragdolldata final
     105             : {
     106             :     public:
     107             :         const ragdollskel *skel;
     108             :         int millis, collidemillis, lastmove;
     109             :         float radius;
     110             :         vec offset, center;
     111             : 
     112             :         //shadows the elements in skel->tris, should not be resized after construction
     113             :         std::vector<matrix3> tris;
     114             : 
     115             :         //shadows the elements in skel->animjoints
     116             :         matrix4x3 *animjoints;
     117             : 
     118             :         //shadows the elements in skel->reljoints
     119             :         dualquat *reljoints;
     120             : 
     121             :         struct vert final
     122             :         {
     123             :             vec oldpos, pos, newpos, undo;
     124             :             float weight;
     125             :             bool collided, stuck;
     126           5 :             vert() : oldpos(0, 0, 0), pos(0, 0, 0), newpos(0, 0, 0), undo(0, 0, 0), weight(0), collided(false), stuck(true) {}
     127             :         };
     128             : 
     129             :         //shadows the elements in skel->verts, should not be resized after construction
     130             :         std::vector<vert> verts;
     131             : 
     132             :         ragdolldata(const ragdollskel *skel, float scale = 1);
     133             :         ~ragdolldata();
     134             : 
     135             :         void move(bool water, float ts);
     136             : 
     137             :         /**
     138             :          * @brief Sets the ragdolldata::animjoints matrix element at index i according to the animation matrix and position
     139             :          *
     140             :          * Const with respect to all other fields within ragdolldata other than animjoints[i].
     141             :          *
     142             :          * The value set at animjoints[i] is not dependent on the value of animjoints[i]
     143             :          * prior to the calculation.
     144             :          *
     145             :          * @param i the index of the joint to calculate
     146             :          * @param anim the animation matrix to transform the joint with
     147             :          */
     148             :         void calcanimjoint(int i, const matrix4x3 &anim);
     149             :         void init(const dynent *d);
     150             : 
     151             :     private:
     152             :         int collisions, floating, unsticks;
     153             :         float timestep, scale;
     154             : 
     155             :         std::vector<matrix3> rotfrictions;
     156             : 
     157             :         /**
     158             :          * @brief Sets new values in the tris matrix vector based on ragdollskel tris
     159             :          *
     160             :          * Const with respect to all values outside of the vector of tris
     161             :          *
     162             :          * Reads values from the associated ragdollskel, and sets the vecs inside the
     163             :          * corresponding matrix in the ragdolldata as follows:
     164             :          *
     165             :          *               /|
     166             :          *              /
     167             :          *          m.c/
     168             :          *            /
     169             :          *        v1 /   m.a     v2
     170             :          *          *---------->*
     171             :          *          |
     172             :          *          |
     173             :          *          |
     174             :          *       m.b|
     175             :          *          v
     176             :          *
     177             :          *
     178             :          *          *
     179             :          *           v3
     180             :          *
     181             :          *        ----→    ----→
     182             :          *  m.c = v1 v2  x v1 v3
     183             :          *        --→   ----→
     184             :          *  m.b = m.c x v1 v2
     185             :          *
     186             :          * m.a points from v1 to v2
     187             :          * m.b points from v1 to v3
     188             :          * m.c points along the normal of the triangle v1, v2, v3
     189             :          *
     190             :          * Prior values that may be in the matrix vector are disregarded and have no
     191             :          * effect on the output values.
     192             :          */
     193             :         void calctris();
     194             : 
     195             :         /**
     196             :          * @brief Calculates the ragdolldata's radius and center position
     197             :          *
     198             :          * Sets the center position to be the average of all the vertices in the ragdoll
     199             :          * Sets the radius to be the distance between the center and the farthest vert
     200             :          *
     201             :          * This is not necessarily the smallest sphere encapsulating all of the points
     202             :          * in the vertex array, since that would be the midpoint of the farthest points in
     203             :          * the vertex array.
     204             :          */
     205             :         void calcboundsphere();
     206             :         void constrain();
     207             :         void constraindist();
     208             : 
     209             :         /**
     210             :          * @brief Applies a rotation around a specified axis to a pair of triangles.
     211             :          *
     212             :          * Modifies the vertices pointed to by the two assigned tri objects by rotating them
     213             :          * to the amount indicated by the angle and about the axis specified by axis.
     214             :          *
     215             :          * @param t1 the first triangle to modify
     216             :          * @param t2 the second triangle to modify
     217             :          * @param angle the angle to rotate by
     218             :          * @param axis the axis by which to rotate around
     219             :          */
     220             :         void applyrotlimit(const ragdollskel::tri &t1, const ragdollskel::tri &t2, float angle, const vec &axis);
     221             :         void constrainrot();
     222             :         void calcrotfriction();
     223             :         void applyrotfriction(float ts);
     224             : 
     225             :         /**
     226             :          * @brief Modifies stuck verticies in the vertex array.
     227             :          *
     228             :          * Only affects those vertices which have the `stuck` field set to `true`.
     229             :          *
     230             :          * Moves those `stuck` vertices towards the average position of the unstuck vertices,
     231             :          * with a magnitude equal to the `speed` parameter.
     232             :          *
     233             :          * @param speed the magnitude by which to modify stuck vertices
     234             :          *
     235             :          */
     236             :         void tryunstick(float speed);
     237             : 
     238             :         /**
     239             :          * @brief Checks collision of `dir` with spherical volume at `pos` with radius `radius`.
     240             :          *
     241             :          * Checks collision of defined sphere with the cubeworld, in direction `dir`.
     242             :          * physics' `collide()` used for collision detection against the cubeworld.
     243             :          *
     244             :          * @param pos positon of sphere center
     245             :          * @param dir direction to check collision against
     246             :          * @param radius radius of sphere center
     247             :          *
     248             :          * @return true if collision occured
     249             :          * @return false if no collision occured
     250             :          */
     251             :         static bool collidevert(const vec &pos, const vec &dir, float radius);
     252             : };
     253             : 
     254             : extern void cleanragdoll(dynent *d);
     255             : 
     256             : #endif

Generated by: LCOV version 1.14