removed VectorTools namespace
[k8-jellyphysics.git] / src / jelly / SpringBody.cpp
blobbb897a789e8c64d701cd2118954fcaa4c5b0c57b
1 /*
2 * Copyright (c) 2007 Walaber
3 * Modified by Ketmar // Invisible Vector
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
23 #include "SpringBody.h"
25 #include "World.h"
26 #include "VectorTools.h"
29 namespace JellyPhysics {
31 SpringBody::SpringBody (
32 World *w, const ClosedShape &shape, float massPerPoint,
33 float edgeSpringK, float edgeSpringDamp,
34 const Vector2 &pos, float angleinRadians,
35 const Vector2 &scale, bool kinematic
36 ) : Body(w, shape, massPerPoint, pos, angleinRadians, scale, kinematic) {
37 mShapeMatchingOn = false;
38 setPositionAngle(pos, angleinRadians, scale);
39 mEdgeSpringK = edgeSpringK;
40 mEdgeSpringDamp = edgeSpringDamp;
41 mShapeSpringK = 0.0f;
42 mShapeSpringDamp = 0.0f;
43 // build default springs
44 _buildDefaultSprings();
48 SpringBody::SpringBody (
49 World *w, const ClosedShape &shape, float massPerPoint,
50 float shapeSpringK, float shapeSpringDamp,
51 float edgeSpringK, float edgeSpringDamp,
52 const Vector2 &pos, float angleinRadians,
53 const Vector2 &scale, bool kinematic
54 ) : Body(w, shape, massPerPoint, pos, angleinRadians, scale, kinematic) {
55 setPositionAngle(pos, angleinRadians, scale);
56 mShapeMatchingOn = true;
57 mShapeSpringK = shapeSpringK;
58 mShapeSpringDamp = shapeSpringDamp;
59 mEdgeSpringK = edgeSpringK;
60 mEdgeSpringDamp = edgeSpringDamp;
61 // build default springs
62 _buildDefaultSprings();
66 SpringBody::~SpringBody () {
70 void SpringBody::addInternalSpring (int pointA, int pointB, float springK, float damping) {
71 float dist = (mPointMasses[pointB].Position-mPointMasses[pointA].Position).length();
72 InternalSpring s(pointA, pointB, dist, springK, damping);
73 mSprings.push_back(s);
77 void SpringBody::clearAllSprings () {
78 mSprings.clear();
79 _buildDefaultSprings();
83 void SpringBody::_buildDefaultSprings () {
84 int c = mPointCount, n;
85 for (int i = 0; i < c; ++i) {
86 if ((n = i+1) >= c) n = 0;
87 addInternalSpring(i, n, mEdgeSpringK, mEdgeSpringDamp);
92 void SpringBody::setEdgeSpringConstants (float edgeSpringK, float edgeSpringDamp) {
93 mEdgeSpringK = edgeSpringK;
94 mEdgeSpringDamp = edgeSpringDamp;
95 // we know that the first n springs in the list are the edge springs
96 int c = mPointCount;
97 for (int i = 0; i < c; ++i) {
98 mSprings[i].springK = edgeSpringK;
99 mSprings[i].damping = edgeSpringDamp;
104 void SpringBody::setSpringConstants (int springID, float springK, float springDamp) {
105 // index is for all internal springs, AFTER the default internal springs
106 int index = mPointCount+springID;
107 mSprings[index].springK = springK;
108 mSprings[index].damping = springDamp;
112 float SpringBody::getSpringK (int springID) const {
113 int index = mPointCount+springID;
114 return mSprings[index].springK;
118 float SpringBody::getSpringDamping (int springID) const {
119 int index = mPointCount+springID;
120 return mSprings[index].damping;
124 void SpringBody::accumulateInternalForces () {
125 // internal spring forces
126 Vector2 force;
127 int i = 0;
128 for (SpringList::const_iterator it = mSprings.begin(); it != mSprings.end(); ++it, ++i) {
129 const InternalSpring &s = *it;
130 PointMass& pmA = mPointMasses[s.pointMassA];
131 PointMass& pmB = mPointMasses[s.pointMassB];
132 if (i < mPointCount) {
133 // spring forces for the edges of the shape can used the cached edge information to reduce calculations
134 force = calculateSpringForce(-mEdgeInfo[i].dir, mEdgeInfo[i].length, pmA.Velocity, pmB.Velocity, s.springD, s.springK, s.damping);
135 } else {
136 // these are other internal springs, they must be fully calculated each frame
137 force = calculateSpringForce(pmA.Position, pmA.Velocity, pmB.Position, pmB.Velocity, s.springD, s.springK, s.damping);
139 pmA.Force += force;
140 pmB.Force -= force;
142 // shape matching forces
143 if (mShapeMatchingOn) {
144 mBaseShape.transformVertices(mDerivedPos, mDerivedAngle, mScale, mGlobalShape);
145 for (int i = 0; i < mPointCount; ++i) {
146 PointMass& pmA = mPointMasses[i];
147 if (mShapeSpringK > 0) {
148 if (!mKinematic) {
149 force = calculateSpringForce(pmA.Position, pmA.Velocity, mGlobalShape[i], pmA.Velocity, 0.0f, mShapeSpringK, mShapeSpringDamp);
150 } else {
151 force = calculateSpringForce(pmA.Position, pmA.Velocity, mGlobalShape[i], Vector2::Zero, 0.0f, mShapeSpringK, mShapeSpringDamp);
153 pmA.Force += force;