big batch of changes
[chaz/yoink] / src / Character.cc
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #include <iostream>
30
31 #include "Character.hh"
32 #include "Log.hh"
33
34
35 class SpringForce
36 {
37 public:
38
39 explicit SpringForce(Mf::Vector2 x) :
40 location(x) {}
41
42 const Mf::Vector2& operator () (const Mf::LinearState<2>& state)
43 {
44 Mf::Vector2 x = state.position - location;
45 Mf::Scalar mag = x.length();
46 Mf::Scalar d = 50.0;
47
48 // spring:
49 //mState.force += -15.0 * x - 1.5 * mState.velocity;
50 force = SCALAR(-10.0) * (mag - d) * (x / mag) - 2.0 * state.velocity;
51
52 return force;
53 }
54
55 private:
56
57 Mf::Vector2 force;
58 Mf::Vector2 location;
59 };
60
61 class ResistanceForce
62 {
63 public:
64
65 explicit ResistanceForce(Mf::Scalar scale = 1.0) :
66 k(scale) {}
67
68 const Mf::Vector2& operator () (const Mf::LinearState<2>& state)
69 {
70 force = -k * state.velocity;
71 return force;
72 }
73
74 private:
75
76 Mf::Vector2 force;
77 Mf::Scalar k;
78 };
79
80
81 Character::Character(const std::string& name) :
82 tilemap(name),
83 animation(name)
84 {
85 mState.init();
86
87 mState.mass = 1.0;
88 mState.inverseMass = 1.0 / mState.mass;
89
90 // forces
91 mState.force = Mf::Vector2(0.0, 0.0);
92 //mState.forces.push_back(SpringForce(Mf::Vector2(500.0, 200.0)));
93 mState.forces.push_back(ResistanceForce(2.0));
94 //mState.forces.push_back(Mf::LinearState<2>::GravityForce(-400.0));
95
96 // starting position
97 mState.position = Mf::Vector2(5.0, 5.0);
98 mState.momentum = Mf::Vector2(0.0, 0.0);
99 mState.recalculate();
100
101 mPrevState = mState;
102 }
103
104
105 void Character::update(Mf::Scalar t, Mf::Scalar dt)
106 {
107 Mf::RigidBody2::update(t, dt); // update physics
108
109 animation.update(t, dt);
110
111 Mf::Vector3 center(mState.position[0], mState.position[1], mZCoord);
112 Mf::Vector3 a(mState.position[0] - 0.5, mState.position[1] - 0.5, mZCoord);
113 Mf::Vector3 b(mState.position[0] + 0.5, mState.position[1] + 0.5, mZCoord);
114
115 mAabb.init(a, b);
116 mSphere.init(center, a);
117 }
118
119
120 void Character::draw(Mf::Scalar alpha) const
121 {
122 //Mf::Vector2 position = cml::lerp(mPrevState.position, mState.position, alpha);
123 Mf::State2 state = getState(alpha);
124 Mf::Vector2 position = state.position;
125
126 //glColor3f(1.0f, 1.0f, 1.0f);
127 tilemap.bind();
128
129 Tilemap::Index frame = animation.getFrame();
130
131 Tilemap::Orientation orientation = Tilemap::NORMAL;
132
133 if (mState.velocity[0] < 0.0) orientation = Tilemap::REVERSE;
134
135 Mf::Scalar coords[8];
136 tilemap.getTileCoords(frame, coords, orientation);
137
138 Mf::Scalar s = 0.5;
139
140 glBegin(GL_TRIANGLE_FAN);
141 glTexCoord2f(coords[0], coords[1]);
142 glVertex3(position[0]-s, position[1]-s, mZCoord);
143 glTexCoord2f(coords[2], coords[3]);
144 glVertex3(position[0]+s, position[1]-s, mZCoord);
145 glTexCoord2f(coords[4], coords[5]);
146 glVertex3(position[0]+s, position[1]+s, mZCoord);
147 glTexCoord2f(coords[6], coords[7]);
148 glVertex3(position[0]-s, position[1]+s, mZCoord);
149 glEnd();
150 }
151
152 void Character::setZCoord(Mf::Scalar z)
153 {
154 mZCoord = z;
155 }
156
157
158 int Character::getOctant(const Mf::Aabb& aabb) const
159 {
160 int octantNum = -1;
161
162 Mf::Plane::Halfspace halfspace;
163
164 Mf::Plane xy = aabb.getPlaneXY();
165 halfspace = xy.intersects(mSphere);
166 if (halfspace == Mf::Plane::INTERSECT)
167 {
168 halfspace = xy.intersects(mAabb);
169 }
170
171 if (halfspace == Mf::Plane::POSITIVE)
172 {
173 Mf::Plane xz = aabb.getPlaneXZ();
174 halfspace = xz.intersects(mSphere);
175 if (halfspace == Mf::Plane::INTERSECT)
176 {
177 halfspace = xz.intersects(mAabb);
178 }
179
180 if (halfspace == Mf::Plane::POSITIVE)
181 {
182 Mf::Plane yz = aabb.getPlaneYZ();
183 halfspace = yz.intersects(mSphere);
184 if (halfspace == Mf::Plane::INTERSECT)
185 {
186 halfspace = yz.intersects(mAabb);
187 }
188
189 if (halfspace == Mf::Plane::POSITIVE)
190 {
191 octantNum = 2;
192 }
193 else if (halfspace == Mf::Plane::NEGATIVE)
194 {
195 octantNum = 3;
196 }
197 }
198 else if (halfspace == Mf::Plane::NEGATIVE)
199 {
200 Mf::Plane yz = aabb.getPlaneYZ();
201 halfspace = yz.intersects(mSphere);
202 if (halfspace == Mf::Plane::INTERSECT)
203 {
204 halfspace = yz.intersects(mAabb);
205 }
206
207 if (halfspace == Mf::Plane::POSITIVE)
208 {
209 octantNum = 1;
210 }
211 else if (halfspace == Mf::Plane::NEGATIVE)
212 {
213 octantNum = 0;
214 }
215 }
216 }
217 else if (halfspace == Mf::Plane::NEGATIVE)
218 {
219 Mf::Plane xz = aabb.getPlaneXZ();
220 halfspace = xz.intersects(mSphere);
221 if (halfspace == Mf::Plane::INTERSECT)
222 {
223 halfspace = xz.intersects(mAabb);
224 }
225
226 if (halfspace == Mf::Plane::POSITIVE)
227 {
228 Mf::Plane yz = aabb.getPlaneYZ();
229 halfspace = yz.intersects(mSphere);
230 if (halfspace == Mf::Plane::INTERSECT)
231 {
232 halfspace = yz.intersects(mAabb);
233 }
234
235 if (halfspace == Mf::Plane::POSITIVE)
236 {
237 octantNum = 6;
238 }
239 else if (halfspace == Mf::Plane::NEGATIVE)
240 {
241 octantNum = 7;
242 }
243 }
244 else if (halfspace == Mf::Plane::NEGATIVE)
245 {
246 Mf::Plane yz = aabb.getPlaneYZ();
247 halfspace = yz.intersects(mSphere);
248 if (halfspace == Mf::Plane::INTERSECT)
249 {
250 halfspace = yz.intersects(mAabb);
251 }
252
253 if (halfspace == Mf::Plane::POSITIVE)
254 {
255 octantNum = 5;
256 }
257 else if (halfspace == Mf::Plane::NEGATIVE)
258 {
259 octantNum = 4;
260 }
261 }
262 }
263
264 return octantNum;
265 }
266
267
268 void Character::addImpulse(Mf::Vector2 impulse)
269 {
270 mState.momentum += impulse;
271 }
272
273 void Character::addForce(Mf::Vector2 force)
274 {
275 mState.force += force;
276 }
277
278 void Character::setPosition(Mf::Vector2 position)
279 {
280 mState.position = position;
281 }
282
283
284 /** vim: set ts=4 sw=4 tw=80: *************************************************/
285
This page took 0.046393 seconds and 4 git commands to generate.