aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp
new file mode 100644
index 0000000..432d2ac
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp
@@ -0,0 +1,303 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CSceneNodeAnimatorCollisionResponse.h"
6#include "ISceneCollisionManager.h"
7#include "ISceneManager.h"
8#include "ICameraSceneNode.h"
9#include "os.h"
10
11namespace irr
12{
13namespace scene
14{
15
16//! constructor
17CSceneNodeAnimatorCollisionResponse::CSceneNodeAnimatorCollisionResponse(
18 ISceneManager* scenemanager,
19 ITriangleSelector* world, ISceneNode* object,
20 const core::vector3df& ellipsoidRadius,
21 const core::vector3df& gravityPerSecond,
22 const core::vector3df& ellipsoidTranslation,
23 f32 slidingSpeed)
24: Radius(ellipsoidRadius), Gravity(gravityPerSecond), Translation(ellipsoidTranslation),
25 World(world), Object(object), SceneManager(scenemanager), LastTime(0),
26 SlidingSpeed(slidingSpeed), CollisionNode(0), CollisionCallback(0),
27 Falling(false), IsCamera(false), AnimateCameraTarget(true), CollisionOccurred(false),
28 FirstUpdate(true)
29{
30 #ifdef _DEBUG
31 setDebugName("CSceneNodeAnimatorCollisionResponse");
32 #endif
33
34 if (World)
35 World->grab();
36
37 setNode(Object);
38}
39
40
41//! destructor
42CSceneNodeAnimatorCollisionResponse::~CSceneNodeAnimatorCollisionResponse()
43{
44 if (World)
45 World->drop();
46
47 if (CollisionCallback)
48 CollisionCallback->drop();
49}
50
51
52//! Returns if the attached scene node is falling, which means that
53//! there is no blocking wall from the scene node in the direction of
54//! the gravity.
55bool CSceneNodeAnimatorCollisionResponse::isFalling() const
56{
57 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
58 return Falling;
59}
60
61
62//! Sets the radius of the ellipsoid with which collision detection and
63//! response is done.
64void CSceneNodeAnimatorCollisionResponse::setEllipsoidRadius(
65 const core::vector3df& radius)
66{
67 Radius = radius;
68 FirstUpdate = true;
69}
70
71
72//! Returns the radius of the ellipsoid with wich the collision detection and
73//! response is done.
74core::vector3df CSceneNodeAnimatorCollisionResponse::getEllipsoidRadius() const
75{
76 return Radius;
77}
78
79
80//! Sets the gravity of the environment.
81void CSceneNodeAnimatorCollisionResponse::setGravity(const core::vector3df& gravity)
82{
83 Gravity = gravity;
84 FirstUpdate = true;
85}
86
87
88//! Returns current vector of gravity.
89core::vector3df CSceneNodeAnimatorCollisionResponse::getGravity() const
90{
91 return Gravity;
92}
93
94
95//! 'Jump' the animator, by adding a jump speed opposite to its gravity
96void CSceneNodeAnimatorCollisionResponse::jump(f32 jumpSpeed)
97{
98 FallingVelocity -= (core::vector3df(Gravity).normalize()) * jumpSpeed;
99 Falling = true;
100}
101
102
103//! Sets the translation of the ellipsoid for collision detection.
104void CSceneNodeAnimatorCollisionResponse::setEllipsoidTranslation(const core::vector3df &translation)
105{
106 Translation = translation;
107}
108
109
110//! Returns the translation of the ellipsoid for collision detection.
111core::vector3df CSceneNodeAnimatorCollisionResponse::getEllipsoidTranslation() const
112{
113 return Translation;
114}
115
116
117//! Sets a triangle selector holding all triangles of the world with which
118//! the scene node may collide.
119void CSceneNodeAnimatorCollisionResponse::setWorld(ITriangleSelector* newWorld)
120{
121 if (newWorld)
122 newWorld->grab();
123
124 if (World)
125 World->drop();
126
127 World = newWorld;
128
129 FirstUpdate = true;
130}
131
132
133//! Returns the current triangle selector containing all triangles for
134//! collision detection.
135ITriangleSelector* CSceneNodeAnimatorCollisionResponse::getWorld() const
136{
137 return World;
138}
139
140
141void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 timeMs)
142{
143 CollisionOccurred = false;
144
145 if (node != Object)
146 setNode(node);
147
148 if(!Object || !World)
149 return;
150
151 // trigger reset
152 if ( timeMs == 0 )
153 {
154 FirstUpdate = true;
155 timeMs = LastTime;
156 }
157
158 if ( FirstUpdate )
159 {
160 LastPosition = Object->getPosition();
161 Falling = false;
162 LastTime = timeMs;
163 FallingVelocity.set ( 0, 0, 0 );
164
165 FirstUpdate = false;
166 }
167
168 const u32 diff = timeMs - LastTime;
169 LastTime = timeMs;
170
171 CollisionResultPosition = Object->getPosition();
172 core::vector3df vel = CollisionResultPosition - LastPosition;
173
174 FallingVelocity += Gravity * (f32)diff * 0.001f;
175
176 CollisionTriangle = RefTriangle;
177 CollisionPoint = core::vector3df();
178 CollisionResultPosition = core::vector3df();
179 CollisionNode = 0;
180
181 // core::vector3df force = vel + FallingVelocity;
182
183 if ( AnimateCameraTarget )
184 {
185 // TODO: divide SlidingSpeed by frame time
186
187 bool f = false;
188 CollisionResultPosition
189 = SceneManager->getSceneCollisionManager()->getCollisionResultPosition(
190 World, LastPosition-Translation,
191 Radius, vel, CollisionTriangle, CollisionPoint, f,
192 CollisionNode, SlidingSpeed, FallingVelocity);
193
194 CollisionOccurred = (CollisionTriangle != RefTriangle);
195
196 CollisionResultPosition += Translation;
197
198 if (f)//CollisionTriangle == RefTriangle)
199 {
200 Falling = true;
201 }
202 else
203 {
204 Falling = false;
205 FallingVelocity.set(0, 0, 0);
206 }
207
208 bool collisionConsumed = false;
209
210 if (CollisionOccurred && CollisionCallback)
211 collisionConsumed = CollisionCallback->onCollision(*this);
212
213 if(!collisionConsumed)
214 Object->setPosition(CollisionResultPosition);
215 }
216
217 // move camera target
218 if (AnimateCameraTarget && IsCamera)
219 {
220 const core::vector3df pdiff = Object->getPosition() - LastPosition - vel;
221 ICameraSceneNode* cam = (ICameraSceneNode*)Object;
222 cam->setTarget(cam->getTarget() + pdiff);
223 }
224
225 LastPosition = Object->getPosition();
226}
227
228
229void CSceneNodeAnimatorCollisionResponse::setNode(ISceneNode* node)
230{
231 Object = node;
232
233 if (Object)
234 {
235 LastPosition = Object->getPosition();
236 IsCamera = (Object->getType() == ESNT_CAMERA);
237 }
238
239 LastTime = os::Timer::getTime();
240}
241
242
243//! Writes attributes of the scene node animator.
244void CSceneNodeAnimatorCollisionResponse::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
245{
246 out->addVector3d("Radius", Radius);
247 out->addVector3d("Gravity", Gravity);
248 out->addVector3d("Translation", Translation);
249 out->addBool("AnimateCameraTarget", AnimateCameraTarget);
250}
251
252
253//! Reads attributes of the scene node animator.
254void CSceneNodeAnimatorCollisionResponse::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
255{
256 Radius = in->getAttributeAsVector3d("Radius");
257 Gravity = in->getAttributeAsVector3d("Gravity");
258 Translation = in->getAttributeAsVector3d("Translation");
259 AnimateCameraTarget = in->getAttributeAsBool("AnimateCameraTarget");
260}
261
262
263ISceneNodeAnimator* CSceneNodeAnimatorCollisionResponse::createClone(ISceneNode* node, ISceneManager* newManager)
264{
265 if (!newManager) newManager = SceneManager;
266
267 CSceneNodeAnimatorCollisionResponse * newAnimator =
268 new CSceneNodeAnimatorCollisionResponse(newManager, World, Object, Radius,
269 (Gravity * 1000.0f), Translation, SlidingSpeed);
270
271 return newAnimator;
272}
273
274void CSceneNodeAnimatorCollisionResponse::setCollisionCallback(ICollisionCallback* callback)
275{
276 if ( CollisionCallback == callback )
277 return;
278
279 if (CollisionCallback)
280 CollisionCallback->drop();
281
282 CollisionCallback = callback;
283
284 if (CollisionCallback)
285 CollisionCallback->grab();
286}
287
288//! Should the Target react on collision ( default = true )
289void CSceneNodeAnimatorCollisionResponse::setAnimateTarget ( bool enable )
290{
291 AnimateCameraTarget = enable;
292 FirstUpdate = true;
293}
294
295//! Should the Target react on collision ( default = true )
296bool CSceneNodeAnimatorCollisionResponse::getAnimateTarget () const
297{
298 return AnimateCameraTarget;
299}
300
301} // end namespace scene
302} // end namespace irr
303