1 #include "SpringBody.h"
4 #include "VectorTools.h"
7 namespace JellyPhysics
{
9 SpringBody::SpringBody (
10 World
*w
, const ClosedShape
&shape
, float massPerPoint
,
11 float edgeSpringK
, float edgeSpringDamp
,
12 const Vector2
&pos
, float angleinRadians
,
13 const Vector2
&scale
, bool kinematic
14 ) : Body(w
, shape
, massPerPoint
, pos
, angleinRadians
, scale
, kinematic
) {
15 mShapeMatchingOn
= false;
16 setPositionAngle(pos
, angleinRadians
, scale
);
17 mEdgeSpringK
= edgeSpringK
;
18 mEdgeSpringDamp
= edgeSpringDamp
;
20 mShapeSpringDamp
= 0.0f
;
21 // build default springs
22 _buildDefaultSprings();
26 SpringBody::SpringBody (
27 World
*w
, const ClosedShape
&shape
, float massPerPoint
,
28 float shapeSpringK
, float shapeSpringDamp
,
29 float edgeSpringK
, float edgeSpringDamp
,
30 const Vector2
&pos
, float angleinRadians
,
31 const Vector2
&scale
, bool kinematic
32 ) : Body(w
, shape
, massPerPoint
, pos
, angleinRadians
, scale
, kinematic
) {
33 setPositionAngle(pos
, angleinRadians
, scale
);
34 mShapeMatchingOn
= true;
35 mShapeSpringK
= shapeSpringK
;
36 mShapeSpringDamp
= shapeSpringDamp
;
37 mEdgeSpringK
= edgeSpringK
;
38 mEdgeSpringDamp
= edgeSpringDamp
;
39 // build default springs
40 _buildDefaultSprings();
44 void SpringBody::addInternalSpring (int pointA
, int pointB
, float springK
, float damping
) {
45 float dist
= (mPointMasses
[pointB
].Position
-mPointMasses
[pointA
].Position
).length();
46 InternalSpring
s(pointA
, pointB
, dist
, springK
, damping
);
47 mSprings
.push_back(s
);
51 void SpringBody::clearAllSprings () {
53 _buildDefaultSprings();
57 void SpringBody::_buildDefaultSprings () {
58 int c
= mPointCount
, n
;
59 for (int i
= 0; i
< c
; ++i
) {
60 if ((n
= i
+1) >= c
) n
= 0;
61 addInternalSpring(i
, n
, mEdgeSpringK
, mEdgeSpringDamp
);
66 void SpringBody::setEdgeSpringConstants (float edgeSpringK
, float edgeSpringDamp
) {
67 mEdgeSpringK
= edgeSpringK
;
68 mEdgeSpringDamp
= edgeSpringDamp
;
69 // we know that the first n springs in the list are the edge springs
71 for (int i
= 0; i
< c
; ++i
) {
72 mSprings
[i
].springK
= edgeSpringK
;
73 mSprings
[i
].damping
= edgeSpringDamp
;
78 void SpringBody::setSpringConstants (int springID
, float springK
, float springDamp
) {
79 // index is for all internal springs, AFTER the default internal springs
80 int index
= mPointCount
+springID
;
81 mSprings
[index
].springK
= springK
;
82 mSprings
[index
].damping
= springDamp
;
86 float SpringBody::getSpringK (int springID
) const {
87 int index
= mPointCount
+springID
;
88 return mSprings
[index
].springK
;
92 float SpringBody::getSpringDamping (int springID
) const {
93 int index
= mPointCount
+springID
;
94 return mSprings
[index
].damping
;
98 void SpringBody::accumulateInternalForces () {
99 // internal spring forces
102 for (SpringList::const_iterator it
= mSprings
.begin(); it
!= mSprings
.end(); ++it
, ++i
) {
103 const InternalSpring
&s
= *it
;
104 PointMass
& pmA
= mPointMasses
[s
.pointMassA
];
105 PointMass
& pmB
= mPointMasses
[s
.pointMassB
];
106 if (i
< mPointCount
) {
107 // spring forces for the edges of the shape can used the cached edge information to reduce calculations
108 force
= VectorTools::calculateSpringForce(-mEdgeInfo
[i
].dir
, mEdgeInfo
[i
].length
, pmA
.Velocity
, pmB
.Velocity
, s
.springD
, s
.springK
, s
.damping
);
110 // these are other internal springs, they must be fully calculated each frame
111 force
= VectorTools::calculateSpringForce(pmA
.Position
, pmA
.Velocity
, pmB
.Position
, pmB
.Velocity
, s
.springD
, s
.springK
, s
.damping
);
116 // shape matching forces
117 if (mShapeMatchingOn
) {
118 mBaseShape
.transformVertices(mDerivedPos
, mDerivedAngle
, mScale
, mGlobalShape
);
119 for (int i
= 0; i
< mPointCount
; ++i
) {
120 PointMass
& pmA
= mPointMasses
[i
];
121 if (mShapeSpringK
> 0) {
123 force
= VectorTools::calculateSpringForce(pmA
.Position
, pmA
.Velocity
, mGlobalShape
[i
], pmA
.Velocity
, 0.0f
, mShapeSpringK
, mShapeSpringDamp
);
125 force
= VectorTools::calculateSpringForce(pmA
.Position
, pmA
.Velocity
, mGlobalShape
[i
], Vector2::Zero
, 0.0f
, mShapeSpringK
, mShapeSpringDamp
);