Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ragdoll.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm> // for max
4 
5 #include "inexor/network/SharedVar.hpp" // for SharedVar
6 #include "inexor/physics/physics.hpp" // for collide
7 #include "inexor/shared/cube_loops.hpp" // for i, loopv, k, loopk, j, loopi
8 #include "inexor/shared/cube_vector.hpp" // for vector
9 #include "inexor/shared/ents.hpp" // for dynent, ::ENT_BOUNCE, physent
10 #include "inexor/shared/geom.hpp" // for vec, matrix4x3, matrix3
11 
12 extern void moveragdoll(dynent *d);
13 extern void cleanragdoll(dynent *d);
14 
16 {
17  struct vert
18  {
20  float radius, weight;
21  };
22 
23  struct tri
24  {
25  int vert[3];
26 
27  bool shareverts(const tri &t) const
28  {
29  loopi(3) loopj(3) if(vert[i] == t.vert[j]) return true;
30  return false;
31  }
32  };
33 
34  struct distlimit
35  {
36  int vert[2];
37  float mindist, maxdist;
38  };
39 
40  struct rotlimit
41  {
42  int tri[2];
43  float maxangle;
45  };
46 
47  struct rotfriction
48  {
49  int tri[2];
51  };
52 
53  struct joint
54  {
55  int bone, tri, vert[3];
56  float weight;
58  };
59 
60  struct reljoint
61  {
62  int bone, parent;
63  };
64 
66  int eye;
74 
75  ragdollskel() : loaded(false), animjoints(false), eye(-1) {}
76 
77  void setupjoints()
78  {
79  loopv(verts) verts[i].weight = 0;
80  loopv(joints)
81  {
82  joint &j = joints[i];
83  j.weight = 0;
84  vec pos(0, 0, 0);
85  loopk(3) if(j.vert[k]>=0)
86  {
87  pos.add(verts[j.vert[k]].pos);
88  j.weight++;
89  verts[j.vert[k]].weight++;
90  }
91  if(j.weight) j.weight = 1/j.weight;
92  pos.mul(j.weight);
93 
94  tri &t = tris[j.tri];
95  matrix4x3 &m = j.orient;
96  const vec &v1 = verts[t.vert[0]].pos,
97  &v2 = verts[t.vert[1]].pos,
98  &v3 = verts[t.vert[2]].pos;
99  m.a = vec(v2).sub(v1).normalize();
100  m.c.cross(m.a, vec(v3).sub(v1)).normalize();
101  m.b.cross(m.c, m.a);
102  m.d = pos;
103  m.transpose();
104  }
105  loopv(verts) if(verts[i].weight) verts[i].weight = 1/verts[i].weight;
106  reljoints.shrink(0);
107  }
108 
110  {
111  rotfrictions.shrink(0);
112  loopv(tris) for(int j = i+1; j < tris.length(); j++) if(tris[i].shareverts(tris[j]))
113  {
114  rotfriction &r = rotfrictions.add();
115  r.tri[0] = i;
116  r.tri[1] = j;
117  }
118  }
119 
120  void setup()
121  {
122  setupjoints();
124 
125  loaded = true;
126  }
127 
128  void addreljoint(int bone, int parent)
129  {
130  reljoint &r = reljoints.add();
131  r.bone = bone;
132  r.parent = parent;
133  }
134 };
135 
137 {
138  struct vert
139  {
141  float weight;
143 
144  vert() : pos(0, 0, 0), newpos(0, 0, 0), weight(0), collided(false), stuck(true) {}
145  };
146 
155 
156  ragdolldata(ragdollskel *skel, float scale = 1);
157 
159  {
160  delete[] verts;
161  delete[] tris;
162  if(animjoints) delete[] animjoints;
163  if(reljoints) delete[] reljoints;
164  }
165 
166  void calcanimjoint(int i, const matrix4x3 &anim)
167  {
168  if(!animjoints) return;
169  ragdollskel::joint &j = skel->joints[i];
170  vec pos(0, 0, 0);
171  loopk(3) if(j.vert[k]>=0) pos.add(verts[j.vert[k]].pos);
172  pos.mul(j.weight);
173 
174  ragdollskel::tri &t = skel->tris[j.tri];
175  matrix4x3 m;
176  const vec &v1 = verts[t.vert[0]].pos,
177  &v2 = verts[t.vert[1]].pos,
178  &v3 = verts[t.vert[2]].pos;
179  m.a = vec(v2).sub(v1).normalize();
180  m.c.cross(m.a, vec(v3).sub(v1)).normalize();
181  m.b.cross(m.c, m.a);
182  m.d = pos;
183  animjoints[i].transposemul(m, anim);
184  }
185 
186  void calctris()
187  {
188  loopv(skel->tris)
189  {
190  ragdollskel::tri &t = skel->tris[i];
191  matrix3 &m = tris[i];
192  const vec &v1 = verts[t.vert[0]].pos,
193  &v2 = verts[t.vert[1]].pos,
194  &v3 = verts[t.vert[2]].pos;
195  m.a = vec(v2).sub(v1).normalize();
196  m.c.cross(m.a, vec(v3).sub(v1)).normalize();
197  m.b.cross(m.c, m.a);
198  }
199  }
200 
202  {
203  center = vec(0, 0, 0);
204  loopv(skel->verts) center.add(verts[i].pos);
205  center.div(skel->verts.length());
206  radius = 0;
207  loopv(skel->verts) radius = std::max(radius, verts[i].pos.dist(center));
208  }
209 
210  void init(dynent *d)
211  {
212  extern SharedVar<int> ragdolltimestepmin;
213  float ts = ragdolltimestepmin/1000.0f;
214  loopv(skel->verts) (verts[i].oldpos = verts[i].pos).sub(vec(d->vel).add(d->falling).mul(ts));
215  timestep = ts;
216 
217  calctris();
218  calcboundsphere();
219  offset = d->o;
220  offset.sub(skel->eye >= 0 ? verts[skel->eye].pos : center);
221  offset.z += (d->eyeheight + d->aboveeye)/2;
222  }
223 
224  void move(dynent *pl, float ts);
225  void updatepos();
226  void constrain();
227  void constraindist();
228  void applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t2, float angle, const vec &axis);
229  void constrainrot();
230  void calcrotfriction();
231  void applyrotfriction(float ts);
232  void tryunstick(float speed);
233 
234  static inline bool collidevert(const vec &pos, const vec &dir, float radius)
235  {
236  static struct vertent : physent
237  {
238  vertent()
239  {
240  type = ENT_BOUNCE;
241  radius = xradius = yradius = eyeheight = aboveeye = 1;
242  }
243  } v;
244  v.o = pos;
245  if(v.radius != radius) v.radius = v.xradius = v.yradius = v.eyeheight = v.aboveeye = radius;
246  return collide(&v, dir, 0, false);
247  }
248 };
vec c
Definition: geom.hpp:904
Definition: geom.hpp:902
vert()
Definition: ragdoll.hpp:144
matrix3 middle
Definition: ragdoll.hpp:50
void setupjoints()
Definition: ragdoll.hpp:77
vert * verts
Definition: ragdoll.hpp:151
int vert[3]
Definition: ragdoll.hpp:55
Definition: ragdoll.hpp:60
void cleanragdoll(dynent *d)
Definition: ragdoll.cpp:315
const T & max(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:224
bool shareverts(const tri &t) const
Definition: ragdoll.hpp:27
Definition: ragdoll.hpp:15
vec b
Definition: geom.hpp:670
void setuprotfrictions()
Definition: ragdoll.hpp:109
bool collided
Definition: ragdoll.hpp:142
float maxangle
Definition: ragdoll.hpp:43
vector< reljoint > reljoints
Definition: ragdoll.hpp:73
bool stuck
Definition: ragdoll.hpp:142
void calcboundsphere()
Definition: ragdoll.hpp:201
void constraindist()
Definition: ragdoll.cpp:41
dualquat * reljoints
Definition: ragdoll.hpp:154
float weight
Definition: ragdoll.hpp:56
vec & mul(const vec &o)
scalar multiplication
Definition: geom.hpp:168
vector< distlimit > distlimits
Definition: ragdoll.hpp:69
int floating
Definition: ragdoll.hpp:148
vec pos
Definition: ragdoll.hpp:140
float scale
Definition: ragdoll.hpp:150
float radius
Definition: ragdoll.hpp:150
int collisions
Definition: ragdoll.hpp:148
void transposemul(const matrix4x3 &m, const matrix4x3 &n)
Definition: geom.hpp:1029
void applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t2, float angle, const vec &axis)
Definition: ragdoll.cpp:63
float weight
Definition: ragdoll.hpp:20
int tri[2]
Definition: ragdoll.hpp:49
vector< rotlimit > rotlimits
Definition: ragdoll.hpp:70
void init(dynent *d)
Definition: ragdoll.hpp:210
void setup()
Definition: ragdoll.hpp:120
int collidemillis
Definition: ragdoll.hpp:148
Definition: geom.hpp:668
Definition: ents.hpp:128
vec c
Definition: geom.hpp:670
float mindist
Definition: ragdoll.hpp:37
Definition: ragdoll.hpp:17
int bone
Definition: ragdoll.hpp:62
vec b
Definition: geom.hpp:904
Definition: geom.hpp:536
vector< vert > verts
Definition: ragdoll.hpp:67
vec newpos
Definition: ragdoll.hpp:140
ragdollskel()
Definition: ragdoll.hpp:75
ragdollskel * skel
Definition: ragdoll.hpp:147
Definition: ragdoll.hpp:47
Definition: ragdoll.hpp:136
vec center
Definition: ragdoll.hpp:149
else loopi(numargs)
Definition: command.cpp:3019
void calcanimjoint(int i, const matrix4x3 &anim)
Definition: ragdoll.hpp:166
Definition: ragdoll.hpp:138
vector< joint > joints
Definition: ragdoll.hpp:72
void calcrotfriction()
Definition: ragdoll.cpp:114
float eyeheight
Definition: ents.hpp:135
void constrain()
Definition: ragdoll.cpp:200
~ragdolldata()
Definition: ragdoll.hpp:158
bool animjoints
Definition: ragdoll.hpp:65
vec d
Definition: geom.hpp:904
matrix3 middle
Definition: ragdoll.hpp:44
Definition: ragdoll.hpp:23
float radius
Definition: ragdoll.hpp:20
void move(dynent *pl, float ts)
Definition: ragdoll.cpp:213
vec oldpos
Definition: ragdoll.hpp:140
void tryunstick(float speed)
Definition: ragdoll.cpp:151
matrix3 * tris
Definition: ragdoll.hpp:152
float aboveeye
Definition: ents.hpp:135
vector with 3 floats and some useful methods.
Definition: geom.hpp:110
vector< tri > tris
Definition: ragdoll.hpp:68
vec falling
Definition: ents.hpp:130
vec & sub(const vec &o)
scalar subtraction
Definition: geom.hpp:177
matrix4x3 * animjoints
Definition: ragdoll.hpp:153
Definition: ragdoll.hpp:34
Definition: ragdoll.hpp:40
vec a
Definition: geom.hpp:670
float weight
Definition: ragdoll.hpp:141
int length() const
return size of used memory
Definition: cube_vector.hpp:146
Definition: ents.hpp:124
vector< rotfriction > rotfrictions
Definition: ragdoll.hpp:71
int d
Definition: octaedit.cpp:1749
void t(T x, const char *cmp)
Definition: utilTest.cpp:52
void constrainrot()
Definition: ragdoll.cpp:94
float maxdist
Definition: ragdoll.hpp:37
vec offset
Definition: ragdoll.hpp:149
Definition: ents.hpp:258
int parent
Definition: ragdoll.hpp:62
#define dir(name, v, d, s, os)
Definition: physics.cpp:2014
#define loopk(m)
Definition: cube_loops.hpp:10
int unsticks
Definition: ragdoll.hpp:148
GLintptr offset
Definition: glexts.hpp:354
vec a
Definition: geom.hpp:904
vec o
Definition: ents.hpp:130
void updatepos()
Definition: ragdoll.cpp:179
vec & add(const vec &o)
scalar sum
Definition: geom.hpp:174
void applyrotfriction(float ts)
Definition: ragdoll.cpp:123
ragdolldata(ragdollskel *skel, float scale=1)
Definition: ragdoll.cpp:273
#define loopj(m)
Definition: cube_loops.hpp:9
int eye
Definition: ragdoll.hpp:66
SharedVar wrapper for primitive/immutable objects.
Definition: SharedVar.hpp:55
int lastmove
Definition: ragdoll.hpp:148
bool collide(const T &p1, const U &p2)
Definition: mpr.hpp:286
void addreljoint(int bone, int parent)
Definition: ragdoll.hpp:128
void calctris()
Definition: ragdoll.hpp:186
Definition: ragdoll.hpp:53
static map entities ("entity") and dynamic entities (players/monsters, "dynent") the gamecode extends...
vec & div(const vec &o)
scalar division
Definition: geom.hpp:171
mathmatics for vectors, matrices, quaterions and more
float timestep
Definition: ragdoll.hpp:150
bool loaded
Definition: ragdoll.hpp:65
int millis
Definition: ragdoll.hpp:148
int vert[3]
Definition: ragdoll.hpp:25
vec vel
Definition: ents.hpp:130
vec & cross(const A &a, const B &b)
template based vector cross product
Definition: geom.hpp:211
matrix4x3 orient
Definition: ragdoll.hpp:57
int bone
Definition: ragdoll.hpp:55
#define loopv(v)
Definition: cube_loops.hpp:21
vec pos
Definition: ragdoll.hpp:19
vec & normalize()
normalize vector: divide it by its length (magnitude)
Definition: geom.hpp:198
void transpose()
Definition: geom.hpp:1014
static bool collidevert(const vec &pos, const vec &dir, float radius)
Definition: ragdoll.hpp:234
int tri
Definition: ragdoll.hpp:55
void moveragdoll(dynent *d)
Definition: ragdoll.cpp:294