Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Converter/BL_ArmatureObject.cpp')
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp691
1 files changed, 0 insertions, 691 deletions
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
deleted file mode 100644
index 049fd49cab9..00000000000
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ /dev/null
@@ -1,691 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/Converter/BL_ArmatureObject.cpp
- * \ingroup bgeconv
- */
-
-
-#include "BL_ArmatureObject.h"
-#include "BL_ActionActuator.h"
-#include "BL_Action.h"
-#include "KX_BlenderSceneConverter.h"
-#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BIK_api.h"
-#include "BKE_action.h"
-#include "BKE_armature.h"
-#include "BKE_object.h"
-#include "BKE_library.h"
-#include "BKE_global.h"
-
-extern "C" {
-#include "BKE_animsys.h"
-}
-
-#include "BKE_constraint.h"
-#include "CTR_Map.h"
-#include "CTR_HashedPtr.h"
-#include "MEM_guardedalloc.h"
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_constraint_types.h"
-#include "RNA_access.h"
-#include "KX_PythonInit.h"
-#include "KX_KetsjiEngine.h"
-
-#include "EXP_ListWrapper.h"
-
-#include "MT_Matrix4x4.h"
-
-/**
- * Move here pose function for game engine so that we can mix with GE objects
- * Principle is as follow:
- * Use Blender structures so that BKE_pose_where_is can be used unchanged
- * Copy the constraint so that they can be enabled/disabled/added/removed at runtime
- * Don't copy the constraints for the pose used by the Action actuator, it does not need them.
- * Scan the constraint structures so that the KX equivalent of target objects are identified and
- * stored in separate list.
- * When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
- * Blender objects and restore after the evaluation.
- */
-static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
-{
- bPose *out;
- bPoseChannel *pchan, *outpchan;
- GHash *ghash;
-
- /* the game engine copies the current armature pose and then swaps
- * the object pose pointer. this makes it possible to change poses
- * without affecting the original blender data. */
-
- if (!src) {
- *dst=NULL;
- return;
- }
- else if (*dst==src) {
- printf("game_copy_pose source and target are the same\n");
- *dst=NULL;
- return;
- }
-
- out= (bPose*)MEM_dupallocN(src);
- out->chanhash = NULL;
- out->agroups.first= out->agroups.last= NULL;
- out->ikdata = NULL;
- out->ikparam = MEM_dupallocN(src->ikparam);
- out->flag |= POSE_GAME_ENGINE;
- BLI_duplicatelist(&out->chanbase, &src->chanbase);
-
- /* remap pointers */
- ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "game_copy_pose gh");
-
- pchan= (bPoseChannel *)src->chanbase.first;
- outpchan= (bPoseChannel *)out->chanbase.first;
- for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
- BLI_ghash_insert(ghash, pchan, outpchan);
-
- for (pchan = (bPoseChannel *)out->chanbase.first; pchan; pchan = pchan->next) {
- pchan->parent= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->parent);
- pchan->child= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->child);
-
- if (copy_constraint) {
- ListBase listb;
- // copy all constraint for backward compatibility
- // BKE_constraints_copy NULLs listb, no need to make extern for this operation.
- BKE_constraints_copy(&listb, &pchan->constraints, false);
- pchan->constraints= listb;
- }
- else {
- BLI_listbase_clear(&pchan->constraints);
- }
-
- if (pchan->custom) {
- id_us_plus(&pchan->custom->id);
- }
-
- // fails to link, props are not used in the BGE yet.
-#if 0
- if (pchan->prop)
- pchan->prop= IDP_CopyProperty(pchan->prop);
-#endif
- pchan->prop = NULL;
- pchan->draw_data = NULL;
- }
-
- BLI_ghash_free(ghash, NULL, NULL);
- // set acceleration structure for channel lookup
- BKE_pose_channels_hash_make(out);
- *dst=out;
-}
-
-
-
-/* Only allowed for Poses with identical channels */
-static void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
-{
- bPoseChannel *dchan;
- const bPoseChannel *schan;
- bConstraint *dcon, *scon;
- float dstweight;
- int i;
-
- if (mode == BL_Action::ACT_BLEND_BLEND)
- {
- dstweight = 1.0f - srcweight;
- } else if (mode == BL_Action::ACT_BLEND_ADD)
- {
- dstweight = 1.0f;
- } else {
- dstweight = 1.0f;
- }
-
- schan= (bPoseChannel *)src->chanbase.first;
- for (dchan = (bPoseChannel *)dst->chanbase.first; dchan; dchan=(bPoseChannel *)dchan->next, schan= (bPoseChannel *)schan->next) {
- // always blend on all channels since we don't know which one has been set
- /* quat interpolation done separate */
- if (schan->rotmode == ROT_MODE_QUAT) {
- float dquat[4], squat[4];
-
- copy_qt_qt(dquat, dchan->quat);
- copy_qt_qt(squat, schan->quat);
- // Normalize quaternions so that interpolation/multiplication result is correct.
- normalize_qt(dquat);
- normalize_qt(squat);
-
- if (mode==BL_Action::ACT_BLEND_BLEND)
- interp_qt_qtqt(dchan->quat, dquat, squat, srcweight);
- else {
- mul_fac_qt_fl(squat, srcweight);
- mul_qt_qtqt(dchan->quat, dquat, squat);
- }
-
- normalize_qt(dchan->quat);
- }
-
- for (i=0; i<3; i++) {
- /* blending for loc and scale are pretty self-explanatory... */
- dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
- dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
-
- /* euler-rotation interpolation done here instead... */
- // FIXME: are these results decent?
- if (schan->rotmode)
- dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
- }
- for (dcon= (bConstraint *)dchan->constraints.first, scon= (bConstraint *)schan->constraints.first;
- dcon && scon;
- dcon = dcon->next, scon = scon->next)
- {
- /* no 'add' option for constraint blending */
- dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
- }
- }
-
- /* this pose is now in src time */
- dst->ctime= src->ctime;
-}
-
-BL_ArmatureObject::BL_ArmatureObject(
- void* sgReplicationInfo,
- SG_Callbacks callbacks,
- Object *armature,
- Scene *scene,
- int vert_deform_type)
-
-: KX_GameObject(sgReplicationInfo,callbacks),
- m_controlledConstraints(),
- m_poseChannels(),
- m_scene(scene), // maybe remove later. needed for BKE_pose_where_is
- m_lastframe(0.0),
- m_timestep(0.040),
- m_vert_deform_type(vert_deform_type),
- m_constraintNumber(0),
- m_channelNumber(0),
- m_lastapplyframe(0.0)
-{
- m_origObjArma = armature; // Keep a copy of the original armature so we can fix drivers later
- m_objArma = BKE_object_copy(G.main, armature);
- m_objArma->data = BKE_armature_copy(G.main, (bArmature *)armature->data);
- // During object replication ob->data is increase, we decrease it now because we get a copy.
- id_us_min(&((bArmature *)m_origObjArma->data)->id);
- m_pose = m_objArma->pose;
- // need this to get iTaSC working ok in the BGE
- m_pose->flag |= POSE_GAME_ENGINE;
- memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat));
-
- // The side-effect of this method registers this object as "animatable" with the KX_Scene.
- GetActionManager();
-}
-
-BL_ArmatureObject::~BL_ArmatureObject()
-{
- BL_ArmatureConstraint* constraint;
- while ((constraint = m_controlledConstraints.Remove()) != NULL) {
- delete constraint;
- }
- BL_ArmatureChannel* channel;
- while ((channel = static_cast<BL_ArmatureChannel*>(m_poseChannels.Remove())) != NULL) {
- delete channel;
- }
-
- if (m_objArma) {
- BKE_libblock_free(G.main, m_objArma->data);
- BKE_libblock_free(G.main, m_objArma);
- }
-}
-
-
-void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
-{
- // first delete any existing constraint (should not have any)
- while (!m_controlledConstraints.Empty()) {
- BL_ArmatureConstraint* constraint = m_controlledConstraints.Remove();
- delete constraint;
- }
- m_constraintNumber = 0;
-
- // list all the constraint and convert them to BL_ArmatureConstraint
- // get the persistent pose structure
- bPoseChannel* pchan;
- bConstraint* pcon;
- const bConstraintTypeInfo* cti;
- Object* blendtarget;
- KX_GameObject* gametarget;
- KX_GameObject* gamesubtarget;
-
- // and locate the constraint
- for (pchan = (bPoseChannel *)m_pose->chanbase.first; pchan; pchan = pchan->next) {
- for (pcon = (bConstraint *)pchan->constraints.first; pcon; pcon = pcon->next) {
- if (pcon->flag & CONSTRAINT_DISABLE)
- continue;
- // which constraint should we support?
- switch (pcon->type) {
- case CONSTRAINT_TYPE_TRACKTO:
- case CONSTRAINT_TYPE_DAMPTRACK:
- case CONSTRAINT_TYPE_KINEMATIC:
- case CONSTRAINT_TYPE_ROTLIKE:
- case CONSTRAINT_TYPE_LOCLIKE:
- case CONSTRAINT_TYPE_MINMAX:
- case CONSTRAINT_TYPE_SIZELIKE:
- case CONSTRAINT_TYPE_LOCKTRACK:
- case CONSTRAINT_TYPE_STRETCHTO:
- case CONSTRAINT_TYPE_CLAMPTO:
- case CONSTRAINT_TYPE_TRANSFORM:
- case CONSTRAINT_TYPE_DISTLIMIT:
- case CONSTRAINT_TYPE_TRANSLIKE:
- cti = BKE_constraint_typeinfo_get(pcon);
- gametarget = gamesubtarget = NULL;
- if (cti && cti->get_constraint_targets) {
- ListBase listb = { NULL, NULL };
- cti->get_constraint_targets(pcon, &listb);
- if (listb.first) {
- bConstraintTarget* target = (bConstraintTarget*)listb.first;
- if (target->tar && target->tar != m_objArma) {
- // only remember external objects, self target is handled automatically
- blendtarget = target->tar;
- gametarget = converter->FindGameObject(blendtarget);
- }
- if (target->next != NULL) {
- // secondary target
- target = target->next;
- if (target->tar && target->tar != m_objArma) {
- // only track external object
- blendtarget = target->tar;
- gamesubtarget = converter->FindGameObject(blendtarget);
- }
- }
- }
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(pcon, &listb, 1);
- }
- BL_ArmatureConstraint* constraint = new BL_ArmatureConstraint(this, pchan, pcon, gametarget, gamesubtarget);
- m_controlledConstraints.AddBack(constraint);
- m_constraintNumber++;
- }
- }
- }
-
- // If we have constraints, make sure we get treated as an "animated" object
- if (m_constraintNumber > 0)
- GetActionManager();
-}
-
-BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(const char* posechannel, const char* constraintname)
-{
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end(); ++cit) {
- BL_ArmatureConstraint* constraint = *cit;
- if (constraint->Match(posechannel, constraintname))
- return constraint;
- }
- return NULL;
-}
-
-BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(const char* posechannelconstraint)
-{
- // performance: use hash string instead of plain string compare
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end(); ++cit) {
- BL_ArmatureConstraint* constraint = *cit;
- if (!strcmp(constraint->GetName(), posechannelconstraint))
- return constraint;
- }
- return NULL;
-}
-
-BL_ArmatureConstraint* BL_ArmatureObject::GetConstraint(int index)
-{
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end() && index; ++cit, --index);
- return (cit.end()) ? NULL : *cit;
-}
-
-/* this function is called to populate the m_poseChannels list */
-void BL_ArmatureObject::LoadChannels()
-{
- if (m_poseChannels.Empty()) {
- bPoseChannel* pchan;
- BL_ArmatureChannel* proxy;
-
- m_channelNumber = 0;
- for (pchan = (bPoseChannel *)m_pose->chanbase.first; pchan; pchan=(bPoseChannel *)pchan->next) {
- proxy = new BL_ArmatureChannel(this, pchan);
- m_poseChannels.AddBack(proxy);
- m_channelNumber++;
- }
- }
-}
-
-BL_ArmatureChannel* BL_ArmatureObject::GetChannel(bPoseChannel* pchan)
-{
- LoadChannels();
- SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
- for (cit.begin(); !cit.end(); ++cit)
- {
- BL_ArmatureChannel* channel = *cit;
- if (channel->m_posechannel == pchan)
- return channel;
- }
- return NULL;
-}
-
-BL_ArmatureChannel* BL_ArmatureObject::GetChannel(const char* str)
-{
- LoadChannels();
- SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
- for (cit.begin(); !cit.end(); ++cit)
- {
- BL_ArmatureChannel* channel = *cit;
- if (!strcmp(channel->m_posechannel->name, str))
- return channel;
- }
- return NULL;
-}
-
-BL_ArmatureChannel* BL_ArmatureObject::GetChannel(int index)
-{
- LoadChannels();
- if (index < 0 || index >= m_channelNumber)
- return NULL;
- SG_DList::iterator<BL_ArmatureChannel> cit(m_poseChannels);
- for (cit.begin(); !cit.end() && index; ++cit, --index);
- return (cit.end()) ? NULL : *cit;
-}
-
-CValue* BL_ArmatureObject::GetReplica()
-{
- BL_ArmatureObject* replica = new BL_ArmatureObject(*this);
- replica->ProcessReplica();
- return replica;
-}
-
-void BL_ArmatureObject::ProcessReplica()
-{
- KX_GameObject::ProcessReplica();
-
- bArmature* tmp = (bArmature*)m_objArma->data;
- m_objArma = BKE_object_copy(G.main, m_objArma);
- m_objArma->data = BKE_armature_copy(G.main, tmp);
- m_pose = m_objArma->pose;
-}
-
-void BL_ArmatureObject::ReParentLogic()
-{
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end(); ++cit) {
- (*cit)->ReParent(this);
- }
- KX_GameObject::ReParentLogic();
-}
-
-void BL_ArmatureObject::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
-{
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end(); ++cit) {
- (*cit)->Relink(obj_map);
- }
- KX_GameObject::Relink(obj_map);
-}
-
-bool BL_ArmatureObject::UnlinkObject(SCA_IObject* clientobj)
-{
- // clientobj is being deleted, make sure we don't hold any reference to it
- bool res = false;
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end(); ++cit) {
- res |= (*cit)->UnlinkObject(clientobj);
- }
- return res;
-}
-
-void BL_ArmatureObject::ApplyPose()
-{
- /* TODO: This doesn't work currently because of eval_ctx. */
-#if 0
- m_armpose = m_objArma->pose;
- m_objArma->pose = m_pose;
- // in the GE, we use ctime to store the timestep
- m_pose->ctime = (float)m_timestep;
- //m_scene->r.cfra++;
- if (m_lastapplyframe != m_lastframe) {
- // update the constraint if any, first put them all off so that only the active ones will be updated
- SG_DList::iterator<BL_ArmatureConstraint> cit(m_controlledConstraints);
- for (cit.begin(); !cit.end(); ++cit) {
- (*cit)->UpdateTarget();
- }
- // update ourself
- UpdateBlenderObjectMatrix(m_objArma);
- BKE_pose_where_is(m_scene, m_objArma); // XXX
- // restore ourself
- memcpy(m_objArma->obmat, m_obmat, sizeof(m_obmat));
- // restore active targets
- for (cit.begin(); !cit.end(); ++cit) {
- (*cit)->RestoreTarget();
- }
- m_lastapplyframe = m_lastframe;
- }
-#endif
-}
-
-void BL_ArmatureObject::RestorePose()
-{
- m_objArma->pose = m_armpose;
- m_armpose = NULL;
-}
-
-void BL_ArmatureObject::SetPose(bPose *pose)
-{
- extract_pose_from_pose(m_pose, pose);
- m_lastapplyframe = -1.0;
-}
-
-void BL_ArmatureObject::SetPoseByAction(bAction *action, float localtime)
-{
- Object *arm = GetArmatureObject();
-
- PointerRNA ptrrna;
- RNA_id_pointer_create(&arm->id, &ptrrna);
-
- animsys_evaluate_action(&ptrrna, action, NULL, localtime);
-}
-
-void BL_ArmatureObject::BlendInPose(bPose *blend_pose, float weight, short mode)
-{
- game_blend_poses(m_pose, blend_pose, weight, mode);
-}
-
-bool BL_ArmatureObject::UpdateTimestep(double curtime)
-{
- if (curtime != m_lastframe) {
- // compute the timestep for the underlying IK algorithm
- m_timestep = curtime-m_lastframe;
- m_lastframe= curtime;
- }
-
- return false;
-}
-
-void BL_ArmatureObject::GetPose(bPose **pose)
-{
- /* If the caller supplies a null pose, create a new one. */
- /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
-
- if (!*pose) {
- /* probably not to good of an idea to
- * duplicate everything, but it clears up
- * a crash and memory leakage when
- * &BL_ActionActuator::m_pose is freed
- */
- game_copy_pose(pose, m_pose, 0);
- }
- else {
- if (*pose == m_pose)
- // no need to copy if the pointers are the same
- return;
-
- extract_pose_from_pose(*pose, m_pose);
- }
-}
-
-double BL_ArmatureObject::GetLastFrame()
-{
- return m_lastframe;
-}
-
-bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix)
-{
- bPoseChannel *pchan;
-
- ApplyPose();
- pchan = BKE_pose_channel_find_name(m_objArma->pose, bone->name);
- if (pchan)
- matrix.setValue(&pchan->pose_mat[0][0]);
- RestorePose();
-
- return (pchan != NULL);
-}
-
-float BL_ArmatureObject::GetBoneLength(Bone* bone) const
-{
- return (float)(MT_Point3(bone->head) - MT_Point3(bone->tail)).length();
-}
-
-#ifdef WITH_PYTHON
-
-// PYTHON
-
-PyTypeObject BL_ArmatureObject::Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "BL_ArmatureObject",
- sizeof(PyObjectPlus_Proxy),
- 0,
- py_base_dealloc,
- 0,
- 0,
- 0,
- 0,
- py_base_repr,
- 0,
- &KX_GameObject::Sequence,
- &KX_GameObject::Mapping,
- 0,0,0,
- NULL,
- NULL,
- 0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- 0,0,0,0,0,0,0,
- Methods,
- 0,
- 0,
- &KX_GameObject::Type,
- 0,0,0,0,0,0,
- py_base_new
-};
-
-PyMethodDef BL_ArmatureObject::Methods[] = {
- KX_PYMETHODTABLE_NOARGS(BL_ArmatureObject, update),
- {NULL,NULL} //Sentinel
-};
-
-PyAttributeDef BL_ArmatureObject::Attributes[] = {
-
- KX_PYATTRIBUTE_RO_FUNCTION("constraints", BL_ArmatureObject, pyattr_get_constraints),
- KX_PYATTRIBUTE_RO_FUNCTION("channels", BL_ArmatureObject, pyattr_get_channels),
- {NULL} //Sentinel
-};
-
-static int bl_armature_object_get_constraints_size_cb(void *self_v)
-{
- return ((BL_ArmatureObject *)self_v)->GetConstraintNumber();
-}
-
-static PyObject *bl_armature_object_get_constraints_item_cb(void *self_v, int index)
-{
- return ((BL_ArmatureObject *)self_v)->GetConstraint(index)->GetProxy();
-}
-
-static const char *bl_armature_object_get_constraints_item_name_cb(void *self_v, int index)
-{
- return ((BL_ArmatureObject *)self_v)->GetConstraint(index)->GetName();
-}
-
-PyObject *BL_ArmatureObject::pyattr_get_constraints(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
-{
- return (new CListWrapper(self_v,
- ((BL_ArmatureObject *)self_v)->GetProxy(),
- NULL,
- bl_armature_object_get_constraints_size_cb,
- bl_armature_object_get_constraints_item_cb,
- bl_armature_object_get_constraints_item_name_cb,
- NULL))->NewProxy(true);
-}
-
-static int bl_armature_object_get_channels_size_cb(void *self_v)
-{
- return ((BL_ArmatureObject *)self_v)->GetChannelNumber();
-}
-
-static PyObject *bl_armature_object_get_channels_item_cb(void *self_v, int index)
-{
- return ((BL_ArmatureObject *)self_v)->GetChannel(index)->GetProxy();
-}
-
-static const char *bl_armature_object_get_channels_item_name_cb(void *self_v, int index)
-{
- return ((BL_ArmatureObject *)self_v)->GetChannel(index)->GetName();
-}
-
-PyObject *BL_ArmatureObject::pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
-{
- BL_ArmatureObject *self = static_cast<BL_ArmatureObject *>(self_v);
- self->LoadChannels(); // make sure we have the channels
- return (new CListWrapper(self_v,
- self->GetProxy(),
- NULL,
- bl_armature_object_get_channels_size_cb,
- bl_armature_object_get_channels_item_cb,
- bl_armature_object_get_channels_item_name_cb,
- NULL))->NewProxy(true);
-}
-
-KX_PYMETHODDEF_DOC_NOARGS(BL_ArmatureObject, update,
- "update()\n"
- "Make sure that the armature will be updated on next graphic frame.\n"
- "This is automatically done if a KX_ArmatureActuator with mode run is active\n"
- "or if an action is playing. This function is useful in other cases.\n")
-{
- UpdateTimestep(KX_GetActiveEngine()->GetFrameTime());
- Py_RETURN_NONE;
-}
-
-#endif // WITH_PYTHON