BGE: Added getActionName() function to KX_GameObject()
[blender.git] / source / gameengine / Ketsji / BL_ActionManager.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Mitchell Stokes.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file BL_ActionManager.cpp
24  *  \ingroup ketsji
25  */
26
27 #include "BL_Action.h"
28 #include "BL_ActionManager.h"
29 #include "DNA_ID.h"
30
31 #define IS_TAGGED(_id) ((_id) && (((ID *)_id)->flag & LIB_DOIT))
32
33 BL_ActionManager::BL_ActionManager(class KX_GameObject *obj):
34         m_obj(obj),
35         m_prevUpdate(-1.0f)
36 {
37 }
38
39 BL_ActionManager::~BL_ActionManager()
40 {
41         BL_ActionMap::iterator it;
42
43         for (it = m_layers.begin(); it != m_layers.end(); it++)
44                 delete it->second;
45
46         m_layers.clear();
47 }
48
49 BL_Action *BL_ActionManager::GetAction(short layer)
50 {
51         BL_ActionMap::iterator it = m_layers.find(layer);
52
53         return (it != m_layers.end()) ? it->second : 0;
54 }
55
56 BL_Action* BL_ActionManager::AddAction(short layer)
57 {
58         BL_Action *action = new BL_Action(m_obj);
59         m_layers[layer] = action;
60
61         return action;
62 }
63
64 float BL_ActionManager::GetActionFrame(short layer)
65 {
66         BL_Action *action = GetAction(layer);
67
68         return action ? action->GetFrame() : 0.f;
69 }
70
71 const char *BL_ActionManager::GetActionName(short layer)
72 {
73         BL_Action *action = GetAction(layer);
74         return action ? action->GetName() : "";
75 }
76
77 void BL_ActionManager::SetActionFrame(short layer, float frame)
78 {
79         BL_Action *action = GetAction(layer);
80
81         if (action) action->SetFrame(frame);
82 }
83
84 struct bAction *BL_ActionManager::GetCurrentAction(short layer)
85 {
86         BL_Action *action = GetAction(layer);
87
88         return action ? action->GetAction() : 0;
89 }
90
91 void BL_ActionManager::SetPlayMode(short layer, short mode)
92 {
93         BL_Action *action = GetAction(layer);
94
95         if (action) action->SetPlayMode(mode);
96 }
97
98 void BL_ActionManager::SetTimes(short layer, float start, float end)
99 {
100         BL_Action *action = GetAction(layer);
101
102         if (action) action->SetTimes(start, end);
103 }
104
105 bool BL_ActionManager::PlayAction(const char* name,
106                                                                 float start,
107                                                                 float end,
108                                                                 short layer,
109                                                                 short priority,
110                                                                 float blendin,
111                                                                 short play_mode,
112                                                                 float layer_weight,
113                                                                 short ipo_flags,
114                                                                 float playback_speed,
115                                                                 short blend_mode)
116 {
117         // Only this method will create layer if non-existent
118         BL_Action *action = GetAction(layer);
119         if (!action)
120                 action = AddAction(layer);
121
122         // Disable layer blending on the first layer
123         if (layer == 0) layer_weight = -1.f;
124
125         return action->Play(name, start, end, priority, blendin, play_mode, layer_weight, ipo_flags, playback_speed, blend_mode);
126 }
127
128 void BL_ActionManager::StopAction(short layer)
129 {
130         BL_Action *action = GetAction(layer);
131
132         if (action) action->Stop();
133 }
134
135 void BL_ActionManager::RemoveTaggedActions()
136 {
137         for (BL_ActionMap::iterator it = m_layers.begin(); it != m_layers.end();) {
138                 if (IS_TAGGED(it->second->GetAction())) {
139                         delete it->second;
140                         m_layers.erase(it++);
141                 }
142                 else
143                         ++it;
144         }
145 }
146
147 bool BL_ActionManager::IsActionDone(short layer)
148 {
149         BL_Action *action = GetAction(layer);
150
151         return action ? action->IsDone() : true;
152 }
153
154 void BL_ActionManager::Update(float curtime)
155 {
156         if (m_prevUpdate == curtime)
157                 return;
158         m_prevUpdate = curtime;
159
160         BL_ActionMap::iterator it;
161         for (it = m_layers.begin(); it != m_layers.end(); )
162         {
163                 if (it->second->IsDone()) {
164                         delete it->second;
165                         m_layers.erase(it++);
166                 }
167                 else {
168                         it->second->Update(curtime);
169                         ++it;
170                 }
171         }
172 }
173
174 void BL_ActionManager::UpdateIPOs()
175 {
176         BL_ActionMap::iterator it;
177         for (it = m_layers.begin(); it != m_layers.end(); ++it)
178         {
179                 if (!it->second->IsDone())
180                         it->second->UpdateIPOs();
181         }
182 }