forked from Mirrors/openclonk
Rope: Compute forces from last contact vertex for connected objects
parent
2aef0d896d
commit
6006b83aa6
|
@ -150,14 +150,14 @@ namespace
|
|||
|
||||
C4RopeElement::C4RopeElement(C4Object* obj, bool fixed):
|
||||
Fixed(fixed), fx(Fix0), fy(Fix0), rx(Fix0), ry(Fix0), rdt(Fix0), fcx(Fix0), fcy(Fix0),
|
||||
Next(NULL), Prev(NULL), Object(obj)
|
||||
Next(NULL), Prev(NULL), Object(obj), LastContactVertex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
C4RopeElement::C4RopeElement(C4Real x, C4Real y, C4Real m, bool fixed):
|
||||
Fixed(fixed), x(x), y(y), vx(Fix0), vy(Fix0), m(m),
|
||||
fx(Fix0), fy(Fix0), rx(Fix0), ry(Fix0), rdt(Fix0), fcx(Fix0), fcy(Fix0),
|
||||
Next(NULL), Prev(NULL), Object(NULL)
|
||||
Next(NULL), Prev(NULL), Object(NULL), LastContactVertex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,30 @@ void C4RopeElement::AddForce(C4Real x, C4Real y)
|
|||
#endif
|
||||
}
|
||||
|
||||
C4Real C4RopeElement::GetTargetX() const
|
||||
{
|
||||
// TODO: Prevent against object changes: Reset when Target changes wrt
|
||||
// to the object LastContactVertex refers to.
|
||||
if(LastContactVertex == -1) return Object->fix_x;
|
||||
|
||||
C4Object* obj = Object;
|
||||
while(obj->Contained)
|
||||
obj = obj->Contained;
|
||||
return obj->fix_x + itofix(obj->Shape.VtxX[LastContactVertex]);
|
||||
}
|
||||
|
||||
C4Real C4RopeElement::GetTargetY() const
|
||||
{
|
||||
// TODO: Prevent against object changes: Reset when Target changes wrt
|
||||
// to the object LastContactVertex refers to.
|
||||
if(LastContactVertex == -1) return Object->fix_y;
|
||||
|
||||
C4Object* obj = Object;
|
||||
while(obj->Contained)
|
||||
obj = obj->Contained;
|
||||
return obj->fix_y + itofix(obj->Shape.VtxY[LastContactVertex]);
|
||||
}
|
||||
|
||||
void C4RopeElement::Execute(const C4Rope* rope, C4Real dt)
|
||||
{
|
||||
ResetForceRedirection(dt);
|
||||
|
@ -279,7 +303,10 @@ void C4RopeElement::Execute(const C4Rope* rope, C4Real dt)
|
|||
iContactVertex = i;
|
||||
|
||||
if(iContactVertex != -1)
|
||||
{
|
||||
LastContactVertex = iContactVertex;
|
||||
SetForceRedirection(rope, Target->Shape.VtxX[iContactVertex], Target->Shape.VtxY[iContactVertex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -520,9 +547,6 @@ void C4Rope::Solve(C4RopeElement* prev, C4RopeElement* next)
|
|||
int nix = fixtoi(next->GetX());
|
||||
int niy = fixtoi(next->GetY());
|
||||
|
||||
// TODO: For objects, run PathFree and PathFinder from vertex which has
|
||||
// had contact to the landscape previously.
|
||||
|
||||
// We only run the PathFinder when the distance between the two segments
|
||||
// is at least twice the nominal distance.
|
||||
|
||||
|
|
|
@ -37,13 +37,16 @@ public:
|
|||
C4RopeElement(C4Object* obj, bool fixed);
|
||||
C4RopeElement(C4Real x, C4Real y, C4Real m, bool fixed);
|
||||
|
||||
C4Real GetX() const { return Object ? Object->fix_x : x; }
|
||||
C4Real GetY() const { return Object ? Object->fix_y : y; }
|
||||
C4Real GetX() const { return Object ? GetTargetX() : x; }
|
||||
C4Real GetY() const { return Object ? GetTargetY() : y; }
|
||||
C4Real GetVx() const { return Object ? Object->xdir : vx; }
|
||||
C4Real GetVy() const { return Object ? Object->ydir : vy; }
|
||||
C4Real GetMass() const { return Object ? itofix(Object->Mass) : m; }
|
||||
C4Object* GetObject() const { return Object; }
|
||||
|
||||
C4Real GetTargetX() const;
|
||||
C4Real GetTargetY() const;
|
||||
|
||||
void AddForce(C4Real x, C4Real y);
|
||||
void Execute(const C4Rope* rope, C4Real dt);
|
||||
private:
|
||||
|
@ -62,6 +65,7 @@ private:
|
|||
C4RopeElement* Next; // next rope element, or NULL
|
||||
C4RopeElement* Prev; // prev rope element, or NULL
|
||||
C4Object* Object; // Connected object. If set, x/y/vx/vy/m are ignored.
|
||||
int LastContactVertex; // Vertex which most recently had collision with landscape
|
||||
};
|
||||
|
||||
class C4Rope: public C4PropListNumbered
|
||||
|
@ -80,8 +84,8 @@ public:
|
|||
|
||||
C4RopeElement* GetFront() const { return Front; }
|
||||
C4RopeElement* GetBack() const { return Back; }
|
||||
void SetFront(C4Object* obj, C4Real x, C4Real y) { Front->Object = obj; Front->x = x; Front->y = y; }
|
||||
void SetBack(C4Object* obj, C4Real x, C4Real y) { Back->Object = obj; Back->x = x; Back->y = y; }
|
||||
void SetFront(C4Object* obj, C4Real x, C4Real y) { Front->Object = obj; Front->x = x; Front->y = y; Front->LastContactVertex = -1; }
|
||||
void SetBack(C4Object* obj, C4Real x, C4Real y) { Back->Object = obj; Back->x = x; Back->y = y; Back->LastContactVertex = -1; }
|
||||
|
||||
C4Real GetFrontAutoSegmentation() const { return FrontAutoSegmentation; }
|
||||
C4Real GetBackAutoSegmentation() const { return BackAutoSegmentation; }
|
||||
|
|
Loading…
Reference in New Issue