fixed the mouse-over sensor,
[blender-staging.git] / source / gameengine / Ketsji / KX_GameObject.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * Game object wrapper
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #ifdef WIN32
39 // This warning tells us about truncation of __long__ stl-generated names.
40 // It can occasionally cause DevStudio to have internal compiler warnings.
41 #pragma warning( disable : 4786 )     
42 #endif
43
44
45 #define KX_INERTIA_INFINITE 10000
46 #include "RAS_IPolygonMaterial.h"
47 #include "KX_GameObject.h"
48 #include "RAS_MeshObject.h"
49 #include "KX_MeshProxy.h"
50 #include <stdio.h> // printf
51 #include "SG_Controller.h"
52 #include "KX_IPhysicsController.h"
53 #include "SG_Node.h"
54 #include "SG_Controller.h"
55 #include "KX_ClientObjectInfo.h"
56 #include "RAS_BucketManager.h"
57
58 #include "KX_PyMath.h"
59
60 // This file defines relationships between parents and children
61 // in the game engine.
62
63 #include "KX_SG_NodeRelationships.h"
64
65 KX_GameObject::KX_GameObject(
66         void* sgReplicationInfo,
67         SG_Callbacks callbacks,
68         PyTypeObject* T
69 ) : 
70         SCA_IObject(T),
71         m_bDyna(false),
72         m_bSuspendDynamics(false),
73         m_bUseObjectColor(false),
74         m_bVisible(true),
75         m_pPhysicsController1(NULL),
76         m_isDeformable(false)
77 {
78         m_ignore_activity_culling = false;
79         m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
80         m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
81         
82         // define the relationship between this node and it's parent.
83         
84         KX_NormalParentRelation * parent_relation = 
85                 KX_NormalParentRelation::New();
86         m_pSGNode->SetParentRelation(parent_relation);
87         
88
89 };
90
91
92
93 KX_GameObject::~KX_GameObject()
94 {
95         // is this delete somewhere ?
96         //if (m_sumoObj)
97         //      delete m_sumoObj;
98         delete m_pClient_info;
99         //if (m_pSGNode)
100         //      delete m_pSGNode;
101         
102 }
103
104
105
106 CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val) 
107 {
108         return NULL;
109 }
110
111
112
113 CValue* KX_GameObject::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
114 {
115         return NULL;
116 }
117
118
119
120 const STR_String & KX_GameObject::GetText()
121 {
122         return m_text;
123 }
124
125
126
127 float KX_GameObject::GetNumber()
128 {
129         return 0;
130 }
131
132
133
134 STR_String KX_GameObject::GetName()
135 {
136         return m_name;
137 }
138
139
140
141 void KX_GameObject::SetName(STR_String name)
142 {
143         m_name = name;
144 };                                                              // Set the name of the value
145
146
147
148 void KX_GameObject::ReplicaSetName(STR_String name)
149 {
150 }
151
152
153
154
155
156
157 KX_IPhysicsController* KX_GameObject::GetPhysicsController()
158 {
159         return m_pPhysicsController1;
160 }
161
162
163
164
165
166 KX_GameObject* KX_GameObject::GetParent()
167 {
168         KX_GameObject* result = NULL;
169         SG_Node* node = m_pSGNode;
170         
171         while (node && !result)
172         {
173                 node = node->GetSGParent();
174                 if (node)
175                         result = (KX_GameObject*)node->GetSGClientObject();
176         }
177         
178         if (result)
179                 result->AddRef();
180
181         return result;
182         
183 }
184
185
186
187 void KX_GameObject::ProcessReplica(KX_GameObject* replica)
188 {
189         replica->m_pPhysicsController1 = NULL;
190         replica->m_pSGNode = NULL;
191         replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
192         replica->m_pClient_info->m_gameobject = replica;
193 }
194
195
196
197 CValue* KX_GameObject::GetReplica()
198 {
199         KX_GameObject* replica = new KX_GameObject(*this);
200         
201         // this will copy properties and so on...
202         CValue::AddDataToReplica(replica);
203         ProcessReplica(replica);
204         
205         return replica;
206 }
207
208
209
210 void KX_GameObject::ApplyForce(const MT_Vector3& force,bool local)
211 {
212         if (m_pPhysicsController1)
213                 m_pPhysicsController1->ApplyForce(force,local);
214 }
215
216
217
218 void KX_GameObject::ApplyTorque(const MT_Vector3& torque,bool local)
219 {
220         if (m_pPhysicsController1)
221                 m_pPhysicsController1->ApplyTorque(torque,local);
222 }
223
224
225
226 void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
227 {
228         if (m_pPhysicsController1) // (IsDynamic())
229         {
230                 m_pPhysicsController1->RelativeTranslate(dloc,local);
231         }
232         GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
233 }
234
235
236
237 void KX_GameObject::ApplyRotation(const MT_Vector3& drot,bool local)
238 {
239         MT_Matrix3x3 rotmat(drot);
240         rotmat.transpose();
241         
242         if (m_pPhysicsController1) // (IsDynamic())
243                 m_pPhysicsController1->RelativeRotate(rotmat,local); 
244         // in worldspace
245         GetSGNode()->RelativeRotate(rotmat,local);
246 }
247
248
249
250 /**
251 GetOpenGL Matrix, returns an OpenGL 'compatible' matrix
252 */
253 double* KX_GameObject::GetOpenGLMatrix()
254 {
255         // todo: optimize and only update if necessary
256         double* fl = m_OpenGL_4x4Matrix.getPointer();
257         MT_Transform trans;
258         
259         trans.setOrigin(GetSGNode()->GetWorldPosition());
260         trans.setBasis(GetSGNode()->GetWorldOrientation());
261         
262         MT_Vector3 scaling = GetSGNode()->GetWorldScaling();
263         
264         trans.scale(scaling[0], scaling[1], scaling[2]);
265         trans.getValue(fl);
266
267         return fl;
268 }
269
270
271
272 void KX_GameObject::Bucketize()
273 {
274         double* fl = GetOpenGLMatrix();
275
276         for (size_t i=0;i<m_meshes.size();i++)
277                 m_meshes[i]->Bucketize(fl, this, m_bUseObjectColor, m_objectColor);
278 }
279
280
281
282 void KX_GameObject::RemoveMeshes()
283 {
284         double* fl = GetOpenGLMatrix();
285
286         for (size_t i=0;i<m_meshes.size();i++)
287                 m_meshes[i]->RemoveFromBuckets(fl, this);
288
289         //note: meshes can be shared, and are deleted by KX_BlenderSceneConverter
290
291         m_meshes.clear();
292 }
293
294
295
296 void KX_GameObject::UpdateNonDynas()
297 {
298         if (m_pPhysicsController1)
299         {
300                 m_pPhysicsController1->SetSumoTransform(true);
301         }
302 }
303
304
305
306 void KX_GameObject::UpdateTransform()
307 {
308         if (m_pPhysicsController1)
309                 m_pPhysicsController1->SetSumoTransform(false);
310 }
311
312 void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene)
313 {
314         ((KX_GameObject*)gameobj)->UpdateTransform();
315 }
316
317
318 void KX_GameObject::SetDebugColor(unsigned int bgra)
319 {
320         for (size_t i=0;i<m_meshes.size();i++)
321                 m_meshes[i]->DebugColor(bgra);  
322 }
323
324
325
326 void KX_GameObject::ResetDebugColor()
327 {
328         SetDebugColor(0xff000000);
329 }
330
331
332
333 void KX_GameObject::UpdateIPO(float curframetime,
334                                                           bool recurse,
335                                                           bool ipo_as_force,
336                                                           bool force_local) 
337 {
338
339         // The ipo-actuator needs a sumo reference... this is retrieved (unfortunately)
340         // by the iposgcontr itself...
341 //              ipocontr->SetSumoReference(gameobj->GetSumoScene(), 
342 //                                                                 gameobj->GetSumoObject());
343
344
345         // The ipo has to be treated as a force, and not a displacement!
346         // For this case, we send some settings to the controller. This
347         // may need some caching...
348         if (ipo_as_force) {
349                 SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin();
350
351                 while (it != GetSGNode()->GetSGControllerList().end()) {
352                         (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force);
353                         (*it)->SetOption(SG_Controller::SG_CONTR_IPO_FORCES_ACT_LOCAL, force_local);
354                         it++;
355                 }
356         } 
357
358         // The rest is the 'normal' update procedure.
359         GetSGNode()->SetSimulatedTime(curframetime,recurse);
360         GetSGNode()->UpdateWorldData(curframetime);
361         UpdateTransform();
362 }
363
364 bool
365 KX_GameObject::GetVisible(
366         void
367         )
368 {
369         return m_bVisible;
370 }
371
372 void
373 KX_GameObject::SetVisible(
374         bool v
375         )
376 {
377         m_bVisible = v;
378 }
379
380 // used by Python, and the actuatorshould _not_ be misused by the
381 // scene!
382 void 
383 KX_GameObject::MarkVisible(
384         bool visible
385         )
386 {
387         /* If explicit visibility settings are used, this is
388          * determined on this level. Maybe change this to mesh level
389          * later on? */
390         
391         double* fl = GetOpenGLMatrixPtr()->getPointer();
392         for (size_t i=0;i<m_meshes.size();i++)
393         {
394                 m_meshes[i]->MarkVisible(fl,this,visible,m_bUseObjectColor,m_objectColor);
395         }
396 }
397
398
399 // Always use the flag?
400 void 
401 KX_GameObject::MarkVisible(
402         void
403         )
404 {
405         double* fl = GetOpenGLMatrixPtr()->getPointer();
406         for (size_t i=0;i<m_meshes.size();i++)
407         {
408                 m_meshes[i]->MarkVisible(fl,
409                                          this,
410                                          m_bVisible,
411                                          m_bUseObjectColor,
412                                          m_objectColor
413                         );
414         }
415 }
416
417 void KX_GameObject::addLinearVelocity(const MT_Vector3& lin_vel,bool local)
418 {
419         if (m_pPhysicsController1)
420                 m_pPhysicsController1->SetLinearVelocity(lin_vel + m_pPhysicsController1->GetLinearVelocity(),local);
421 }
422
423
424
425 void KX_GameObject::setLinearVelocity(const MT_Vector3& lin_vel,bool local)
426 {
427         if (m_pPhysicsController1)
428                 m_pPhysicsController1->SetLinearVelocity(lin_vel,local);
429 }
430
431
432
433 void KX_GameObject::setAngularVelocity(const MT_Vector3& ang_vel,bool local)
434 {
435         if (m_pPhysicsController1)
436                 m_pPhysicsController1->SetAngularVelocity(ang_vel,local);
437 }
438
439 void KX_GameObject::ResolveCombinedVelocities(
440         const MT_Vector3 & lin_vel,
441         const MT_Vector3 & ang_vel,
442         bool lin_vel_local,
443         bool ang_vel_local
444 ){
445         if (m_pPhysicsController1)
446         {
447
448                 MT_Vector3 lv = lin_vel_local ? NodeGetWorldOrientation() * lin_vel : lin_vel;
449                 MT_Vector3 av = ang_vel_local ? NodeGetWorldOrientation() * ang_vel : ang_vel;
450                 m_pPhysicsController1->resolveCombinedVelocities(
451                         lv.x(),lv.y(),lv.z(),av.x(),av.y(),av.z());
452         }
453 }
454
455
456 void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec)
457 {
458         m_bUseObjectColor = true;
459         m_objectColor = rgbavec;
460 }
461
462
463
464 MT_Vector3 KX_GameObject::GetLinearVelocity()
465 {
466         MT_Vector3 velocity(0.0,0.0,0.0);
467         
468         if (m_pPhysicsController1)
469         {
470                 velocity = m_pPhysicsController1->GetLinearVelocity();
471         }
472         return velocity;
473         
474 }
475
476
477 // scenegraph node stuff
478
479 void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
480 {
481         if (m_pPhysicsController1)
482         {
483                 m_pPhysicsController1->setPosition(trans);
484         }
485
486         GetSGNode()->SetLocalPosition(trans);
487 }
488
489
490
491 void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
492 {
493         if (m_pPhysicsController1)
494         {
495                 m_pPhysicsController1->setOrientation(rot.getRotation());
496         }
497         
498         GetSGNode()->SetLocalOrientation(rot);
499 }
500
501
502
503 void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
504 {
505         if (m_pPhysicsController1)
506         {
507                 m_pPhysicsController1->setScaling(scale);
508         }
509         
510         GetSGNode()->SetLocalScale(scale);
511 }
512
513
514
515 void KX_GameObject::NodeSetRelativeScale(const MT_Vector3& scale)
516 {
517         GetSGNode()->RelativeScale(scale);
518 }
519
520
521
522 void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
523 {
524         GetSGNode()->UpdateWorldData(time);
525 }
526
527
528
529 const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const
530 {
531         return GetSGNode()->GetWorldOrientation();
532 }
533
534
535
536 const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
537 {
538         return GetSGNode()->GetWorldScaling();
539 }
540
541
542
543 const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
544 {
545         return GetSGNode()->GetWorldPosition();
546 }
547
548 /* Suspend/ resume: for the dynamic behaviour, there is a simple
549  * method. For the residual motion, there is not. I wonder what the
550  * correct solution is for Sumo. Remove from the motion-update tree?
551  *
552  * So far, only switch the physics and logic.
553  * */
554
555 void KX_GameObject::Resume(void)
556 {
557         if (m_suspended) {
558                 SCA_IObject::Resume();
559                 GetPhysicsController()->RestoreDynamics();
560
561                 m_suspended = false;
562         }
563 }
564
565 void KX_GameObject::Suspend(void)
566 {
567         if ((!m_ignore_activity_culling) 
568                 && (!m_suspended))  {
569                 SCA_IObject::Suspend();
570                 GetPhysicsController()->SuspendDynamics();
571                 m_suspended = true;
572         }
573 }
574
575
576
577
578 /* ------- python stuff ---------------------------------------------------*/
579
580
581
582
583 PyMethodDef KX_GameObject::Methods[] = {
584         {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},  
585         {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS},
586         {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS},
587         {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS},
588         {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_VARARGS},
589         {"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
590         {"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
591         {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_VARARGS},
592         {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_VARARGS},
593         {"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS},
594         {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_VARARGS},
595         {"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_VARARGS},
596         {"enableRigidBody", (PyCFunction)KX_GameObject::sPyEnableRigidBody,METH_VARARGS},
597         {"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_VARARGS},
598         {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_VARARGS},
599         {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
600         {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
601         KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
602         
603         {NULL,NULL} //Sentinel
604 };
605
606
607
608 /*
609 bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
610                                                                                         MT_Vector3& pos,
611                                                                                         MT_Vector3& pos2)
612 {
613         PyObject* pylist;
614         PyObject* pylist2;
615         bool error = (PyArg_ParseTuple(args,"OO",&pylist,&pylist2)) != 0;
616
617         pos = ConvertPythonPylist(pylist);
618         pos2 = ConvertPythonPylist(pylist2);
619                 
620         return error;
621 }
622 */
623
624
625 PyObject* KX_GameObject::sPySetPosition(PyObject* self,
626                                                                                 PyObject* args,
627                                                                                 PyObject* kwds)
628 {
629         return ((KX_GameObject*) self)->PySetPosition(self, args, kwds);
630 }
631         
632
633
634 PyObject* KX_GameObject::PyGetPosition(PyObject* self,
635                                                                            PyObject* args, 
636                                                                            PyObject* kwds)
637 {
638         return PyObjectFrom(NodeGetWorldPosition());
639 }
640
641
642
643 PyTypeObject KX_GameObject::Type = {
644         PyObject_HEAD_INIT(&PyType_Type)
645                 0,
646                 "KX_GameObject",
647                 sizeof(KX_GameObject),
648                 0,
649                 PyDestructor,
650                 0,
651                 __getattr,
652                 __setattr,
653                 0, //&MyPyCompare,
654                 __repr,
655                 0, //&cvalue_as_number,
656                 0,
657                 0,
658                 0,
659                 0
660 };
661
662
663
664 PyParentObject KX_GameObject::Parents[] = {
665         &KX_GameObject::Type,
666                 &SCA_IObject::Type,
667                 &CValue::Type,
668                 NULL
669 };
670
671
672
673
674 PyObject* KX_GameObject::_getattr(const STR_String& attr)
675 {
676         if (m_pPhysicsController1)
677         {
678                 if (attr == "mass")
679                         return PyFloat_FromDouble(GetPhysicsController()->GetMass());
680         }
681
682         if (attr == "parent")
683         {       
684                 KX_GameObject* parent = GetParent();
685                 if (parent)
686                 {
687                         parent->AddRef();
688                         return parent;
689                 }
690                 Py_Return;
691         }
692
693         if (attr == "visible")
694                 return PyInt_FromLong(m_bVisible);
695         
696         if (attr == "position")
697                 return PyObjectFrom(NodeGetWorldPosition());
698         
699         if (attr == "orientation")
700                 return PyObjectFrom(NodeGetWorldOrientation());
701         
702         if (attr == "scaling")
703                 return PyObjectFrom(NodeGetWorldScaling());
704                 
705         if (attr == "name")
706                 return PyString_FromString(m_name.ReadPtr());
707         
708         _getattr_up(SCA_IObject);
709 }
710
711 int KX_GameObject::_setattr(const STR_String& attr, PyObject *value)    // _setattr method
712 {
713         if (attr == "mass")
714                 return 1;
715         
716         if (attr == "parent")
717                 return 1;
718                 
719         if (PyInt_Check(value))
720         {
721                 int val = PyInt_AsLong(value);
722                 if (attr == "visible")
723                 {
724                         SetVisible(val != 0);
725                         return 0;
726                 }
727         }
728         
729         if (PySequence_Check(value))
730         {
731                 if (attr == "orientation")
732                 {
733                         MT_Matrix3x3 rot;
734                         if (PyObject_IsMT_Matrix(value, 3))
735                         {
736                                 if (PyMatTo(value, rot))
737                                 {
738                                         NodeSetLocalOrientation(rot);
739                                         return 0;
740                                 }
741                                 return 1;
742                         }
743                         
744                         if (PySequence_Size(value) == 4)
745                         {
746                                 MT_Quaternion qrot;
747                                 if (PyVecTo(value, qrot))
748                                 {
749                                         rot.setRotation(qrot);
750                                         NodeSetLocalOrientation(rot);
751                                         return 0;
752                                 }
753                                 return 1;
754                         }
755                         
756                         if (PySequence_Size(value) == 3)
757                         {
758                                 MT_Vector3 erot;
759                                 if (PyVecTo(value, erot))
760                                 {
761                                         rot.setEuler(erot);
762                                         NodeSetLocalOrientation(rot);
763                                         return 0;
764                                 }
765                                 return 1;
766                         }
767                         
768                         return 1;
769                 }
770                 
771                 if (attr == "position")
772                 {
773                         MT_Point3 pos;
774                         if (PyVecTo(value, pos))
775                         {
776                                 NodeSetLocalPosition(pos);
777                                 return 0;
778                         }
779                         return 1;
780                 }
781                 
782                 if (attr == "scaling")
783                 {
784                         MT_Vector3 scale;
785                         if (PyVecTo(value, scale))
786                         {
787                                 NodeSetLocalScale(scale);
788                                 return 0;
789                         }
790                         return 1;
791                 }
792         }
793         
794         if (PyString_Check(value))
795         {
796                 if (attr == "name")
797                 {
798                         m_name = PyString_AsString(value);
799                         return 0;
800                 }
801         }
802         
803         return SCA_IObject::_setattr(attr, value);
804 }
805
806
807 PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, 
808                                                                                          PyObject* args, 
809                                                                                          PyObject* kwds)
810 {
811         // only can get the velocity if we have a physics object connected to us...
812         return PyObjectFrom(GetLinearVelocity());
813 }
814
815
816
817 PyObject* KX_GameObject::PySetVisible(PyObject* self,
818                                                                           PyObject* args,
819                                                                           PyObject* kwds)
820 {
821         int visible = 1;
822         
823         if (PyArg_ParseTuple(args,"i",&visible))
824         {
825                 MarkVisible(visible!=0);
826                 m_bVisible = (visible!=0);
827         }
828         else
829         {
830                 return NULL;         
831         }
832         Py_Return;
833         
834 }
835
836
837
838 PyObject* KX_GameObject::PyGetVelocity(PyObject* self, 
839                                                                            PyObject* args, 
840                                                                            PyObject* kwds)
841 {
842         // only can get the velocity if we have a physics object connected to us...
843         MT_Vector3 velocity(0.0,0.0,0.0);
844         MT_Point3 point(0.0,0.0,0.0);
845         
846         
847         PyObject* pypos = NULL;
848         if (PyArg_ParseTuple(args, "|O", &pypos))
849         {
850                 if (pypos)
851                         PyVecTo(pypos, point);
852         }
853         
854         if (m_pPhysicsController1)
855         {
856                 velocity = m_pPhysicsController1->GetVelocity(point);
857         }
858         
859         return PyObjectFrom(velocity);
860 }
861
862
863
864 PyObject* KX_GameObject::PyGetMass(PyObject* self, 
865                                                                    PyObject* args, 
866                                                                    PyObject* kwds)
867 {
868         PyObject* pymass = NULL;
869         
870         float mass = GetPhysicsController()->GetMass();
871         pymass = PyFloat_FromDouble(mass);
872
873         if (pymass)
874                 return pymass;
875         
876         Py_Return;
877 }
878
879
880
881 PyObject* KX_GameObject::PyGetReactionForce(PyObject* self, 
882                                                                                         PyObject* args, 
883                                                                                         PyObject* kwds)
884 {
885         // only can get the velocity if we have a physics object connected to us...
886         return PyObjectFrom(GetPhysicsController()->getReactionForce());
887 }
888
889
890
891 PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self, 
892                                                                                    PyObject* args, 
893                                                                                    PyObject* kwds)
894 {
895         
896         GetPhysicsController()->setRigidBody(true);
897
898         Py_Return;
899 }
900
901
902
903 PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self, 
904                                                                                         PyObject* args, 
905                                                                                         PyObject* kwds)
906 {
907         GetPhysicsController()->setRigidBody(false);
908
909         Py_Return;
910 }
911
912
913
914 PyObject* KX_GameObject::PyGetParent(PyObject* self, 
915                                                                          PyObject* args, 
916                                                                          PyObject* kwds)
917 {
918         KX_GameObject* parent = this->GetParent();
919         if (parent)
920         {
921                 parent->AddRef();
922                 return parent;
923         }
924         Py_Return;
925 }
926
927
928
929 PyObject* KX_GameObject::PyGetMesh(PyObject* self, 
930                                                                    PyObject* args, 
931                                                                    PyObject* kwds)
932 {
933         int mesh = 0;
934         
935         if (PyArg_ParseTuple(args, "|i", &mesh))
936         {
937                 if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0)
938                 {
939                         KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[mesh]);
940                         return meshproxy;
941                 }
942         }
943         Py_Return;
944 }
945
946
947
948 PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, 
949                                                                                 PyObject* args, 
950                                                                                 PyObject* kwds)
951 {
952         
953         
954         PyObject* pyattach;
955         PyObject* pyimpulse;
956
957         printf("impulse1\n");
958         
959         
960         if (PyArg_ParseTuple(args, "OO", &pyattach, &pyimpulse))
961         {
962                 MT_Point3  attach;
963                 MT_Vector3 impulse;
964                 printf("impulse2\n");
965         
966                 if (m_pPhysicsController1)
967                 {
968                                 printf("impulse3\n");
969
970                         if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse))
971                         {
972                                 printf("impulse4\n");
973                                 m_pPhysicsController1->applyImpulse(attach, impulse);
974                                 Py_Return;
975                         }
976                 }
977
978         }
979         
980         return NULL;
981 }
982
983
984
985 PyObject* KX_GameObject::PySuspendDynamics(PyObject* self, 
986                                                                                    PyObject* args, 
987                                                                                    PyObject* kwds)
988 {
989         if (m_bSuspendDynamics)
990         {
991                 Py_Return;
992         }
993         
994         if (m_pPhysicsController1)
995         {
996                 m_pPhysicsController1->SuspendDynamics();
997         }
998         m_bSuspendDynamics = true;
999         
1000         Py_Return;
1001 }
1002
1003
1004
1005 PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self, 
1006                                                                                    PyObject* args, 
1007                                                                                    PyObject* kwds)
1008 {
1009         
1010         if (!m_bSuspendDynamics)
1011         {
1012                 Py_Return;
1013         }
1014         
1015         if (m_pPhysicsController1)
1016         {
1017                 m_pPhysicsController1->RestoreDynamics();
1018         }
1019         m_bSuspendDynamics = false;
1020         
1021         Py_Return;
1022 }
1023
1024
1025
1026 PyObject* KX_GameObject::PyGetOrientation(PyObject* self,
1027                                                                                   PyObject* args,
1028                                                                                   PyObject* kwds) //keywords
1029 {
1030         return PyObjectFrom(NodeGetWorldOrientation());
1031 }
1032
1033
1034
1035 PyObject* KX_GameObject::PySetOrientation(PyObject* self, 
1036                                                                                   PyObject* args, 
1037                                                                                   PyObject* kwds)
1038 {
1039         PyObject* pylist;
1040         
1041         if (PyArg_ParseTuple(args,"O",&pylist))
1042         {
1043                 MT_Matrix3x3 matrix;
1044                 if (PyObject_IsMT_Matrix(pylist, 3) && PyMatTo(pylist, matrix))
1045                 {
1046                         NodeSetLocalOrientation(matrix);
1047                         Py_Return;
1048                 }
1049         
1050                 MT_Quaternion quat;
1051                 if (PyVecTo(pylist, quat))
1052                 {
1053                         matrix.setRotation(quat);
1054                         NodeSetLocalOrientation(matrix);
1055                         Py_Return;
1056                 }
1057         }
1058         return NULL;
1059 }
1060
1061
1062
1063 PyObject* KX_GameObject::PySetPosition(PyObject* self, 
1064                                                                            PyObject* args, 
1065                                                                            PyObject* kwds)
1066 {
1067         MT_Point3 pos;
1068         if (PyVecArgTo(args, pos))
1069         {
1070                 NodeSetLocalPosition(pos);
1071                 Py_Return;
1072         }
1073         
1074         return NULL;
1075 }
1076
1077 PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self,
1078                                                                                            PyObject* args,
1079                                                                                            PyObject* kwds)
1080 {
1081         KX_IPhysicsController* ctrl = GetPhysicsController();
1082         int physid=0;
1083         if (ctrl)
1084         {
1085                 physid= (int)ctrl->GetUserData();
1086         }
1087         return PyInt_FromLong(physid);
1088 }
1089
1090 KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
1091 "getDistanceTo(other): get distance to another point/KX_GameObject")
1092 {
1093         MT_Point3 b;
1094         if (PyVecArgTo(args, b))
1095         {
1096                 return PyFloat_FromDouble(NodeGetWorldPosition().distance(b));
1097         }
1098         PyErr_Clear();
1099         
1100         PyObject *pyother;
1101         if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &pyother))
1102         {
1103                 KX_GameObject *other = static_cast<KX_GameObject*>(pyother);
1104                 return PyFloat_FromDouble(NodeGetWorldPosition().distance(other->NodeGetWorldPosition()));
1105         }
1106         
1107         return NULL;
1108 }
1109
1110
1111 /* --------------------------------------------------------------------- 
1112  * Some stuff taken from the header
1113  * --------------------------------------------------------------------- */
1114 void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)        
1115 {
1116         /* intentionally empty ? */
1117 }
1118