diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-03-18 00:44:58 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-03-18 00:44:58 +0300 |
commit | d52400bfbd2a7e4d09b5a71bc461a554d232af15 (patch) | |
tree | 08815f065fc90aac0ae62ae5f3a89d20e19399e6 /source/gameengine | |
parent | 1ac0d54fea831c485e8e27e8bfa887e15beb58de (diff) | |
parent | 28f6d223d079b1e5cb67e3fc22fb7f818deb8dcb (diff) |
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r18677:19317
Notes:
* Sequence transform strip uses G.scene global, this is commented
out now, should be fixed.
* Etch-a-ton code was most difficult to merge. The files already in
2.5 got merged, but no new files were added. Calls to these files
are commented out with "XXX etch-a-ton". editarmature.c and
transform_snap.c were complex to merge. Martin, please check?
* Game engine compiles and links again here for scons/make/cmake
(player still fails to link).
Diffstat (limited to 'source/gameengine')
212 files changed, 3034 insertions, 1859 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 8d443b9b386..90d5a1860aa 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -576,10 +576,12 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, // get some preferences SYS_SystemHandle syshandle = SYS_GetSystem(); + /* bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); + */ bool game2ipo = true;//(SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0); bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); bool usemat = false; diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 2300323a55e..e090a4b9c56 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -40,5 +40,9 @@ SET(INC ${PYTHON_INC} ) +IF(WITH_FFMPEG) + ADD_DEFINITIONS(-DWITH_FFMPEG) +ENDIF(WITH_FFMPEG) + BLENDERLIB(bf_blroutines "${SRC}" "${INC}") #env.BlenderLib ( 'bf_bloutines', sources, Split(incs), [], libtype=['game', 'game2', 'player'], priority=[0, 0, 55] , compileflags=cxxflags) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 1797d6c1a0f..42ad7769cbd 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -80,7 +80,7 @@ void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty) * has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in * a scene. */ -void KX_BlenderRenderTools::ProcessLighting(int layer, const MT_Transform& viewmat) +void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat) { if(m_lastlightlayer == layer) return; @@ -101,12 +101,12 @@ void KX_BlenderRenderTools::ProcessLighting(int layer, const MT_Transform& viewm } if(enable) - EnableOpenGLLights(); + EnableOpenGLLights(rasty); else DisableOpenGLLights(); } -void KX_BlenderRenderTools::EnableOpenGLLights() +void KX_BlenderRenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty) { if(m_lastlighting == true) return; @@ -115,7 +115,8 @@ void KX_BlenderRenderTools::EnableOpenGLLights() glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE); if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index a7618462c9b..ebf7562503f 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -60,9 +60,9 @@ public: void EndFrame(RAS_IRasterizer* rasty); void BeginFrame(RAS_IRasterizer* rasty); - void EnableOpenGLLights(); + void EnableOpenGLLights(RAS_IRasterizer *rasty); void DisableOpenGLLights(); - void ProcessLighting(int layer, const MT_Transform& viewmat); + void ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat); void RenderText2D(RAS_TEXT_RENDER_MODE mode, const char* text, diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile index b1be56ac47f..03a7a247727 100644 --- a/source/gameengine/BlenderRoutines/Makefile +++ b/source/gameengine/BlenderRoutines/Makefile @@ -77,3 +77,6 @@ endif CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) +ifeq ($(WITH_FFMPEG), true) + CPPFLAGS += -DWITH_FFMPEG +endif diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index f7a3971e288..020402e9bcd 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -2,6 +2,7 @@ Import ('env') sources = env.Glob('*.cpp') +defs = [] incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc' incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #intern/bmfont' @@ -12,19 +13,27 @@ incs += ' #source/blender/blenkernel #source/blender #source/blender/editors/inc incs += ' #source/blender/makesdna #source/gameengine/Rasterizer #source/gameengine/GameLogic' incs += ' #source/gameengine/Expressions #source/gameengine/Network' incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common' -incs += ' #source/gameengine/Physics/Bullet #source/gameengine/Physics/Sumo' -incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' +incs += ' #source/gameengine/Physics/Bullet' +incs += ' #source/gameengine/Network/LoopBackNetwork' incs += ' #intern/SoundSystem #source/blender/misc #source/blender/blenloader' incs += ' #extern/glew/include #source/blender/gpu' incs += ' #source/blender/windowmanager' +if env['WITH_BF_SOLID']: + incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' + incs += ' ' + env['BF_SOLID_INC'] + defs.append('USE_SUMO_SOLID') + +if env['WITH_BF_FFMPEG']: + defs.append('WITH_FFMPEG') + incs += ' ' + env['BF_PYTHON_INC'] -incs += ' ' + env['BF_SOLID_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] cxxflags = [] if env['OURPLATFORM']=='win32-vc': cxxflags.append ('/GR') + cxxflags.append ('/O2') -env.BlenderLib ( 'bf_bloutines', sources, Split(incs), [], libtype=['core', 'player'], priority=[300, 45] , compileflags=cxxflags) +env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 45] , cxx_compileflags=cxxflags) diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 536faa11b03..ce555fc1aeb 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -391,7 +391,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) /* Find percentages */ newweight = (m_blendframe/(float)m_blendin); - blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND); + // XXX blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND); /* Increment current blending percentage */ m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate(); @@ -1035,8 +1035,8 @@ PyAttributeDef BL_ActionActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* BL_ActionActuator::_getattr(const STR_String& attr) { - if (attr == "action") +PyObject* BL_ActionActuator::_getattr(const char *attr) { + if (!strcmp(attr, "action")) return PyString_FromString(m_action->id.name+2); PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) @@ -1044,8 +1044,8 @@ PyObject* BL_ActionActuator::_getattr(const STR_String& attr) { _getattr_up(SCA_IActuator); } -int BL_ActionActuator::_setattr(const STR_String& attr, PyObject* value) { - if (attr == "action") +int BL_ActionActuator::_setattr(const char *attr, PyObject* value) { + if (!strcmp(attr, "action")) { if (!PyString_Check(value)) { diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 6e291106553..6161048afb8 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -110,8 +110,8 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,setChannel); - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject* value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); /* attribute check */ static int CheckFrame(void *self, const PyAttributeDef*) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 45461205fbb..da74fa49cba 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -361,7 +361,7 @@ BL_Material* ConvertMaterial( facetex = true; if(validface && mat->mtex[0]) { MTex *tmp = mat->mtex[0]; - if(!tmp->tex || tmp->tex && !tmp->tex->ima ) + if(!tmp->tex || (tmp->tex && !tmp->tex->ima)) facetex = true; } numchan = numchan>MAXTEX?MAXTEX:numchan; @@ -593,7 +593,7 @@ BL_Material* ConvertMaterial( MT_Point2 uv2[4]; const char *uvName = "", *uv2Name = ""; - uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); + uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f); if( validface ) { @@ -607,12 +607,12 @@ BL_Material* ConvertMaterial( material->tile = tface->tile; material->mode = tface->mode; - uv[0] = MT_Point2(tface->uv[0]); - uv[1] = MT_Point2(tface->uv[1]); - uv[2] = MT_Point2(tface->uv[2]); + uv[0].setValue(tface->uv[0]); + uv[1].setValue(tface->uv[1]); + uv[2].setValue(tface->uv[2]); if (mface->v4) - uv[3] = MT_Point2(tface->uv[3]); + uv[3].setValue(tface->uv[3]); uvName = tfaceName; } @@ -622,6 +622,8 @@ BL_Material* ConvertMaterial( material->mode = default_face_mode; material->transp = TF_SOLID; material->tile = 0; + + uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); } // with ztransp enabled, enforce alpha blending mode @@ -665,14 +667,14 @@ BL_Material* ConvertMaterial( { MT_Point2 uvSet[4]; - uvSet[0] = MT_Point2(layer.face->uv[0]); - uvSet[1] = MT_Point2(layer.face->uv[1]); - uvSet[2] = MT_Point2(layer.face->uv[2]); + uvSet[0].setValue(layer.face->uv[0]); + uvSet[1].setValue(layer.face->uv[1]); + uvSet[2].setValue(layer.face->uv[2]); if (mface->v4) - uvSet[3] = MT_Point2(layer.face->uv[3]); + uvSet[3].setValue(layer.face->uv[3]); else - uvSet[3] = MT_Point2(0.0f, 0.0f); + uvSet[3].setValue(0.0f, 0.0f); if (isFirstSet) { @@ -790,10 +792,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0); /* get coordinates, normals and tangents */ - pt0 = MT_Point3(mvert[mface->v1].co); - pt1 = MT_Point3(mvert[mface->v2].co); - pt2 = MT_Point3(mvert[mface->v3].co); - pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0); + pt0.setValue(mvert[mface->v1].co); + pt1.setValue(mvert[mface->v2].co); + pt2.setValue(mvert[mface->v3].co); + if (mface->v4) pt3.setValue(mvert[mface->v4].co); if(mface->flag & ME_SMOOTH) { float n0[3], n1[3], n2[3], n3[3]; @@ -894,12 +896,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* visible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE)); - uv0 = MT_Point2(tface->uv[0]); - uv1 = MT_Point2(tface->uv[1]); - uv2 = MT_Point2(tface->uv[2]); + uv0.setValue(tface->uv[0]); + uv1.setValue(tface->uv[1]); + uv2.setValue(tface->uv[2]); if (mface->v4) - uv3 = MT_Point2(tface->uv[3]); + uv3.setValue(tface->uv[3]); } else { /* no texfaces, set COLLSION true and everything else FALSE */ @@ -960,7 +962,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref); } else { - polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f); + polymat->m_specular.setValue(0.0f,0.0f,0.0f); polymat->m_shininess = 35.0; } } @@ -1313,6 +1315,12 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, CreateMaterialFromBlenderObject(blenderobject, kxscene); KX_ObjectProperties objprop; + objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0; + objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0; + objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0; + objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0; + objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0; + objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0; objprop.m_isCompoundChild = isCompoundChild; objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0; @@ -1911,21 +1919,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie, MT_Matrix3x3 angor; if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra; - MT_Point3 pos = MT_Point3( + MT_Point3 pos; + pos.setValue( blenderobject->loc[0]+blenderobject->dloc[0], blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[2]+blenderobject->dloc[2] ); - MT_Vector3 eulxyz = MT_Vector3( - blenderobject->rot[0], - blenderobject->rot[1], - blenderobject->rot[2] - ); - MT_Vector3 scale = MT_Vector3( - blenderobject->size[0], - blenderobject->size[1], - blenderobject->size[2] - ); + MT_Vector3 eulxyz(blenderobject->rot); + MT_Vector3 scale(blenderobject->size); if (converter->addInitFromFrame){//rcruiz float eulxyzPrev[3]; blenderscene->r.cfra=blenderscene->r.sfra-1; @@ -1997,18 +1998,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie, MT_Vector3 x(ori.getColumn(0)); MT_Vector3 y(ori.getColumn(1)); MT_Vector3 z(ori.getColumn(2)); - MT_Vector3 scale(x.length(), y.length(), z.length()); - if (!MT_fuzzyZero(scale[0])) - x /= scale[0]; - if (!MT_fuzzyZero(scale[1])) - y /= scale[1]; - if (!MT_fuzzyZero(scale[2])) - z /= scale[2]; + MT_Vector3 parscale(x.length(), y.length(), z.length()); + if (!MT_fuzzyZero(parscale[0])) + x /= parscale[0]; + if (!MT_fuzzyZero(parscale[1])) + y /= parscale[1]; + if (!MT_fuzzyZero(parscale[2])) + z /= parscale[2]; ori.setColumn(0, x); ori.setColumn(1, y); ori.setColumn(2, z); parentinversenode->SetLocalOrientation(ori); - parentinversenode->SetLocalScale(scale); + parentinversenode->SetLocalScale(parscale); parentinversenode->AddChild(gameobj->GetSGNode()); } @@ -2113,21 +2114,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra; - MT_Point3 pos = MT_Point3( + MT_Point3 pos( blenderobject->loc[0]+blenderobject->dloc[0], blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[2]+blenderobject->dloc[2] ); - MT_Vector3 eulxyz = MT_Vector3( - blenderobject->rot[0], - blenderobject->rot[1], - blenderobject->rot[2] - ); - MT_Vector3 scale = MT_Vector3( - blenderobject->size[0], - blenderobject->size[1], - blenderobject->size[2] - ); + MT_Vector3 eulxyz(blenderobject->rot); + MT_Vector3 scale(blenderobject->size); if (converter->addInitFromFrame){//rcruiz float eulxyzPrev[3]; blenderscene->r.cfra=blenderscene->r.sfra-1; @@ -2194,18 +2187,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie, MT_Vector3 x(ori.getColumn(0)); MT_Vector3 y(ori.getColumn(1)); MT_Vector3 z(ori.getColumn(2)); - MT_Vector3 scale(x.length(), y.length(), z.length()); - if (!MT_fuzzyZero(scale[0])) - x /= scale[0]; - if (!MT_fuzzyZero(scale[1])) - y /= scale[1]; - if (!MT_fuzzyZero(scale[2])) - z /= scale[2]; + MT_Vector3 localscale(x.length(), y.length(), z.length()); + if (!MT_fuzzyZero(localscale[0])) + x /= localscale[0]; + if (!MT_fuzzyZero(localscale[1])) + y /= localscale[1]; + if (!MT_fuzzyZero(localscale[2])) + z /= localscale[2]; ori.setColumn(0, x); ori.setColumn(1, y); ori.setColumn(2, z); parentinversenode->SetLocalOrientation(ori); - parentinversenode->SetLocalScale(scale); + parentinversenode->SetLocalScale(localscale); parentinversenode->AddChild(gameobj->GetSGNode()); } diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index fa3b8185fe2..80112346c72 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -51,7 +51,6 @@ bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*) { size_t i; - float *co; // only apply once per frame if the mesh is actually modified if(m_pMeshObject->MeshModified() && @@ -70,8 +69,7 @@ bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*) // For each vertex for(i=it.startvertex; i<it.endvertex; i++) { RAS_TexVert& v = it.vertex[i]; - co = m_bmesh->mvert[v.getOrigIndex()].co; - v.SetXYZ(MT_Point3(co)); + v.SetXYZ(m_bmesh->mvert[v.getOrigIndex()].co); } } } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index df1aed38ceb..f4e3e7e0ae8 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -484,8 +484,8 @@ PyAttributeDef BL_ShapeActionActuator::Attributes[] = { }; -PyObject* BL_ShapeActionActuator::_getattr(const STR_String& attr) { - if (attr == "action") +PyObject* BL_ShapeActionActuator::_getattr(const char *attr) { + if (!strcmp(attr, "action")) return PyString_FromString(m_action->id.name+2); PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) @@ -493,8 +493,8 @@ PyObject* BL_ShapeActionActuator::_getattr(const STR_String& attr) { _getattr_up(SCA_IActuator); } -int BL_ShapeActionActuator::_setattr(const STR_String& attr, PyObject* value) { - if (attr == "action") +int BL_ShapeActionActuator::_setattr(const char *attr, PyObject* value) { + if (!strcmp(attr, "action")) { if (!PyString_Check(value)) { @@ -911,6 +911,6 @@ PyObject* BL_ShapeActionActuator::PySetType(PyObject* self, printf("Invalid type for action actuator: %d\n", typeArg); /* error */ } - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index b521c0d98a6..7f2431bcfa5 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -103,8 +103,8 @@ public: KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetType); KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetType); - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject* value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); static int CheckBlendTime(void *self, const PyAttributeDef*) { @@ -169,8 +169,8 @@ protected: short m_playtype; short m_priority; struct bAction *m_action; - STR_String m_propname; STR_String m_framepropname; + STR_String m_propname; vector<float> m_blendshape; }; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 7b68dbda176..7daca6c32fe 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -321,7 +321,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/ int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0); if (visualizePhysics) - ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText); + ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints); //todo: get a button in blender ? //disable / enable debug drawing (contact points, aabb's etc) @@ -663,7 +663,7 @@ extern "C" Ipo *add_ipo( char *name, int idcode ); //XXX char *getIpoCurveName( IpoCurve * icu ); //XXX struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int); - void testhandles_ipocurve(struct IpoCurve *icu); + //XXX void testhandles_ipocurve(struct IpoCurve *icu); void insert_vert_icu(struct IpoCurve *, float, float, short); void Mat3ToEul(float tmat[][3], float *eul); } @@ -751,7 +751,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) } } } else - { ipo = add_ipo(blenderObject->id.name+2, ID_OB); + { ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB); blenderObject->ipo = ipo; } @@ -907,7 +907,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) float curVal = position.x(); //XXX insert_vert_icu(icu1, frameNumber, curVal, 0); #ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); #endif } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); @@ -917,7 +917,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) //XXX insert_vert_icu(icu1, frameNumber, curVal, 0); #ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); #endif } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); @@ -926,7 +926,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) float curVal = position.z(); //XXX insert_vert_icu(icu1, frameNumber, curVal, 0); #ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); #endif } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); @@ -936,7 +936,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) //XXX insert_vert_icu(icu1, frameNumber, curVal, 0); #ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); #endif } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); @@ -946,7 +946,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) //XXX insert_vert_icu(icu1, frameNumber, curVal, 0); #ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); #endif } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); @@ -956,7 +956,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) //XXX insert_vert_icu(icu1, frameNumber, curVal, 0); #ifdef TEST_HANDLES_GAME2IPO - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); #endif } @@ -1060,32 +1060,32 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo() icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); if (icu1) { - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); if (icu1) { - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); if (icu1) { - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); if (icu1) { - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); if (icu1) { - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); } icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); if (icu1) { - testhandles_ipocurve(icu1); + //XXX testhandles_ipocurve(icu1); } } diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp index da490b4ee85..fb100b0a68b 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.cpp +++ b/source/gameengine/Converter/KX_ConvertControllers.cpp @@ -200,6 +200,13 @@ void BL_ConvertControllers( gameobj->AddController(gamecontroller); converter->RegisterGameController(gamecontroller, bcontr); + + if (bcontr->type==CONT_PYTHON) { + /* not strictly needed but gives syntax errors early on and + * gives more pradictable performance for larger scripts */ + (static_cast<SCA_PythonController*>(gamecontroller))->Compile(); + } + //done with gamecontroller gamecontroller->Release(); } diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index b7b47b3b39f..c91197b72a6 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -317,12 +317,12 @@ void BL_ConvertSensors(struct Object* blenderobject, { // collision sensor can sense both materials and properties. - bool bFindMaterial = false; + bool bFindMaterial = false, bTouchPulse = false; bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data; - bFindMaterial = (blendertouchsensor->mode - & SENS_COLLISION_MATERIAL); + bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL); + bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE); STR_String touchPropOrMatName = ( bFindMaterial ? @@ -335,6 +335,7 @@ void BL_ConvertSensors(struct Object* blenderobject, gamesensor = new KX_TouchSensor(eventmgr, gameobj, bFindMaterial, + bTouchPulse, touchPropOrMatName); } @@ -360,6 +361,7 @@ void BL_ConvertSensors(struct Object* blenderobject, gamesensor = new KX_TouchSensor(eventmgr, gameobj, bFindMaterial, + false, touchpropertyname); } } diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp index ce004fa0504..f19390db8a9 100644 --- a/source/gameengine/Converter/KX_IpoConvert.cpp +++ b/source/gameengine/Converter/KX_IpoConvert.cpp @@ -311,67 +311,67 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend } { - KX_ObColorIpoSGController* ipocontr=NULL; + KX_ObColorIpoSGController* ipocontr_obcol=NULL; ipo = ipoList->GetScalarInterpolator(OB_COL_R); if (ipo) { - if (!ipocontr) + if (!ipocontr_obcol) { - ipocontr = new KX_ObColorIpoSGController(); - gameobj->GetSGNode()->AddSGController(ipocontr); - ipocontr->SetObject(gameobj->GetSGNode()); + ipocontr_obcol = new KX_ObColorIpoSGController(); + gameobj->GetSGNode()->AddSGController(ipocontr_obcol); + ipocontr_obcol->SetObject(gameobj->GetSGNode()); } KX_IInterpolator *interpolator = new KX_ScalarInterpolator( - &ipocontr->m_rgba[0], + &ipocontr_obcol->m_rgba[0], ipo); - ipocontr->AddInterpolator(interpolator); + ipocontr_obcol->AddInterpolator(interpolator); } ipo = ipoList->GetScalarInterpolator(OB_COL_G); if (ipo) { - if (!ipocontr) + if (!ipocontr_obcol) { - ipocontr = new KX_ObColorIpoSGController(); - gameobj->GetSGNode()->AddSGController(ipocontr); - ipocontr->SetObject(gameobj->GetSGNode()); + ipocontr_obcol = new KX_ObColorIpoSGController(); + gameobj->GetSGNode()->AddSGController(ipocontr_obcol); + ipocontr_obcol->SetObject(gameobj->GetSGNode()); } KX_IInterpolator *interpolator = new KX_ScalarInterpolator( - &ipocontr->m_rgba[1], + &ipocontr_obcol->m_rgba[1], ipo); - ipocontr->AddInterpolator(interpolator); + ipocontr_obcol->AddInterpolator(interpolator); } ipo = ipoList->GetScalarInterpolator(OB_COL_B); if (ipo) { - if (!ipocontr) + if (!ipocontr_obcol) { - ipocontr = new KX_ObColorIpoSGController(); - gameobj->GetSGNode()->AddSGController(ipocontr); - ipocontr->SetObject(gameobj->GetSGNode()); + ipocontr_obcol = new KX_ObColorIpoSGController(); + gameobj->GetSGNode()->AddSGController(ipocontr_obcol); + ipocontr_obcol->SetObject(gameobj->GetSGNode()); } KX_IInterpolator *interpolator = new KX_ScalarInterpolator( - &ipocontr->m_rgba[2], + &ipocontr_obcol->m_rgba[2], ipo); - ipocontr->AddInterpolator(interpolator); + ipocontr_obcol->AddInterpolator(interpolator); } ipo = ipoList->GetScalarInterpolator(OB_COL_A); if (ipo) { - if (!ipocontr) + if (!ipocontr_obcol) { - ipocontr = new KX_ObColorIpoSGController(); - gameobj->GetSGNode()->AddSGController(ipocontr); - ipocontr->SetObject(gameobj->GetSGNode()); + ipocontr_obcol = new KX_ObColorIpoSGController(); + gameobj->GetSGNode()->AddSGController(ipocontr_obcol); + ipocontr_obcol->SetObject(gameobj->GetSGNode()); } KX_IInterpolator *interpolator = new KX_ScalarInterpolator( - &ipocontr->m_rgba[3], + &ipocontr_obcol->m_rgba[3], ipo); - ipocontr->AddInterpolator(interpolator); + ipocontr_obcol->AddInterpolator(interpolator); } } diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 5c2ab49a04c..98b7c71bad2 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -2,6 +2,7 @@ Import ('env') sources = env.Glob('*.cpp') +defs = [] incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc' incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #intern/bmfont' @@ -14,13 +15,17 @@ incs += ' #source/blender/editors/include #source/blender/makesdna #source/gamee incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #source/gameengine/GameLogic' incs += ' #source/gameengine/Expressions #source/gameengine/Network #source/gameengine/SceneGraph' incs += ' #source/gameengine/Physics/common #source/gameengine/Physics/Bullet #source/gameengine/Physics/BlOde' -incs += ' #source/gameengine/Physics/Dummy #source/gameengine/Physics/Sumo' -incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' +incs += ' #source/gameengine/Physics/Dummy' +incs += ' #source/gameengine/Network/LoopBackNetwork' incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu' incs += ' #source/blender/windowmanager' +if env['WITH_BF_SOLID']: + incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include' + incs += ' ' + env['BF_SOLID_INC'] + defs.append('USE_SUMO_SOLID') + incs += ' ' + env['BF_PYTHON_INC'] -incs += ' ' + env['BF_SOLID_INC'] incs += ' ' + env['BF_BULLET_INC'] -env.BlenderLib ( 'bf_converter', sources, Split(incs), [], libtype=['core','player'], priority=[305,50] ) +env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,50] ) diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp index 93f102d04a6..460eaa73f35 100644 --- a/source/gameengine/Expressions/FloatValue.cpp +++ b/source/gameengine/Expressions/FloatValue.cpp @@ -127,6 +127,9 @@ ret: a new object containing the result of applying operator op to val and { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CFloatValue(fmod(((CIntValue *) val)->GetInt(), m_float)); + break; case VALUE_ADD_OPERATOR: ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float); break; @@ -171,6 +174,9 @@ ret: a new object containing the result of applying operator op to val and { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_float)); + break; case VALUE_ADD_OPERATOR: ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float); break; diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index 32a9de32e21..94663c4a365 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -38,6 +38,9 @@ // cool things like (IF(LOD==1,CCurvedValue,IF(LOD==2,CCurvedValue2)) etc... #include "IfExpr.h" +#if defined(WIN32) || defined(WIN64) +#define strcasecmp _stricmp +#endif /* Def WIN32 or Def WIN64 */ #define NUM_PRIORITY 6 ////////////////////////////////////////////////////////////////////// @@ -172,6 +175,9 @@ void CParser::NextSym() case ',': sym = commasym; NextCh(); break; + case '%' : + sym = opsym; opkind = OPmodulus; NextCh(); + break; case '+' : sym = opsym; opkind = OPplus; NextCh(); break; @@ -271,33 +277,30 @@ void CParser::NextSym() } else if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) { // reserved word? - int start; - STR_String funstr; + start = chcount; CharRep(); GrabString(start); - funstr = const_as_string; - funstr.Upper(); - if (funstr == STR_String("SUM")) { + if (!strcasecmp(const_as_string, "SUM")) { sym = sumsym; } - else if (funstr == STR_String("NOT")) { + else if (!strcasecmp(const_as_string, "NOT")) { sym = opsym; opkind = OPnot; } - else if (funstr == STR_String("AND")) { + else if (!strcasecmp(const_as_string, "AND")) { sym = opsym; opkind = OPand; } - else if (funstr == STR_String("OR")) { + else if (!strcasecmp(const_as_string, "OR")) { sym = opsym; opkind = OPor; } - else if (funstr == STR_String("IF")) { + else if (!strcasecmp(const_as_string, "IF")) sym = ifsym; - } else if (funstr == STR_String("WHOMADE")) { + else if (!strcasecmp(const_as_string, "WHOMADE")) sym = whocodedsym; - } else if (funstr == STR_String("FALSE")) { + else if (!strcasecmp(const_as_string, "FALSE")) { sym = constsym; constkind = booltype; boolvalue = false; - } else if (funstr == STR_String("TRUE")) { + } else if (!strcasecmp(const_as_string, "TRUE")) { sym = constsym; constkind = booltype; boolvalue = true; } else { sym = idsym; @@ -370,6 +373,7 @@ int CParser::Priority(int optorkind) { case OPunequal: return 3; case OPplus: case OPminus: return 4; + case OPmodulus: case OPtimes: case OPdivide: return 5; } @@ -390,6 +394,7 @@ CExpression *CParser::Ex(int i) { NextSym(); e2 = Ex(i + 1); switch(opkind2) { + case OPmodulus: e1 = new COperator2Expr(VALUE_MOD_OPERATOR,e1, e2); break; case OPplus: e1 = new COperator2Expr(VALUE_ADD_OPERATOR,e1, e2); break; case OPminus: e1 = new COperator2Expr(VALUE_SUB_OPERATOR,e1, e2); break; case OPtimes: e1 = new COperator2Expr(VALUE_MUL_OPERATOR,e1, e2); break; diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h index 4caa47cbb0c..f51c473ba18 100644 --- a/source/gameengine/Expressions/InputParser.h +++ b/source/gameengine/Expressions/InputParser.h @@ -49,6 +49,7 @@ private: }; // all kinds of symbols enum optype { + OPmodulus, OPplus, OPminus, OPtimes, diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index fbf4f4f59e0..fb586cb4979 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -125,6 +125,9 @@ this object case VALUE_INT_TYPE: { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CIntValue (((CIntValue *) val)->GetInt() % m_int); + break; case VALUE_ADD_OPERATOR: ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int); break; @@ -181,6 +184,9 @@ this object case VALUE_FLOAT_TYPE: { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_int)); + break; case VALUE_ADD_OPERATOR: ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int); break; diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 9ffdbb1223c..90a939af236 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -34,7 +34,12 @@ Py_ssize_t listvalue_bufferlen(PyObject* list) PyObject* listvalue_buffer_item(PyObject* list,Py_ssize_t index) { - if (index >= 0 && index < ((CListValue*) list)->GetCount()) + int count = ((CListValue*) list)->GetCount(); + + if (index < 0) + index = count+index; + + if (index >= 0 && index < count) { PyObject* pyobj = ((CListValue*) list)->GetValue(index)->ConvertValueToPython(); if (pyobj) @@ -64,8 +69,7 @@ PyObject* listvalue_mapping_subscript(PyObject* list,PyObject* pyindex) } PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */ - STR_String index_str(PyString_AsString(pyindex_str)); - PyErr_Format(PyExc_KeyError, "'%s' not in list", index_str.Ptr()); + PyErr_Format(PyExc_KeyError, "'%s' not in list", PyString_AsString(pyindex_str)); Py_DECREF(pyindex_str); return NULL; } @@ -220,17 +224,19 @@ PyParentObject CListValue::Parents[] = { PyMethodDef CListValue::Methods[] = { - {"append", (PyCFunction)CListValue::sPyappend,METH_VARARGS}, - {"reverse", (PyCFunction)CListValue::sPyreverse,METH_VARARGS}, - {"index", (PyCFunction)CListValue::sPyindex,METH_VARARGS}, - {"count", (PyCFunction)CListValue::sPycount,METH_VARARGS}, + {"append", (PyCFunction)CListValue::sPyappend,METH_O}, + {"reverse", (PyCFunction)CListValue::sPyreverse,METH_NOARGS}, + {"index", (PyCFunction)CListValue::sPyindex,METH_O}, + {"count", (PyCFunction)CListValue::sPycount,METH_O}, {NULL,NULL} //Sentinel }; +PyAttributeDef CListValue::Attributes[] = { + { NULL } //Sentinel +}; - -PyObject* CListValue::_getattr(const STR_String& attr) { +PyObject* CListValue::_getattr(const char *attr) { _getattr_up(CValue); } @@ -399,34 +405,17 @@ void CListValue::MergeList(CListValue *otherlist) -PyObject* CListValue::Pyappend(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* CListValue::Pyappend(PyObject* self, PyObject* value) { - - PyObject* pyobj = NULL; - if (PyArg_ParseTuple(args,"O",&pyobj)) - { - return listvalue_buffer_concat(self,pyobj); - } - else - { - return NULL; - } - - + return listvalue_buffer_concat(self, value); } -PyObject* CListValue::Pyreverse(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* CListValue::Pyreverse(PyObject* self) { std::reverse(m_pValueArray.begin(),m_pValueArray.end()); - - Py_Return; - + Py_RETURN_NONE; } @@ -448,58 +437,56 @@ bool CListValue::CheckEqual(CValue* first,CValue* second) -PyObject* CListValue::Pyindex(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* CListValue::Pyindex(PyObject* self, PyObject *value) { PyObject* result = NULL; - PyObject* pyobj = NULL; - if (PyArg_ParseTuple(args,"O",&pyobj)) + CValue* checkobj = ConvertPythonToValue(value); + if (checkobj==NULL) + return NULL; /* ConvertPythonToValue sets the error */ + + int numelem = GetCount(); + for (int i=0;i<numelem;i++) { - - CValue* checkobj = ConvertPythonToValue(pyobj); - int numelem = GetCount(); - for (int i=0;i<numelem;i++) + CValue* elem = GetValue(i); + if (CheckEqual(checkobj,elem)) { - CValue* elem = GetValue(i); - if (CheckEqual(checkobj,elem)) - { - result = PyInt_FromLong(i); - break; - } + result = PyInt_FromLong(i); + break; } - checkobj->Release(); } + checkobj->Release(); + if (result==NULL) { + PyErr_SetString(PyExc_ValueError, "ValueError: list.index(x): x not in CListValue"); + } return result; } -PyObject* CListValue::Pycount(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* CListValue::Pycount(PyObject* self, PyObject* value) { - int numfound = 0; - PyObject* pyobj = NULL; - if (PyArg_ParseTuple(args,"O",&pyobj)) + CValue* checkobj = ConvertPythonToValue(value); + + if (checkobj==NULL) { /* in this case just return that there are no items in the list */ + PyErr_Clear(); + PyInt_FromLong(0); + } + + int numelem = GetCount(); + for (int i=0;i<numelem;i++) { - CValue* checkobj = ConvertPythonToValue(pyobj); - int numelem = GetCount(); - for (int i=0;i<numelem;i++) + CValue* elem = GetValue(i); + if (CheckEqual(checkobj,elem)) { - CValue* elem = GetValue(i); - if (CheckEqual(checkobj,elem)) - { - numfound ++; - } + numfound ++; } - checkobj->Release(); } + checkobj->Release(); return PyInt_FromLong(numfound); } diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 431f8f558a9..104e3e63283 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -59,12 +59,12 @@ public: bool CheckEqual(CValue* first,CValue* second); - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); - KX_PYMETHOD(CListValue,append); - KX_PYMETHOD(CListValue,reverse); - KX_PYMETHOD(CListValue,index); - KX_PYMETHOD(CListValue,count); + KX_PYMETHOD_O(CListValue,append); + KX_PYMETHOD_NOARGS(CListValue,reverse); + KX_PYMETHOD_O(CListValue,index); + KX_PYMETHOD_O(CListValue,count); private: diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 8fd99c8d267..1bead0a7664 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -94,7 +94,7 @@ PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor * PyObjectPlus Methods -- Every class, even the abstract one should have a Methods ------------------------------*/ PyMethodDef PyObjectPlus::Methods[] = { - {"isA", (PyCFunction) sPy_isA, METH_VARARGS}, + {"isA", (PyCFunction) sPy_isA, METH_O}, {NULL, NULL} /* Sentinel */ }; @@ -106,24 +106,24 @@ PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL}; /*------------------------------ * PyObjectPlus attributes -- attributes ------------------------------*/ -PyObject *PyObjectPlus::_getattr(const STR_String& attr) +PyObject *PyObjectPlus::_getattr(const char *attr) { - if (attr == "__doc__" && GetType()->tp_doc) + if (!strcmp(attr, "__doc__") && GetType()->tp_doc) return PyString_FromString(GetType()->tp_doc); //if (streq(attr, "type")) // return Py_BuildValue("s", (*(GetParents()))->tp_name); - return Py_FindMethod(Methods, this, const_cast<char *>(attr.ReadPtr())); + return Py_FindMethod(Methods, this, attr); } -int PyObjectPlus::_delattr(const STR_String& attr) +int PyObjectPlus::_delattr(const char *attr) { PyErr_SetString(PyExc_AttributeError, "attribute cant be deleted"); return 1; } -int PyObjectPlus::_setattr(const STR_String& attr, PyObject *value) +int PyObjectPlus::_setattr(const char *attr, PyObject *value) { //return PyObject::_setattr(attr,value); //cerr << "Unknown attribute" << endl; @@ -131,12 +131,12 @@ int PyObjectPlus::_setattr(const STR_String& attr, PyObject *value) return 1; } -PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr) +PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *self, const char *attr) { const PyAttributeDef *attrdef; for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++) { - if (attr == attrdef->m_name) + if (!strcmp(attr, attrdef->m_name)) { if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY) { @@ -147,7 +147,7 @@ PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *sel if (attrdef->m_length > 1) { PyObject* resultlist = PyList_New(attrdef->m_length); - for (int i=0; i<attrdef->m_length; i++) + for (unsigned int i=0; i<attrdef->m_length; i++) { switch (attrdef->m_type) { case KX_PYATTRIBUTE_TYPE_BOOL: @@ -238,7 +238,7 @@ PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *sel return NULL; } -int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr, PyObject *value) +int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, const char *attr, PyObject *value) { const PyAttributeDef *attrdef; void *undoBuffer = NULL; @@ -247,7 +247,7 @@ int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, con for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++) { - if (attr == attrdef->m_name) + if (!strcmp(attr, attrdef->m_name)) { if (attrdef->m_access == KX_PYATTRIBUTE_RO || attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY) @@ -688,23 +688,54 @@ bool PyObjectPlus::isA(const char *mytypename) // check typename of each parent for (P = Ps[i=0]; P != NULL; P = Ps[i++]) { - if (STR_String(P->tp_name) == STR_String(mytypename) ) + if (strcmp(P->tp_name, mytypename)==0) return true; } return false; } -PyObject *PyObjectPlus::Py_isA(PyObject *args) // Python wrapper for isA +PyObject *PyObjectPlus::Py_isA(PyObject *value) // Python wrapper for isA { - char *mytypename; - if (!PyArg_ParseTuple(args, "s", &mytypename)) + if (!PyString_Check(value)) { + PyErr_SetString(PyExc_TypeError, "expected a string"); return NULL; - if(isA(mytypename)) + } + if(isA(PyString_AsString(value))) Py_RETURN_TRUE; else Py_RETURN_FALSE; } +/* Utility function called by the macro _getattr_up() + * for getting ob.__dict__() values from our PyObject + * this is used by python for doing dir() on an object, so its good + * if we return a list of attributes and methods. + * + * Other then making dir() useful the value returned from __dict__() is not useful + * since every value is a Py_None + * */ +PyObject *_getattr_dict(PyObject *pydict, PyMethodDef *meth, PyAttributeDef *attrdef) +{ + if(pydict==NULL) { /* incase calling __dict__ on the parent of this object raised an error */ + PyErr_Clear(); + pydict = PyDict_New(); + } + + if(meth) { + for (; meth->ml_name != NULL; meth++) { + PyDict_SetItemString(pydict, meth->ml_name, Py_None); + } + } + + if(attrdef) { + for (; attrdef->m_name != NULL; attrdef++) { + PyDict_SetItemString(pydict, attrdef->m_name, Py_None); + } + } + + return pydict; +} + #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index e0e2213d984..1a5f50a3d23 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -72,11 +72,8 @@ typedef int Py_ssize_t; #define PY_METHODCHAR const char * #endif - // some basic python macros -#define Py_Return { Py_INCREF(Py_None); return Py_None;} - static inline void Py_Fatal(const char *M) { - //cout << M << endl; + fprintf(stderr, "%s\n", M); exit(-1); }; @@ -92,35 +89,22 @@ static inline void Py_Fatal(const char *M) { virtual PyParentObject *GetParents(void) {return Parents;} + // This defines the _getattr_up macro // which allows attribute and method calls // to be properly passed up the hierarchy. #define _getattr_up(Parent) \ - PyObject *rvalue = NULL; \ - if (attr=="__methods__") { \ - PyObject *_attr_string = NULL; \ - PyMethodDef *meth = Methods; \ - rvalue = Parent::_getattr(attr); \ - if (rvalue==NULL) { \ - PyErr_Clear(); \ - rvalue = PyList_New(0); \ - } \ - if (meth) { \ - for (; meth->ml_name != NULL; meth++) { \ - _attr_string = PyString_FromString(meth->ml_name); \ - PyList_Append(rvalue, _attr_string); \ - Py_DECREF(_attr_string); \ - } \ + PyObject *rvalue = Py_FindMethod(Methods, this, attr); \ + \ + if (rvalue == NULL) { \ + PyErr_Clear(); \ + rvalue = Parent::_getattr(attr); \ } \ - } else { \ - rvalue = Py_FindMethod(Methods, this, const_cast<char*>(attr.ReadPtr())); \ - if (rvalue == NULL) { \ - PyErr_Clear(); \ - rvalue = Parent::_getattr(attr); \ - } \ - } \ - return rvalue; \ - + if ((rvalue == NULL) && !strcmp(attr, "__dict__")) {\ + PyErr_Clear(); \ + rvalue = _getattr_dict(Parent::_getattr(attr), Methods, Attributes); \ + } \ + return rvalue; \ /** * These macros are helpfull when embedding Python routines. The second @@ -283,10 +267,17 @@ typedef struct KX_PYATTRIBUTE_DEF { #define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, &((object *)0)->field, NULL, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, ((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \ + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} } +// SHORT_LIST +#define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \ + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } +#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \ + { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, &((object *)0)->field, NULL, NULL, NULL} } +#define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} } #define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \ @@ -296,10 +287,17 @@ typedef struct KX_PYATTRIBUTE_DEF { #define KX_PYATTRIBUTE_INT_RO(name,object,field) \ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, ((object *)0)->field, NULL, NULL} } #define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \ + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} } +// INT_LIST +#define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \ + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } +#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \ + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, &((object *)0)->field, NULL, NULL} } +#define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} } // always clamp for float @@ -310,11 +308,11 @@ typedef struct KX_PYATTRIBUTE_DEF { #define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} } #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} } #define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, {NULL, NULL, NULL, &((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, {NULL, NULL, NULL, ((object *)0)->field, NULL} } #define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \ - { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} } + { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} } #define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} } @@ -323,6 +321,10 @@ typedef struct KX_PYATTRIBUTE_DEF { #define KX_PYATTRIBUTE_STRING_RO(name,object,field) \ { name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} } +//Multiple integer +#define KX_PYATTRIBUTE_MINT_RW_CHECK(name,min,max,clamp,object,field,length,function) \ + { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, &((object *)0)->field, NULL, NULL} } + /*------------------------------ * PyObjectPlus ------------------------------*/ @@ -348,23 +350,23 @@ public: // Py_DECREF(this); // }; // decref method - virtual PyObject *_getattr(const STR_String& attr); // _getattr method + virtual PyObject *_getattr(const char *attr); // _getattr method static PyObject *__getattr(PyObject * PyObj, char *attr) // This should be the entry in Type. { - return ((PyObjectPlus*) PyObj)->_getattr(STR_String(attr)); + return ((PyObjectPlus*) PyObj)->_getattr(attr); } - static PyObject *_getattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr); - static int _setattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr, PyObject *value); + static PyObject *_getattr_self(const PyAttributeDef attrlist[], void *self, const char *attr); + static int _setattr_self(const PyAttributeDef attrlist[], void *self, const char *attr, PyObject *value); - virtual int _delattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); // _setattr method + virtual int _delattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); // _setattr method static int __setattr(PyObject *PyObj, // This should be the entry in Type. char *attr, PyObject *value) { if (!value) return ((PyObjectPlus*) PyObj)->_delattr(attr); - return ((PyObjectPlus*) PyObj)->_setattr(STR_String(attr), value); + return ((PyObjectPlus*) PyObj)->_setattr(attr, value); } virtual PyObject *_repr(void); // _repr method @@ -376,13 +378,15 @@ public: // isA methods bool isA(PyTypeObject *T); bool isA(const char *mytypename); - PyObject *Py_isA(PyObject *args); - static PyObject *sPy_isA(PyObject *self, PyObject *args, PyObject *kwd) + PyObject *Py_isA(PyObject *value); + static PyObject *sPy_isA(PyObject *self, PyObject *value) { - return ((PyObjectPlus*)self)->Py_isA(args); + return ((PyObjectPlus*)self)->Py_isA(value); } }; +PyObject *_getattr_dict(PyObject *pydict, PyMethodDef *meth, PyAttributeDef *attrdef); + #endif // _adr_py_lib_h_ #endif //NO_EXP_PYTHON_EMBEDDING diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index f391afec60b..25adcf3e895 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -6,4 +6,9 @@ sources = env.Glob('*.cpp') incs ='. #source/kernel/gen_system #intern/string #intern/moto/include' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [310,120] ) +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,120], cxx_compileflags=cxxflags) diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index f2b5569c76e..ebb12636ac2 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -52,6 +52,10 @@ PyObject* cvalue_div(PyObject*v, PyObject*w) { return ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w); } +PyObject* cvalue_mod(PyObject*v, PyObject*w) +{ + return ((CValue*)v)->Calc(VALUE_MOD_OPERATOR,(CValue*)w); +} PyObject* cvalue_neg(PyObject*v) { return ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v); @@ -112,7 +116,7 @@ static PyNumberMethods cvalue_as_number = { (binaryfunc)cvalue_sub, /*nb_subtract*/ (binaryfunc)cvalue_mul, /*nb_multiply*/ (binaryfunc)cvalue_div, /*nb_divide*/ - 0,//(binaryfunc)cvalue_remainder, /*nb_remainder*/ + (binaryfunc)cvalue_mod, /*nb_remainder*/ 0,//(binaryfunc)cvalue_divmod, /*nb_divmod*/ 0,//0,//0,//0,//(ternaryfunc)cvalue_pow, /*nb_power*/ (unaryfunc)cvalue_neg, /*nb_negative*/ @@ -257,6 +261,9 @@ STR_String CValue::op2str (VALUE_OPERATOR op) STR_String opmsg; switch (op) { + case VALUE_MOD_OPERATOR: + opmsg = " % "; + break; case VALUE_ADD_OPERATOR: opmsg = " + "; break; @@ -673,10 +680,14 @@ static PyMethodDef CValueMethods[] = { NULL,NULL} // Sentinel }; +PyAttributeDef CValue::Attributes[] = { + { NULL } //Sentinel +}; + -PyObject* CValue::_getattr(const STR_String& attr) +PyObject* CValue::_getattr(const char *attr) { - CValue* resultattr = FindIdentifier(attr); + CValue* resultattr = FindIdentifier(STR_String(attr)); STR_String text; if (resultattr) { @@ -761,26 +772,27 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj) } -int CValue::_delattr(const STR_String& attr) +int CValue::_delattr(const char *attr) { - if (!RemoveProperty(attr)) /* sets error */ + if (!RemoveProperty(STR_String(attr))) /* sets error */ return 1; return 0; } -int CValue::_setattr(const STR_String& attr,PyObject* pyobj) +int CValue::_setattr(const char *attr,PyObject* pyobj) { CValue* vallie = ConvertPythonToValue(pyobj); if (vallie) { - CValue* oldprop = GetProperty(attr); + STR_String attr_str = attr; + CValue* oldprop = GetProperty(attr_str); if (oldprop) { oldprop->SetValue(vallie); } else { - SetProperty(attr,vallie); + SetProperty(attr_str, vallie); } vallie->Release(); } else @@ -858,7 +870,42 @@ void CValue::SetDeprecationWarnings(bool ignoreDeprecationWarnings) void CValue::ShowDeprecationWarning(const char* old_way,const char* new_way) { - if (!m_ignore_deprecation_warnings) + if (!m_ignore_deprecation_warnings) { printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way); + + // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno) + + PyObject *getframe, *frame; + PyObject *f_lineno, *f_code, *co_filename; + + getframe = PySys_GetObject("_getframe"); // borrowed + if (getframe) { + frame = PyObject_CallObject(getframe, NULL); + if (frame) { + f_lineno= PyObject_GetAttrString(frame, "f_lineno"); + f_code= PyObject_GetAttrString(frame, "f_code"); + if (f_lineno && f_code) { + co_filename= PyObject_GetAttrString(f_code, "co_filename"); + if (co_filename) { + + printf("\t%s:%d\n", PyString_AsString(co_filename), (int)PyInt_AsLong(f_lineno)); + + Py_DECREF(f_lineno); + Py_DECREF(f_code); + Py_DECREF(co_filename); + Py_DECREF(frame); + return; + } + } + + Py_XDECREF(f_lineno); + Py_XDECREF(f_code); + Py_DECREF(frame); + } + + } + PyErr_Clear(); + printf("\tERROR - Could not access sys._getframe(0).f_lineno or sys._getframe().f_code.co_filename\n"); + } } diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 56a4991af27..caf1064dc32 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -75,6 +75,7 @@ enum VALUE_OPERATOR { + VALUE_MOD_OPERATOR, // % VALUE_ADD_OPERATOR, // + VALUE_SUB_OPERATOR, // - VALUE_MUL_OPERATOR, // * @@ -223,7 +224,7 @@ public: - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); void SpecialRelease() { @@ -250,8 +251,8 @@ public: virtual CValue* ConvertPythonToValue(PyObject* pyobj); - virtual int _delattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr,PyObject* value); + virtual int _delattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); virtual PyObject* ConvertKeysToPython( void ); diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index e8e29fb2769..c21e5db1410 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -42,14 +42,14 @@ SCA_Joystick::SCA_Joystick(short int index) m_axis21(0), m_prec(3200), m_buttonnum(-2), + m_axismax(-1), m_hatdir(-2), + m_buttonmax(-1), + m_hatmax(-1), m_isinit(0), m_istrig_axis(0), m_istrig_button(0), - m_istrig_hat(0), - m_axismax(-1), - m_buttonmax(-1), - m_hatmax(-1) + m_istrig_hat(0) { #ifndef DISABLE_SDL m_private = new PrivateData(); diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp index a70830193db..7bf051f2b5c 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp @@ -113,7 +113,10 @@ PyMethodDef SCA_2DFilterActuator::Methods[] = { {NULL,NULL} }; +PyAttributeDef SCA_2DFilterActuator::Attributes[] = { + { NULL } //Sentinel +}; -PyObject* SCA_2DFilterActuator::_getattr(const STR_String& attr) { +PyObject* SCA_2DFilterActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index 7ec07cf5b19..9da0500afff 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -38,7 +38,7 @@ public: virtual bool Update(); virtual CValue* GetReplica(); - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; #endif diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp index cfc2d25e0ae..b67ef7dabaf 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.cpp +++ b/source/gameengine/GameLogic/SCA_ANDController.cpp @@ -137,7 +137,11 @@ PyMethodDef SCA_ANDController::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_ANDController::_getattr(const STR_String& attr) { +PyAttributeDef SCA_ANDController::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* SCA_ANDController::_getattr(const char *attr) { _getattr_up(SCA_IController); } diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index 376f4a9a876..eba7e1b545a 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -48,7 +48,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index fae8d2ba5a7..7f8dbef7758 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -161,7 +161,7 @@ PyAttributeDef SCA_ActuatorSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_ActuatorSensor::_getattr(const STR_String& attr) { +PyObject* SCA_ActuatorSensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; @@ -180,7 +180,7 @@ int SCA_ActuatorSensor::CheckActuator(void *self, const PyAttributeDef*) return 1; } -int SCA_ActuatorSensor::_setattr(const STR_String& attr, PyObject *value) { +int SCA_ActuatorSensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) return ret; @@ -221,7 +221,7 @@ PyObject* SCA_ActuatorSensor::PySetActuator(PyObject* self, PyObject* args, PyOb } else { ; /* error: bad actuator name */ } - Py_Return; + Py_RETURN_NONE; } /* eof */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 3d64247461c..75ee08f42d6 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -61,8 +61,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); /* 3. setProperty */ KX_PYMETHOD_DOC(SCA_ActuatorSensor,SetActuator); diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index f9fbf2387c4..154f0ad8cef 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -135,7 +135,11 @@ PyMethodDef SCA_AlwaysSensor::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_AlwaysSensor::_getattr(const STR_String& attr) { +PyAttributeDef SCA_AlwaysSensor::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* SCA_AlwaysSensor::_getattr(const char *attr) { _getattr_up(SCA_ISensor); } diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 8bf2a8aa98e..ebe6ba80208 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -52,7 +52,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index 4c97ca98d72..31a620b939d 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -53,10 +53,10 @@ SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr, int duration, bool repeat, PyTypeObject* T) - : SCA_ISensor(gameobj,eventmgr, T), + : SCA_ISensor(gameobj,eventmgr, T), + m_repeat(repeat), m_delay(delay), - m_duration(duration), - m_repeat(repeat) + m_duration(duration) { Init(); } @@ -178,14 +178,14 @@ PyAttributeDef SCA_DelaySensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_DelaySensor::_getattr(const STR_String& attr) { +PyObject* SCA_DelaySensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; _getattr_up(SCA_ISensor); } -int SCA_DelaySensor::_setattr(const STR_String& attr, PyObject *value) { +int SCA_DelaySensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) return ret; @@ -211,7 +211,7 @@ PyObject* SCA_DelaySensor::PySetDelay(PyObject* self, PyObject* args, PyObject* return NULL; } m_delay = delay; - Py_Return; + Py_RETURN_NONE; } const char SCA_DelaySensor::SetDuration_doc[] = @@ -233,7 +233,7 @@ PyObject* SCA_DelaySensor::PySetDuration(PyObject* self, PyObject* args, PyObjec return NULL; } m_duration = duration; - Py_Return; + Py_RETURN_NONE; } const char SCA_DelaySensor::SetRepeat_doc[] = @@ -250,7 +250,7 @@ PyObject* SCA_DelaySensor::PySetRepeat(PyObject* self, PyObject* args, PyObject* return NULL; } m_repeat = (repeat != 0); - Py_Return; + Py_RETURN_NONE; } const char SCA_DelaySensor::GetDelay_doc[] = diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index ff3afe16542..491eee61da8 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -60,8 +60,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); /* setProperty */ KX_PYMETHOD_DOC(SCA_DelaySensor,SetDelay); diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index e9a543c9f31..8ed46beb7f3 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -49,7 +49,8 @@ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj, const STR_String& exprtext, PyTypeObject* T) :SCA_IController(gameobj,T), - m_exprText(exprtext) + m_exprText(exprtext), + m_exprCache(NULL) { } @@ -57,6 +58,8 @@ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj, SCA_ExpressionController::~SCA_ExpressionController() { + if (m_exprCache) + m_exprCache->Release(); } @@ -65,6 +68,7 @@ CValue* SCA_ExpressionController::GetReplica() { SCA_ExpressionController* replica = new SCA_ExpressionController(*this); replica->m_exprText = m_exprText; + replica->m_exprCache = NULL; // this will copy properties and so on... CValue::AddDataToReplica(replica); @@ -72,18 +76,32 @@ CValue* SCA_ExpressionController::GetReplica() } +// Forced deletion of precalculated expression to break reference loop +// Use this function when you know that you won't use the sensor anymore +void SCA_ExpressionController::Delete() +{ + if (m_exprCache) + { + m_exprCache->Release(); + m_exprCache = NULL; + } + Release(); +} + void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr) { bool expressionresult = false; - - CParser parser; - parser.SetContext(this->AddRef()); - CExpression* expr = parser.ProcessText(m_exprText); - if (expr) + if (!m_exprCache) + { + CParser parser; + parser.SetContext(this->AddRef()); + m_exprCache = parser.ProcessText(m_exprText); + } + if (m_exprCache) { - CValue* value = expr->Calculate(); + CValue* value = m_exprCache->Calculate(); if (value) { if (value->IsError()) @@ -97,7 +115,8 @@ void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr) value->Release(); } - expr->Release(); + //m_exprCache->Release(); + //m_exprCache = NULL; } /* diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index f1db45a19e0..79c26eea1e7 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -38,6 +38,7 @@ class SCA_ExpressionController : public SCA_IController { // Py_Header; STR_String m_exprText; + CExpression* m_exprCache; public: SCA_ExpressionController(SCA_IObject* gameobj, @@ -48,12 +49,17 @@ public: virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); virtual CValue* FindIdentifier(const STR_String& identifiername); + /** + * used to release the expression cache + * so that self references are removed before the controller itself is released + */ + virtual void Delete(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ -// virtual PyObject* _getattr(const STR_String& attr); +// virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp index eeca2d7b44c..309f3108418 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.cpp +++ b/source/gameengine/GameLogic/SCA_IActuator.cpp @@ -36,8 +36,8 @@ using namespace std; SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj, PyTypeObject* T) : - m_links(0), - SCA_ILogicBrick(gameobj,T) + SCA_ILogicBrick(gameobj,T), + m_links(0) { // nothing to do } diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 7ffb21b5490..51bd6454d92 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -36,9 +36,9 @@ class SCA_IActuator : public SCA_ILogicBrick { friend class SCA_LogicManager; protected: - std::vector<CValue*> m_events; int m_links; // number of active links to controllers // when 0, the actuator is automatically stopped + std::vector<CValue*> m_events; void RemoveAllEvents(); public: diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp index 0bd20117f31..f9c192cae5c 100644 --- a/source/gameengine/GameLogic/SCA_IController.cpp +++ b/source/gameengine/GameLogic/SCA_IController.cpp @@ -38,8 +38,8 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj, PyTypeObject* T) : - m_statemask(0), - SCA_ILogicBrick(gameobj,T) + SCA_ILogicBrick(gameobj,T), + m_statemask(0) { } diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp index 8286c0829a7..49d39f75814 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp @@ -278,7 +278,7 @@ int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef) } PyObject* -SCA_ILogicBrick::_getattr(const STR_String& attr) +SCA_ILogicBrick::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) @@ -286,7 +286,7 @@ SCA_ILogicBrick::_getattr(const STR_String& attr) _getattr_up(CValue); } -int SCA_ILogicBrick::_setattr(const STR_String& attr, PyObject *value) +int SCA_ILogicBrick::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) @@ -324,7 +324,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* self, m_Execute_Ueber_Priority = priority; - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index 772bd65d577..70d49941613 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -62,6 +62,7 @@ public: SCA_IObject* GetParent(); virtual void ReParent(SCA_IObject* parent); virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map); + virtual void Delete() { Release(); } // act as a BoolValue (with value IsPositiveTrigger) virtual CValue* Calc(VALUE_OPERATOR op, CValue *val); @@ -78,8 +79,8 @@ public: virtual bool LessComparedTo(SCA_ILogicBrick* other); - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); static class SCA_LogicManager* m_sCurrentLogicManager; diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index b0f8decee26..debd62d44e6 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -40,7 +40,7 @@ MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0); -SCA_IObject::SCA_IObject(PyTypeObject* T): m_initState(0), m_state(0), CValue(T) +SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0) { m_suspended = false; } @@ -59,7 +59,9 @@ SCA_IObject::~SCA_IObject() SCA_ControllerList::iterator itc; for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc) { - ((CValue*)(*itc))->Release(); + //Use Delete for controller to ensure proper cleaning (expression controller) + (*itc)->Delete(); + //((CValue*)(*itc))->Release(); } SCA_ActuatorList::iterator ita; for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita) @@ -407,9 +409,12 @@ PyMethodDef SCA_IObject::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef SCA_IObject::Attributes[] = { + { NULL } //Sentinel +}; -PyObject* SCA_IObject::_getattr(const STR_String& attr) { +PyObject* SCA_IObject::_getattr(const char *attr) { _getattr_up(CValue); } diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 38a7ed29dca..d47353b1ac0 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -145,7 +145,7 @@ public: // const class MT_Point3& ConvertPythonPylist(PyObject* pylist); // here come the python forwarded methods - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); virtual int GetGameObjectType() {return -1;} diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp index 68a3a93eab0..e8a072f4c46 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.cpp +++ b/source/gameengine/GameLogic/SCA_ISensor.cpp @@ -264,7 +264,7 @@ PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyOb int pyarg = 0; if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; } m_pos_pulsemode = PyArgToBool(pyarg); - Py_Return; + Py_RETURN_NONE; } /** @@ -303,7 +303,7 @@ PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject* }; m_pulse_frequency = pulse_frequencyArg; - Py_Return; + Py_RETURN_NONE; } @@ -326,7 +326,7 @@ PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwd int pyarg = 0; if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; } m_invert = PyArgToBool(pyarg); - Py_Return; + Py_RETURN_NONE; } const char SCA_ISensor::GetLevel_doc[] = @@ -352,7 +352,7 @@ PyObject* SCA_ISensor::PySetLevel(PyObject* self, PyObject* args, PyObject* kwds int pyarg = 0; if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; } m_level = PyArgToBool(pyarg); - Py_Return; + Py_RETURN_NONE; } const char SCA_ISensor::GetUseNegPulseMode_doc[] = @@ -375,7 +375,7 @@ PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyOb int pyarg = 0; if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; } m_neg_pulsemode = PyArgToBool(pyarg); - Py_Return; + Py_RETURN_NONE; } //<------Deprecated @@ -385,7 +385,7 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset, "\tThe sensor is put in its initial state as if it was just activated.\n") { Init(); - Py_Return; + Py_RETURN_NONE; } /* ----------------------------------------------- */ @@ -461,19 +461,19 @@ PyAttributeDef SCA_ISensor::Attributes[] = { }; PyObject* -SCA_ISensor::_getattr(const STR_String& attr) +SCA_ISensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; - if (attr == "triggered") + if (!strcmp(attr, "triggered")) { int retval = 0; if (SCA_PythonController::m_sCurrentController) retval = SCA_PythonController::m_sCurrentController->IsTriggered(this); return PyInt_FromLong(retval); } - if (attr == "positive") + if (!strcmp(attr, "positive")) { int retval = IsPositiveTrigger(); return PyInt_FromLong(retval); @@ -481,7 +481,7 @@ SCA_ISensor::_getattr(const STR_String& attr) _getattr_up(SCA_ILogicBrick); } -int SCA_ISensor::_setattr(const STR_String& attr, PyObject *value) +int SCA_ISensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 1b57c4621e4..23f2c76c19f 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -105,11 +105,6 @@ public: bool negmode, int freq); - /** Release sensor - * For property sensor, it is used to release the pre-calculated expression - * so that self references are removed before the sensor itself is released - */ - virtual void Delete() { Release(); } /** Set inversion of pulses on or off. */ void SetInvert(bool inv); /** set the level detection on or off */ @@ -141,8 +136,8 @@ public: /* Python functions: */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); //Deprecated functions -----> KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive); diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 694bca9bac5..c2d90c830cf 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -331,8 +331,8 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = { KX_PYATTRIBUTE_SHORT_RW("index",0,JOYINDEX_MAX-1,true,SCA_JoystickSensor,m_joyindex), KX_PYATTRIBUTE_INT_RW("threshold",0,32768,true,SCA_JoystickSensor,m_precision), KX_PYATTRIBUTE_INT_RW("button",0,100,false,SCA_JoystickSensor,m_button), - KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis), - KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat), + KX_PYATTRIBUTE_INT_LIST_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis), + KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat), // dummy attributes will just be read-only in _setattr // you still need to defined them in _getattr KX_PYATTRIBUTE_DUMMY("axisPosition"), @@ -343,24 +343,24 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) { +PyObject* SCA_JoystickSensor::_getattr(const char *attr) { SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); - if (attr == "axisPosition") { + if (!strcmp(attr, "axisPosition")) { if(joy) return Py_BuildValue("[iiii]", joy->GetAxis10(), joy->GetAxis11(), joy->GetAxis20(), joy->GetAxis21()); else return Py_BuildValue("[iiii]", 0, 0, 0, 0); } - if (attr == "numAxis") { + if (!strcmp(attr, "numAxis")) { return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 ); } - if (attr == "numButtons") { + if (!strcmp(attr, "numButtons")) { return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 ); } - if (attr == "numHats") { + if (!strcmp(attr, "numHats")) { return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 ); } - if (attr == "connected") { + if (!strcmp(attr, "connected")) { return PyBool_FromLong( joy ? joy->Connected() : 0 ); } PyObject* object = _getattr_self(Attributes, this, attr); @@ -369,7 +369,7 @@ PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) { _getattr_up(SCA_ISensor); } -int SCA_JoystickSensor::_setattr(const STR_String& attr, PyObject *value) +int SCA_JoystickSensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index fa11f1cc3d0..49d220c056d 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -121,8 +121,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); /* Joystick Index */ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetIndex); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index 981d165287b..324e5eae98a 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -577,7 +577,7 @@ PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject* /* anything. It's up to the user to provide a sensible number. */ m_hotkey = keyCode; - Py_Return; + Py_RETURN_NONE; } /** 3. GetHold1 : set the first bucky bit */ @@ -609,7 +609,7 @@ PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObjec /* anything. It's up to the user to provide a sensible number. */ m_qual = keyCode; - Py_Return; + Py_RETURN_NONE; } /** 5. GetHold2 : get the second bucky bit */ @@ -641,7 +641,7 @@ PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObjec /* anything. It's up to the user to provide a sensible number. */ m_qual2 = keyCode; - Py_Return; + Py_RETURN_NONE; } @@ -682,7 +682,7 @@ PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, P if (index>0) return resultlist; } - Py_Return; + Py_RETURN_NONE; } @@ -725,7 +725,7 @@ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice(); if (index > 0) return resultlist; } - Py_Return; + Py_RETURN_NONE; } //<---- Deprecated @@ -770,7 +770,7 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus, return PyInt_FromLong(inevent.m_status); } - Py_Return; + Py_RETURN_NONE; } /* ------------------------------------------------------------------------- */ @@ -831,7 +831,7 @@ PyAttributeDef SCA_KeyboardSensor::Attributes[] = { }; PyObject* -SCA_KeyboardSensor::_getattr(const STR_String& attr) +SCA_KeyboardSensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) @@ -839,7 +839,7 @@ SCA_KeyboardSensor::_getattr(const STR_String& attr) _getattr_up(SCA_ISensor); } -int SCA_KeyboardSensor::_setattr(const STR_String& attr, PyObject *value) +int SCA_KeyboardSensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 4efbe9366cc..bc2f86327a5 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -126,8 +126,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); //Deprecated functions -----> /** 1. GetKey : check which key this sensor looks at */ diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp index 09b46e6443e..57535b29f32 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp +++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp @@ -158,8 +158,8 @@ bool SCA_MouseSensor::Evaluate(CValue* event) case KX_MOUSESENSORMODE_WHEELUP: case KX_MOUSESENSORMODE_WHEELDOWN: { - const SCA_InputEvent& event = mousedev->GetEventValue(m_hotkey); - switch (event.m_status){ + const SCA_InputEvent& mevent = mousedev->GetEventValue(m_hotkey); + switch (mevent.m_status){ case SCA_InputEvent::KX_JUSTACTIVATED: m_val = 1; result = true; @@ -282,7 +282,7 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, int button = PyInt_AsLong(value); if ((button < SCA_IInputDevice::KX_LEFTMOUSE) - || (button > SCA_IInputDevice::KX_MIDDLEMOUSE)){ + || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){ PyErr_SetString(PyExc_ValueError, "invalid button specified!"); return NULL; } @@ -292,7 +292,7 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus, return PyInt_FromLong(event.m_status); } - Py_Return; + Py_RETURN_NONE; } /* ------------------------------------------------------------------------- */ @@ -337,11 +337,11 @@ PyMethodDef SCA_MouseSensor::Methods[] = { PyAttributeDef SCA_MouseSensor::Attributes[] = { KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkey), - KX_PYATTRIBUTE_SHORT_ARRAY_RO("position",SCA_MouseSensor,m_x,2), + KX_PYATTRIBUTE_SHORT_LIST_RO("position",SCA_MouseSensor,m_x,2), { NULL } //Sentinel }; -PyObject* SCA_MouseSensor::_getattr(const STR_String& attr) +PyObject* SCA_MouseSensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) @@ -349,7 +349,7 @@ PyObject* SCA_MouseSensor::_getattr(const STR_String& attr) _getattr_up(SCA_ISensor); } -int SCA_MouseSensor::_setattr(const STR_String& attr, PyObject *value) +int SCA_MouseSensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index 82af2ce9c04..30b43fe53cc 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -109,8 +109,8 @@ class SCA_MouseSensor : public SCA_ISensor /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); //Deprecated functions -----> /* read x-coordinate */ diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp index 5b869ee8298..18426d75582 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.cpp +++ b/source/gameengine/GameLogic/SCA_NANDController.cpp @@ -137,7 +137,11 @@ PyMethodDef SCA_NANDController::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_NANDController::_getattr(const STR_String& attr) { +PyAttributeDef SCA_NANDController::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* SCA_NANDController::_getattr(const char *attr) { _getattr_up(SCA_IController); } diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 1193ff64f07..d88504cfc0d 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -48,7 +48,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp index 2866dec0b74..1de6a641c3d 100644 --- a/source/gameengine/GameLogic/SCA_NORController.cpp +++ b/source/gameengine/GameLogic/SCA_NORController.cpp @@ -137,7 +137,11 @@ PyMethodDef SCA_NORController::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_NORController::_getattr(const STR_String& attr) { +PyAttributeDef SCA_NORController::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* SCA_NORController::_getattr(const char *attr) { _getattr_up(SCA_IController); } diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index aab59e3d46c..45b639f3f3f 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -48,7 +48,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp index 2d4eb31f241..61fbc889d90 100644 --- a/source/gameengine/GameLogic/SCA_ORController.cpp +++ b/source/gameengine/GameLogic/SCA_ORController.cpp @@ -129,7 +129,12 @@ PyMethodDef SCA_ORController::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_ORController::_getattr(const STR_String& attr) { +PyAttributeDef SCA_ORController::Attributes[] = { + { NULL } //Sentinel +}; + + +PyObject* SCA_ORController::_getattr(const char *attr) { _getattr_up(SCA_IController); } diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index beb69aa2af9..9a6e9e75022 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -49,7 +49,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; #endif //__KX_ORCONTROLLER diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index 566d3b63487..c9ace081bae 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -260,14 +260,14 @@ PyAttributeDef SCA_PropertyActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_PropertyActuator::_getattr(const STR_String& attr) { +PyObject* SCA_PropertyActuator::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; _getattr_up(SCA_IActuator); } -int SCA_PropertyActuator::_setattr(const STR_String& attr, PyObject *value) { +int SCA_PropertyActuator::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) return ret; @@ -298,7 +298,7 @@ PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, Py } prop->Release(); - Py_Return; + Py_RETURN_NONE; } /* 2. getProperty */ @@ -328,7 +328,7 @@ PyObject* SCA_PropertyActuator::PySetValue(PyObject* self, PyObject* args, PyObj if (valArg) m_exprtxt = valArg; - Py_Return; + Py_RETURN_NONE; } /* 4. getValue */ diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index cdfeee4c67d..444d9285796 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -85,8 +85,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); // python wrapped methods KX_PYMETHOD_DOC(SCA_PropertyActuator,SetProperty); diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp index a6f7a9cd82b..d683c8bb3e7 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp +++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp @@ -352,14 +352,14 @@ PyAttributeDef SCA_PropertySensor::Attributes[] = { }; -PyObject* SCA_PropertySensor::_getattr(const STR_String& attr) { +PyObject* SCA_PropertySensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; _getattr_up(SCA_ISensor); /* implicit return! */ } -int SCA_PropertySensor::_setattr(const STR_String& attr, PyObject *value) { +int SCA_PropertySensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) return ret; @@ -397,7 +397,7 @@ PyObject* SCA_PropertySensor::PySetType(PyObject* self, PyObject* args, PyObject m_checktype = typeArg; } - Py_Return; + Py_RETURN_NONE; } /* 3. getProperty */ @@ -434,7 +434,7 @@ PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyOb ; /* error: bad property name */ } prop->Release(); - Py_Return; + Py_RETURN_NONE; } /* 5. getValue */ @@ -470,7 +470,7 @@ PyObject* SCA_PropertySensor::PySetValue(PyObject* self, PyObject* args, PyObjec m_checkpropval = oldval; return NULL; } - Py_Return; + Py_RETURN_NONE; } /* eof */ diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index e625e84a36f..2594e3fca9d 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -70,6 +70,10 @@ public: KX_PROPSENSOR_TYPE checktype, PyTypeObject* T=&Type ); + /** + * For property sensor, it is used to release the pre-calculated expression + * so that self references are removed before the sensor itself is released + */ virtual void Delete(); virtual ~SCA_PropertySensor(); virtual CValue* GetReplica(); @@ -85,8 +89,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); /* 1. getType */ KX_PYMETHOD_DOC(SCA_PropertySensor,GetType); diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index e879481a444..c75e36acab2 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -157,8 +157,40 @@ static const char* sPyGetCurrentController__doc__; PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self) { - m_sCurrentController->AddRef(); - return m_sCurrentController; + return m_sCurrentController->AddRef(); +} + +SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) +{ + // for safety, todo: only allow for registered actuators (pointertable) + // we don't want to crash gameengine/blender by python scripts + std::vector<SCA_IActuator*> lacts = m_sCurrentController->GetLinkedActuators(); + std::vector<SCA_IActuator*>::iterator it; + + if (PyString_Check(value)) { + /* get the actuator from the name */ + char *name= PyString_AsString(value); + for(it = lacts.begin(); it!= lacts.end(); it++) { + if( name == (*it)->GetName() ) { + return *it; + } + } + } + else { + /* Expecting an actuator type */ + for(it = lacts.begin(); it!= lacts.end(); it++) { + if( static_cast<SCA_IActuator*>(value) == (*it) ) { + return *it; + } + } + } + + /* set the exception */ + PyObject *value_str = PyObject_Repr(value); /* new ref */ + PyErr_Format(PyExc_ValueError, "'%s' not in this controllers actuator list", PyString_AsString(value_str)); + Py_DECREF(value_str); + + return false; } #if 0 @@ -175,26 +207,14 @@ PyObject* SCA_PythonController::sPyAddActiveActuator( int activate; if (!PyArg_ParseTuple(args, "Oi", &ob1,&activate)) return NULL; - - // for safety, todo: only allow for registered actuators (pointertable) - // we don't want to crash gameengine/blender by python scripts - std::vector<SCA_IActuator*> lacts = m_sCurrentController->GetLinkedActuators(); - std::vector<SCA_IActuator*>::iterator it; - bool found = false; - CValue* act = (CValue*)ob1; - - for(it = lacts.begin(); it!= lacts.end(); it++) { - if( static_cast<SCA_IActuator*>(act) == (*it) ) { - found=true; - break; - } - } - if(found){ - CValue* boolval = new CBoolValue(activate!=0); - m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)act,boolval); - boolval->Release(); - } + SCA_IActuator* actu = LinkedActuatorFromPy(ob1); + if(actu==NULL) + return NULL; + + CValue* boolval = new CBoolValue(activate!=0); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval); + boolval->Release(); Py_RETURN_NONE; } @@ -229,18 +249,61 @@ PyParentObject SCA_PythonController::Parents[] = { NULL }; PyMethodDef SCA_PythonController::Methods[] = { + {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O}, + {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O}, + {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetActuators_doc}, {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator, METH_O, (PY_METHODCHAR)SCA_PythonController::GetActuator_doc}, {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetSensors_doc}, {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor, METH_O, (PY_METHODCHAR)SCA_PythonController::GetSensor_doc}, - {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O}, //Deprecated functions ------> + {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O}, {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS}, {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_NOARGS}, //<----- Deprecated {NULL,NULL} //Sentinel }; +PyAttributeDef SCA_PythonController::Attributes[] = { + { NULL } //Sentinel +}; + +bool SCA_PythonController::Compile() +{ + //printf("py script modified '%s'\n", m_scriptName.Ptr()); + + // if a script already exists, decref it before replace the pointer to a new script + if (m_bytecode) + { + Py_DECREF(m_bytecode); + m_bytecode=NULL; + } + // recompile the scripttext into bytecode + m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input); + m_bModified=false; + + if (m_bytecode) + { + + return true; + } + else { + // didn't compile, so instead of compile, complain + // something is wrong, tell the user what went wrong + printf("Python compile error from controller \"%s\": \n", GetName().Ptr()); + //PyRun_SimpleString(m_scriptText.Ptr()); + PyErr_Print(); + + /* Added in 2.48a, the last_traceback can reference Objects for example, increasing + * their user count. Not to mention holding references to wrapped data. + * This is especially bad when the PyObject for the wrapped data is free'd, after blender + * has alredy dealocated the pointer */ + PySys_SetObject( (char *)"last_traceback", Py_None); + PyErr_Clear(); /* just to be sure */ + + return false; + } +} void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) { @@ -249,33 +312,13 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) if (m_bModified) { - // if a script already exists, decref it before replace the pointer to a new script - if (m_bytecode) - { - Py_DECREF(m_bytecode); - m_bytecode=NULL; - } - // recompile the scripttext into bytecode - m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input); - if (!m_bytecode) - { - // didn't compile, so instead of compile, complain - // something is wrong, tell the user what went wrong - printf("Python compile error from controller \"%s\": \n", GetName().Ptr()); - //PyRun_SimpleString(m_scriptText.Ptr()); - PyErr_Print(); - - /* Added in 2.48a, the last_traceback can reference Objects for example, increasing - * their user count. Not to mention holding references to wrapped data. - * This is especially bad when the PyObject for the wrapped data is free'd, after blender - * has alredy dealocated the pointer */ - PySys_SetObject( "last_traceback", Py_None); - PyErr_Clear(); /* just to be sure */ - + if (Compile()==false) // sets m_bModified to false return; - } - m_bModified=false; } + if (!m_bytecode) { + return; + } + /* * This part here with excdict is a temporary patch @@ -313,7 +356,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) * their user count. Not to mention holding references to wrapped data. * This is especially bad when the PyObject for the wrapped data is free'd, after blender * has alredy dealocated the pointer */ - PySys_SetObject( "last_traceback", Py_None); + PySys_SetObject( (char *)"last_traceback", Py_None); PyErr_Clear(); /* just to be sure */ //PyRun_SimpleString(m_scriptText.Ptr()); @@ -329,30 +372,63 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) -PyObject* SCA_PythonController::_getattr(const STR_String& attr) +PyObject* SCA_PythonController::_getattr(const char *attr) { - if (attr == "script") { - return PyString_FromString(m_scriptText); - } - if (attr == "state") { + if (!strcmp(attr,"state")) { return PyInt_FromLong(m_statemask); } + if (!strcmp(attr,"script")) { + return PyString_FromString(m_scriptText); + } _getattr_up(SCA_IController); } -int SCA_PythonController::_setattr(const STR_String& attr, PyObject *value) +int SCA_PythonController::_setattr(const char *attr, PyObject *value) { - if (attr == "script") { - PyErr_SetString(PyExc_AttributeError, "script is read only, use setScript() to update the script"); + if (!strcmp(attr,"state")) { + PyErr_SetString(PyExc_AttributeError, "state is read only"); return 1; } - if (attr == "state") { - PyErr_SetString(PyExc_AttributeError, "state is read only"); + if (!strcmp(attr,"script")) { + char *scriptArg = PyString_AsString(value); + + if (scriptArg==NULL) { + PyErr_SetString(PyExc_TypeError, "expected a string (script name)"); + return -1; + } + + /* set scripttext sets m_bModified to true, + so next time the script is needed, a reparse into byte code is done */ + this->SetScriptText(scriptArg); + return 1; } return SCA_IController::_setattr(attr, value); } +PyObject* SCA_PythonController::PyActivate(PyObject* self, PyObject *value) +{ + SCA_IActuator* actu = LinkedActuatorFromPy(value); + if(actu==NULL) + return NULL; + + CValue* boolval = new CBoolValue(true); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval); + boolval->Release(); + Py_RETURN_NONE; +} + +PyObject* SCA_PythonController::PyDeActivate(PyObject* self, PyObject *value) +{ + SCA_IActuator* actu = LinkedActuatorFromPy(value); + if(actu==NULL) + return NULL; + + CValue* boolval = new CBoolValue(false); + m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval); + boolval->Release(); + Py_RETURN_NONE; +} PyObject* SCA_PythonController::PyGetActuators(PyObject* self) { @@ -410,8 +486,7 @@ SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value) for (unsigned int index=0;index<m_linkedactuators.size();index++) { SCA_IActuator* actua = m_linkedactuators[index]; - STR_String realname = actua->GetName(); - if (realname == scriptArg) + if (actua->GetName() == scriptArg) { return actua->AddRef(); } @@ -448,6 +523,9 @@ PyObject* SCA_PythonController::PyGetScript(PyObject* self) PyObject* SCA_PythonController::PySetScript(PyObject* self, PyObject* value) { char *scriptArg = PyString_AsString(value); + + ShowDeprecationWarning("setScript()", "the script property"); + if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "expected a string (script name)"); return NULL; diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 1918cc488d8..4ec18f32c23 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -70,15 +70,20 @@ class SCA_PythonController : public SCA_IController void AddTriggeredSensor(class SCA_ISensor* sensor) { m_triggeredSensors.push_back(sensor); } int IsTriggered(class SCA_ISensor* sensor); + bool Compile(); static const char* sPyGetCurrentController__doc__; static PyObject* sPyGetCurrentController(PyObject* self); static const char* sPyAddActiveActuator__doc__; static PyObject* sPyAddActiveActuator(PyObject* self, PyObject* args); - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + static SCA_IActuator* LinkedActuatorFromPy(PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); + + KX_PYMETHOD_O(SCA_PythonController,Activate); + KX_PYMETHOD_O(SCA_PythonController,DeActivate); KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetSensors); KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetActuators); KX_PYMETHOD_DOC_O(SCA_PythonController,GetSensor); diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index 840b95d559a..d6c73f21f37 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -369,22 +369,22 @@ PyAttributeDef SCA_RandomActuator::Attributes[] = { { NULL } //Sentinel }; -PyObject* SCA_RandomActuator::_getattr(const STR_String& attr) { +PyObject* SCA_RandomActuator::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; - if (attr == "seed") { + if (!strcmp(attr, "seed")) { return PyInt_FromLong(m_base->GetSeed()); } _getattr_up(SCA_IActuator); } -int SCA_RandomActuator::_setattr(const STR_String& attr, PyObject *value) +int SCA_RandomActuator::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) return ret; - if (attr == "seed") { + if (!strcmp(attr, "seed")) { if (PyInt_Check(value)) { int ival = PyInt_AsLong(value); m_base->SetSeed(ival); @@ -413,7 +413,7 @@ PyObject* SCA_RandomActuator::PySetSeed(PyObject* self, PyObject* args, PyObject m_base->SetSeed(seedArg); - Py_Return; + Py_RETURN_NONE; } /* 2. getSeed */ const char SCA_RandomActuator::GetSeed_doc[] = @@ -478,7 +478,7 @@ PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyOb } prop->Release(); - Py_Return; + Py_RETURN_NONE; } /* 10. getProperty */ const char SCA_RandomActuator::GetProperty_doc[] = @@ -506,7 +506,7 @@ PyObject* SCA_RandomActuator::PySetBoolConst(PyObject* self, m_distribution = KX_RANDOMACT_BOOL_CONST; m_parameter1 = (paraArg) ? 1.0 : 0.0; - Py_Return; + Py_RETURN_NONE; } /* 12. setBoolUniform, */ const char SCA_RandomActuator::SetBoolUniform_doc[] = @@ -518,7 +518,7 @@ PyObject* SCA_RandomActuator::PySetBoolUniform(PyObject* self, /* no args */ m_distribution = KX_RANDOMACT_BOOL_UNIFORM; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 13. setBoolBernouilli, */ const char SCA_RandomActuator::SetBoolBernouilli_doc[] = @@ -536,7 +536,7 @@ PyObject* SCA_RandomActuator::PySetBoolBernouilli(PyObject* self, m_distribution = KX_RANDOMACT_BOOL_BERNOUILLI; m_parameter1 = paraArg; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 14. setIntConst,*/ const char SCA_RandomActuator::SetIntConst_doc[] = @@ -554,7 +554,7 @@ PyObject* SCA_RandomActuator::PySetIntConst(PyObject* self, m_distribution = KX_RANDOMACT_INT_CONST; m_parameter1 = paraArg; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 15. setIntUniform,*/ const char SCA_RandomActuator::SetIntUniform_doc[] = @@ -575,7 +575,7 @@ PyObject* SCA_RandomActuator::PySetIntUniform(PyObject* self, m_parameter1 = paraArg1; m_parameter2 = paraArg2; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 16. setIntPoisson, */ const char SCA_RandomActuator::SetIntPoisson_doc[] = @@ -595,7 +595,7 @@ PyObject* SCA_RandomActuator::PySetIntPoisson(PyObject* self, m_distribution = KX_RANDOMACT_INT_POISSON; m_parameter1 = paraArg; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 17. setFloatConst,*/ const char SCA_RandomActuator::SetFloatConst_doc[] = @@ -613,7 +613,7 @@ PyObject* SCA_RandomActuator::PySetFloatConst(PyObject* self, m_distribution = KX_RANDOMACT_FLOAT_CONST; m_parameter1 = paraArg; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 18. setFloatUniform, */ const char SCA_RandomActuator::SetFloatUniform_doc[] = @@ -634,7 +634,7 @@ PyObject* SCA_RandomActuator::PySetFloatUniform(PyObject* self, m_parameter1 = paraArg1; m_parameter2 = paraArg2; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 19. setFloatNormal, */ const char SCA_RandomActuator::SetFloatNormal_doc[] = @@ -655,7 +655,7 @@ PyObject* SCA_RandomActuator::PySetFloatNormal(PyObject* self, m_parameter1 = paraArg1; m_parameter2 = paraArg2; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* 20. setFloatNegativeExponential, */ const char SCA_RandomActuator::SetFloatNegativeExponential_doc[] = @@ -674,7 +674,7 @@ PyObject* SCA_RandomActuator::PySetFloatNegativeExponential(PyObject* self, m_distribution = KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL; m_parameter1 = paraArg; enforceConstraints(); - Py_Return; + Py_RETURN_NONE; } /* eof */ diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index de8faaf9c72..0d404fa8a9f 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -96,8 +96,8 @@ class SCA_RandomActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); /* 1. setSeed */ KX_PYMETHOD_DOC(SCA_RandomActuator,SetSeed); diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 8fae0bbeaba..5354c120f52 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -165,22 +165,22 @@ PyAttributeDef SCA_RandomSensor::Attributes[] = { {NULL} //Sentinel }; -PyObject* SCA_RandomSensor::_getattr(const STR_String& attr) { +PyObject* SCA_RandomSensor::_getattr(const char *attr) { PyObject* object = _getattr_self(Attributes, this, attr); if (object != NULL) return object; - if (attr == "seed") { + if (!strcmp(attr,"seed")) { return PyInt_FromLong(m_basegenerator->GetSeed()); } _getattr_up(SCA_ISensor); } -int SCA_RandomSensor::_setattr(const STR_String& attr, PyObject *value) +int SCA_RandomSensor::_setattr(const char *attr, PyObject *value) { int ret = _setattr_self(Attributes, this, attr, value); if (ret >= 0) return ret; - if (attr == "seed") { + if (!strcmp(attr,"seed")) { if (PyInt_Check(value)) { int ival = PyInt_AsLong(value); m_basegenerator->SetSeed(ival); @@ -209,7 +209,7 @@ PyObject* SCA_RandomSensor::PySetSeed(PyObject* self, PyObject* args, PyObject* m_basegenerator->SetSeed(seedArg); - Py_Return; + Py_RETURN_NONE; } /* 2. getSeed */ diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 009efc32aac..d808db07536 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -60,8 +60,8 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); /* 1. setSeed */ KX_PYMETHOD_DOC(SCA_RandomSensor,SetSeed); diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp index 3ef7c07fe0a..b2734dd1b33 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.cpp +++ b/source/gameengine/GameLogic/SCA_XNORController.cpp @@ -141,7 +141,11 @@ PyMethodDef SCA_XNORController::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_XNORController::_getattr(const STR_String& attr) { +PyAttributeDef SCA_XNORController::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* SCA_XNORController::_getattr(const char *attr) { _getattr_up(SCA_IController); } diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index 4b1eaee95d8..a431a72c177 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -48,7 +48,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp index 6499c62f5f2..662ef523d56 100644 --- a/source/gameengine/GameLogic/SCA_XORController.cpp +++ b/source/gameengine/GameLogic/SCA_XORController.cpp @@ -141,7 +141,11 @@ PyMethodDef SCA_XORController::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* SCA_XORController::_getattr(const STR_String& attr) { +PyAttributeDef SCA_XORController::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* SCA_XORController::_getattr(const char *attr) { _getattr_up(SCA_IController); } diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index f50cd33c125..2fbc7866ecf 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -48,7 +48,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index 25cf73cd079..88e5f7e87cc 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -17,4 +17,9 @@ if env['WITH_BF_SDL']: else: defs += ' DISABLE_SDL' -env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[315, 100] ) +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[330, 100], cxx_compileflags=cxxflags ) diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 78d8eaf2aa3..c0d6248a3ca 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -85,7 +85,7 @@ void GPC_RenderTools::EndFrame(RAS_IRasterizer* rasty) * has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in * a scene. */ -void GPC_RenderTools::ProcessLighting(int layer, const MT_Transform& viewmat) +void GPC_RenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat) { if(m_lastlightlayer == layer) return; @@ -106,12 +106,12 @@ void GPC_RenderTools::ProcessLighting(int layer, const MT_Transform& viewmat) } if(enable) - EnableOpenGLLights(); + EnableOpenGLLights(rasty); else DisableOpenGLLights(); } -void GPC_RenderTools::EnableOpenGLLights() +void GPC_RenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty) { if(m_lastlighting == true) return; @@ -120,7 +120,8 @@ void GPC_RenderTools::EnableOpenGLLights() glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE); if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index 382956e73ea..2a1b66a3aa9 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -65,9 +65,9 @@ public: void EndFrame(RAS_IRasterizer* rasty); void BeginFrame(RAS_IRasterizer* rasty); - void EnableOpenGLLights(); + void EnableOpenGLLights(RAS_IRasterizer *rasty); void DisableOpenGLLights(); - void ProcessLighting(int layer, const MT_Transform& viewmat); + void ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat); /* @attention mode is ignored here */ void RenderText2D(RAS_TEXT_RENDER_MODE mode, diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 30f20a670d3..23ad413350b 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -39,15 +39,13 @@ incs = ['.', '#source/gameengine/Network', '#source/gameengine/SceneGraph', '#source/gameengine/Physics/common', - '#source/gameengine/Physics/Sumo', - '#source/gameengine/Physics/Sumo/Fuzzics/include', '#source/gameengine/Network/LoopBackNetwork', '#source/gameengine/GamePlayer/ghost', '#source/blender/misc', '#source/blender/blenloader', '#source/blender/gpu', '#extern/glew/include'] - + #This is all plugin stuff! #if sys.platform=='win32': # source_files += ['windows/GPW_Canvas.cpp', @@ -62,13 +60,18 @@ incs = ['.', # 'unix/GPU_System.cpp'] # gp_common_env.Append ( CPPPATH = ['unix']) +if env['WITH_BF_SOLID']: + incs.append('#source/gameengine/Physics/Sumo') + incs.append('#source/gameengine/Physics/Sumo/Fuzzics/include') + incs += Split(env['BF_SOLID_INC']) + incs += Split(env['BF_PYTHON_INC']) -incs += Split(env['BF_SOLID_INC']) incs += Split(env['BF_PNG_INC']) incs += Split(env['BF_ZLIB_INC']) -cflags=[] +cxxflags = [] if env['OURPLATFORM']=='win32-vc': - cflags = ['/GR'] + cxxflags.append ('/GR') + cxxflags.append ('/O2') -env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, compileflags=cflags) +env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, cxx_compileflags=cxxflags) diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index c09772c6196..d993694ab4a 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -163,33 +163,39 @@ void usage(const char* program) consoleoption = ""; #endif - printf("usage: %s [-w l t w h] %s[-g gamengineoptions] " + printf("usage: %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] " "[-s stereomode] filename.blend\n", program, consoleoption); - printf(" -h: Prints this command summary\n"); + printf(" -h: Prints this command summary\n\n"); printf(" -w: display in a window\n"); + printf(" --Optional parameters--\n"); + printf(" w = window width\n"); + printf(" h = window height\n\n"); printf(" l = window left coordinate\n"); printf(" t = window top coordinate\n"); - printf(" w = window width\n"); - printf(" h = window height\n"); + printf(" Note: If w or h is defined, both must be defined.\n"); + printf(" Also, if l or t is defined, all options must be used.\n\n"); printf(" -f: start game in full screen mode\n"); + printf(" --Optional parameters--\n"); printf(" fw = full screen mode pixel width\n"); - printf(" fh = full screen mode pixel height\n"); + printf(" fh = full screen mode pixel height\n\n"); printf(" fb = full screen mode bits per pixel\n"); printf(" ff = full screen mode frequency\n"); + printf(" Note: If fw or fh is defined, both must be defined.\n"); + printf(" Also, if fb is used, fw and fh must be used. ff requires all options.\n\n"); printf(" -s: start player in stereo\n"); printf(" stereomode: hwpageflip (Quad buffered shutter glasses)\n"); printf(" syncdoubling (Above Below)\n"); printf(" sidebyside (Left Right)\n"); printf(" anaglyph (Red-Blue glasses)\n"); printf(" vinterlace (Vertical interlace for autostereo display)\n"); - printf(" depending on the type of stereo you want\n"); + printf(" depending on the type of stereo you want\n\n"); #ifndef _WIN32 - printf(" -i: parent windows ID \n"); + printf(" -i: parent windows ID \n\n"); #endif #ifdef _WIN32 - printf(" -c: keep console window open\n"); + printf(" -c: keep console window open\n\n"); #endif - printf(" -d: turn debugging on\n"); + printf(" -d: turn debugging on\n\n"); printf(" -g: game engine options:\n\n"); printf(" Name Default Description\n"); printf(" ------------------------------------------------------------------------\n"); @@ -201,7 +207,7 @@ void usage(const char* program) printf(" blender_material 0 Enable material settings\n"); printf(" ignore_deprecation_warnings 0 Ignore deprecation warnings\n"); printf("\n"); - printf("example: %s -w 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program); + printf("example: %s -w 320 200 10 10 -g noaudio c:\\loadtest.blend\n", program); printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program); } @@ -241,7 +247,7 @@ static void get_filename(int argc, char **argv, char *filename) if (BLI_exists(gamefile)) BLI_strncpy(filename, gamefile, FILE_MAXDIR + FILE_MAXFILE); - delete gamefile; + delete [] gamefile; } #else @@ -430,54 +436,41 @@ int main(int argc, char** argv) G.f |= G_DEBUG; /* std output printf's */ MEM_set_memory_debug(); break; - - case 'p': - // Parse window position and size options - if (argv[i][2] == 0) { - i++; - if ((i + 4) < argc) - { - windowLeft = atoi(argv[i++]); - windowTop = atoi(argv[i++]); - windowWidth = atoi(argv[i++]); - windowHeight = atoi(argv[i++]); - windowParFound = true; - } - else - { - error = true; - printf("error: too few options for window argument.\n"); - } - } else { /* mac specific */ - - if (strncmp(argv[i], "-psn_", 5)==0) - i++; /* skip process serial number */ - } - break; + case 'f': i++; fullScreen = true; fullScreenParFound = true; - if ((i + 2) < argc && argv[i][0] != '-' && argv[i+1][0] != '-') + if ((i + 2) <= argc && argv[i][0] != '-' && argv[i+1][0] != '-') { fullScreenWidth = atoi(argv[i++]); fullScreenHeight = atoi(argv[i++]); - if ((i + 1) < argc && argv[i][0] != '-') + if ((i + 1) <= argc && argv[i][0] != '-') { fullScreenBpp = atoi(argv[i++]); - if ((i + 1) < argc && argv[i][0] != '-') + if ((i + 1) <= argc && argv[i][0] != '-') fullScreenFrequency = atoi(argv[i++]); } } break; case 'w': // Parse window position and size options + i++; + fullScreen = false; + windowParFound = true; + + if ((i + 2) <= argc && argv[i][0] != '-' && argv[i+1][0] != '-') { - fullScreen = false; - fullScreenParFound = true; - i++; + windowWidth = atoi(argv[i++]); + windowHeight = atoi(argv[i++]); + if ((i +2) <= argc && argv[i][0] != '-' && argv[i+1][0] != '-') + { + windowLeft = atoi(argv[i++]); + windowTop = atoi(argv[i++]); + } } break; + case 'h': usage(argv[0]); return 0; diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 7ad2fdd37a7..9b17ed3757b 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -34,8 +34,6 @@ incs = ['.', '#source/gameengine/Network', '#source/gameengine/SceneGraph', '#source/gameengine/Physics/common', - '#source/gameengine/Physics/Sumo', - '#source/gameengine/Physics/Sumo/Fuzzics/include', '#source/gameengine/Network/LoopBackNetwork', '#source/gameengine/GamePlayer/common', '#source/blender/misc', @@ -43,14 +41,19 @@ incs = ['.', '#source/blender/gpu', '#extern/glew/include'] +if env['WITH_BF_SOLID']: + incs.append(['#source/gameengine/Physics/Sumo', '#source/gameengine/Physics/Sumo/Fuzzics/include']) + incs += Split(env['BF_SOLID_INC']) + incs += Split(env['BF_PYTHON_INC']) -incs += Split(env['BF_SOLID_INC']) -cflags = [] + +cxxflags = [] if env['OURPLATFORM']=='win32-vc': - cflags = ['/GR'] + cxxflags.append ('/GR') + cxxflags.append ('/O2') defs = '' if env['WITH_BF_FFMPEG']: defs += ' WITH_FFMPEG' -env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = Split(defs), libtype='player',priority=5, compileflags=cflags) +env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = Split(defs), libtype='player',priority=5, cxx_compileflags=cxxflags) diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp index 80892764089..60cb288436a 100644 --- a/source/gameengine/Ketsji/BL_Shader.cpp +++ b/source/gameengine/Ketsji/BL_Shader.cpp @@ -18,7 +18,7 @@ #define spit(x) std::cout << x << std::endl; #define SORT_UNIFORMS 1 -#define UNIFORM_MAX_LEN sizeof(float)*16 +#define UNIFORM_MAX_LEN (int)sizeof(float)*16 #define MAX_LOG_LEN 262144 // bounds BL_Uniform::BL_Uniform(int data_size) @@ -108,7 +108,7 @@ void BL_Uniform::SetData(int location, int type,bool transpose) #endif } -const bool BL_Shader::Ok()const +bool BL_Shader::Ok()const { return (mShader !=0 && mOk && mUse); } @@ -729,7 +729,7 @@ void BL_Shader::SetUniform(int uniform, const int* val, int len) } -PyObject* BL_Shader::_getattr(const STR_String& attr) +PyObject* BL_Shader::_getattr(const char *attr) { _getattr_up(PyObjectPlus); } @@ -767,6 +767,9 @@ PyMethodDef BL_Shader::Methods[] = {NULL,NULL} //Sentinel }; +PyAttributeDef BL_Shader::Attributes[] = { + { NULL } //Sentinel +}; PyTypeObject BL_Shader::Type = { PyObject_HEAD_INIT(&PyType_Type) @@ -796,7 +799,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg if(mShader !=0 && mOk ) { // already set... - Py_Return; + Py_RETURN_NONE; } char *v,*f; int apply=0; @@ -807,12 +810,12 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg if( LinkProgram() ) { glUseProgramObjectARB( mShader ); mUse = apply!=0; - Py_Return; + Py_RETURN_NONE; } vertProg = 0; fragProg = 0; mUse = 0; - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -827,7 +830,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" ) mShader = 0; mOk = 0; mUse = 0; - Py_Return; + Py_RETURN_NONE; } KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" ) @@ -871,7 +874,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()") MEM_freeN(logInf); logInf=0; } - Py_Return; + Py_RETURN_NONE; } @@ -912,7 +915,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass ) return NULL; mPass = 1; - Py_Return; + Py_RETURN_NONE; } /// access functions @@ -935,7 +938,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" ) SetUniform( loc, (float)value ); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -959,7 +962,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)") SetUniform(loc, array, 2); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -983,7 +986,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ") SetUniform(loc, array, 3); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; @@ -1008,7 +1011,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) " SetUniform(loc, array, 4); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -1032,7 +1035,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" ) SetUniform(loc, (int)value); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -1056,7 +1059,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)") SetUniform(loc, array, 2); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -1081,7 +1084,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ") SetUniform(loc, array, 3); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -1104,7 +1107,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) " SetUniform(loc, array, 4); #endif } - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -1144,7 +1147,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis #else SetUniform(loc, array2, 2); #endif - Py_Return; + Py_RETURN_NONE; } break; case 3: { @@ -1154,7 +1157,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis #else SetUniform(loc, array3, 3); #endif - Py_Return; + Py_RETURN_NONE; }break; case 4: { @@ -1164,7 +1167,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis #else SetUniform(loc, array4, 4); #endif - Py_Return; + Py_RETURN_NONE; }break; default: { @@ -1212,7 +1215,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 #else SetUniform(loc, array2, 2); #endif - Py_Return; + Py_RETURN_NONE; } break; case 3: { @@ -1223,7 +1226,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 #else SetUniform(loc, array3, 3); #endif - Py_Return; + Py_RETURN_NONE; }break; case 4: { @@ -1234,7 +1237,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3 #else SetUniform(loc, array4, 4); #endif - Py_Return; + Py_RETURN_NONE; }break; default: { @@ -1282,7 +1285,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4, #else SetUniform(loc,mat,(transp!=0)); #endif - Py_Return; + Py_RETURN_NONE; } } } @@ -1323,7 +1326,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3, #else SetUniform(loc,mat,(transp!=0)); #endif - Py_Return; + Py_RETURN_NONE; } } @@ -1346,7 +1349,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" ) mAttr=SHD_TANGENT; glUseProgramObjectARB(mShader); glBindAttribLocationARB(mShader, mAttr, "Tangent"); - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -1376,7 +1379,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" ) } if(defined) { - Py_Return; + Py_RETURN_NONE; } BL_DefUniform *uni = new BL_DefUniform(); @@ -1384,7 +1387,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" ) uni->mType = nloc; uni->mFlag = 0; mPreDef.push_back(uni); - Py_Return; + Py_RETURN_NONE; } } return NULL; diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 18ca8f8b4f8..76acd5513ef 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -166,7 +166,7 @@ public: //const BL_Sampler* GetSampler(int i); void SetSampler(int loc, int unit); - const bool Ok()const; + bool Ok()const; unsigned int GetProg(); void SetProg(bool enable); int GetAttribute(){return mAttr;}; @@ -202,7 +202,7 @@ public: void SetUniform(int uniform, const int val); // Python interface - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); // ----------------------------------- KX_PYMETHOD_DOC( BL_Shader, setSource ); diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index f0ef84032f7..5d40ba7d75c 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -609,7 +609,7 @@ int BL_Texture::GetPow2(int n) void BL_Texture::SplitEnvMap(EnvMap *map) { - if (!map || !map->ima || map->ima && !map->ima->ok) return; + if (!map || !map->ima || (map->ima && !map->ima->ok)) return; ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL); if (ibuf) my_envmap_split_ima(map, ibuf); diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp index 85921ae75ca..4e5f27df2da 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp @@ -143,7 +143,11 @@ PyMethodDef KX_NetworkMessageActuator::Methods[] = { {NULL,NULL} // Sentinel }; -PyObject* KX_NetworkMessageActuator::_getattr(const STR_String& attr) { +PyAttributeDef KX_NetworkMessageActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_NetworkMessageActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -162,7 +166,7 @@ PyObject* KX_NetworkMessageActuator::PySetToPropName( return NULL; } - Py_Return; + Py_RETURN_NONE; } // 2. SetSubject @@ -180,7 +184,7 @@ PyObject* KX_NetworkMessageActuator::PySetSubject( return NULL; } - Py_Return; + Py_RETURN_NONE; } // 3. SetBodyType @@ -198,7 +202,7 @@ PyObject* KX_NetworkMessageActuator::PySetBodyType( return NULL; } - Py_Return; + Py_RETURN_NONE; } // 4. SetBody @@ -216,6 +220,6 @@ PyObject* KX_NetworkMessageActuator::PySetBody( return NULL; } - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index 653107699c7..96b55ef839b 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -61,7 +61,7 @@ public: /* Python interface ------------------------------------------- */ /* ------------------------------------------------------------ */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName); KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject); diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index 8956df9c96b..ac89d8b0716 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -213,7 +213,11 @@ PyMethodDef KX_NetworkMessageSensor::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* KX_NetworkMessageSensor::_getattr(const STR_String& attr) { +PyAttributeDef KX_NetworkMessageSensor::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_NetworkMessageSensor::_getattr(const char *attr) { _getattr_up(SCA_ISensor); // implicit return! } diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 8cdfd6cdb5a..26adbc9945a 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -72,7 +72,7 @@ public: /* Python interface -------------------------------------------- */ /* ------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD_DOC_O(KX_NetworkMessageSensor, SetSubjectFilterText); KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetFrameMessageCount); diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 93b65757ac5..b417edf6413 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -9,4 +9,10 @@ incs += ' #source/gameengine/Network' incs += ' ' + env['BF_PYTHON_INC'] -env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145] ) +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + + +env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145], cxx_compileflags=cxxflags ) diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index f92200780d5..b9bd7647f89 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -748,6 +748,9 @@ PyMethodDef KX_BlenderMaterial::Methods[] = {NULL,NULL} //Sentinel }; +PyAttributeDef KX_BlenderMaterial::Attributes[] = { + { NULL } //Sentinel +}; PyTypeObject KX_BlenderMaterial::Type = { PyObject_HEAD_INIT(&PyType_Type) @@ -772,12 +775,12 @@ PyParentObject KX_BlenderMaterial::Parents[] = { }; -PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr) +PyObject* KX_BlenderMaterial::_getattr(const char *attr) { _getattr_up(PyObjectPlus); } -int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue) +int KX_BlenderMaterial::_setattr(const char *attr, PyObject *pyvalue) { return PyObjectPlus::_setattr(attr, pyvalue); } @@ -790,7 +793,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") spit("Fragment shaders not supported"); mModified = true; - Py_Return; + Py_RETURN_NONE; } if( !GLEW_ARB_vertex_shader) { @@ -798,14 +801,14 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") spit("Vertex shaders not supported"); mModified = true; - Py_Return; + Py_RETURN_NONE; } if(!GLEW_ARB_shader_objects) { if(!mModified) spit("GLSL not supported"); mModified = true; - Py_Return; + Py_RETURN_NONE; } else { // returns Py_None on error @@ -838,7 +841,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") } } } - Py_Return; + Py_RETURN_NONE; } PyErr_Format(PyExc_ValueError, "GLSL Error"); return NULL; @@ -910,7 +913,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.sr return NULL; } mUserDefBlend = true; - Py_Return; + Py_RETURN_NONE; } return NULL; } diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 6e5db1b56c1..2cf623dbd85 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -82,8 +82,8 @@ public: ); // -------------------------------- - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *pyvalue); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *pyvalue); KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader ); KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex ); diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index 534c48661b7..062e9f7df50 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -384,10 +384,10 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) childit!= destnode->GetSGChildren().end(); ++childit ) { - KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); - if (clientgameobj) + KX_GameObject *clientgameobj_child = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); + if (clientgameobj_child) { - parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController(); + parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj_child->GetPhysicsController(); parentctrl = parentKxCtrl; ccdParent = parentKxCtrl; } diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp index a5d7f6d799a..ef7883910fd 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.cpp +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -197,9 +197,11 @@ PyMethodDef KX_CDActuator::Methods[] = { {NULL,NULL,NULL,NULL} //Sentinel }; +PyAttributeDef KX_CDActuator::Attributes[] = { + { NULL } //Sentinel +}; - -PyObject* KX_CDActuator::_getattr(const STR_String& attr) +PyObject* KX_CDActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -210,7 +212,7 @@ PyObject* KX_CDActuator::_getattr(const STR_String& attr) PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwds) { SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); - Py_Return; + Py_RETURN_NONE; } @@ -218,7 +220,7 @@ PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwd PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwds) { SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE); - Py_Return; + Py_RETURN_NONE; } @@ -226,7 +228,7 @@ PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwd PyObject* KX_CDActuator::PyStopCD(PyObject* self, PyObject* args, PyObject* kwds) { SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP); - Py_Return; + Py_RETURN_NONE; } @@ -239,7 +241,7 @@ PyObject* KX_CDActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwd SND_CDObject::Instance()->SetGain(gain); - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h index f46dd99b6dc..393c49083f9 100644 --- a/source/gameengine/Ketsji/KX_CDActuator.h +++ b/source/gameengine/Ketsji/KX_CDActuator.h @@ -81,7 +81,7 @@ public: /* Python interface --------------------------------------------------- */ /* -------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD(KX_CDActuator,StartCD); KX_PYMETHOD(KX_CDActuator,PauseCD); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index fb91c793765..5caac2fc670 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -470,19 +470,23 @@ int KX_Camera::GetViewportTop() const PyMethodDef KX_Camera::Methods[] = { KX_PYMETHODTABLE(KX_Camera, sphereInsideFrustum), - KX_PYMETHODTABLE(KX_Camera, boxInsideFrustum), - KX_PYMETHODTABLE(KX_Camera, pointInsideFrustum), - KX_PYMETHODTABLE(KX_Camera, getCameraToWorld), - KX_PYMETHODTABLE(KX_Camera, getWorldToCamera), - KX_PYMETHODTABLE(KX_Camera, getProjectionMatrix), - KX_PYMETHODTABLE(KX_Camera, setProjectionMatrix), - KX_PYMETHODTABLE(KX_Camera, enableViewport), + KX_PYMETHODTABLE_O(KX_Camera, boxInsideFrustum), + KX_PYMETHODTABLE_O(KX_Camera, pointInsideFrustum), + KX_PYMETHODTABLE_NOARGS(KX_Camera, getCameraToWorld), + KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera), + KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix), + KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix), + KX_PYMETHODTABLE_O(KX_Camera, enableViewport), KX_PYMETHODTABLE(KX_Camera, setViewport), - KX_PYMETHODTABLE(KX_Camera, setOnTop), + KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop), {NULL,NULL} //Sentinel }; +PyAttributeDef KX_Camera::Attributes[] = { + { NULL } //Sentinel +}; + char KX_Camera::doc[] = "Module KX_Camera\n\n" "Constants:\n" "\tINSIDE\n" @@ -538,48 +542,48 @@ PyParentObject KX_Camera::Parents[] = { NULL }; -PyObject* KX_Camera::_getattr(const STR_String& attr) +PyObject* KX_Camera::_getattr(const char *attr) { - if (attr == "INSIDE") + if (!strcmp(attr, "INSIDE")) return PyInt_FromLong(INSIDE); /* new ref */ - if (attr == "OUTSIDE") + if (!strcmp(attr, "OUTSIDE")) return PyInt_FromLong(OUTSIDE); /* new ref */ - if (attr == "INTERSECT") + if (!strcmp(attr, "INTERSECT")) return PyInt_FromLong(INTERSECT); /* new ref */ - if (attr == "lens") + if (!strcmp(attr, "lens")) return PyFloat_FromDouble(GetLens()); /* new ref */ - if (attr == "near") + if (!strcmp(attr, "near")) return PyFloat_FromDouble(GetCameraNear()); /* new ref */ - if (attr == "far") + if (!strcmp(attr, "far")) return PyFloat_FromDouble(GetCameraFar()); /* new ref */ - if (attr == "frustum_culling") + if (!strcmp(attr, "frustum_culling")) return PyInt_FromLong(m_frustum_culling); /* new ref */ - if (attr == "perspective") + if (!strcmp(attr, "perspective")) return PyInt_FromLong(m_camdata.m_perspective); /* new ref */ - if (attr == "projection_matrix") + if (!strcmp(attr, "projection_matrix")) return PyObjectFrom(GetProjectionMatrix()); /* new ref */ - if (attr == "modelview_matrix") + if (!strcmp(attr, "modelview_matrix")) return PyObjectFrom(GetModelviewMatrix()); /* new ref */ - if (attr == "camera_to_world") + if (!strcmp(attr, "camera_to_world")) return PyObjectFrom(GetCameraToWorld()); /* new ref */ - if (attr == "world_to_camera") + if (!strcmp(attr, "world_to_camera")) return PyObjectFrom(GetWorldToCamera()); /* new ref */ _getattr_up(KX_GameObject); } -int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue) +int KX_Camera::_setattr(const char *attr, PyObject *pyvalue) { if (PyInt_Check(pyvalue)) { - if (attr == "frustum_culling") + if (!strcmp(attr, "frustum_culling")) { m_frustum_culling = PyInt_AsLong(pyvalue); return 0; } - if (attr == "perspective") + if (!strcmp(attr, "perspective")) { m_camdata.m_perspective = PyInt_AsLong(pyvalue); return 0; @@ -588,19 +592,19 @@ int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue) if (PyFloat_Check(pyvalue)) { - if (attr == "lens") + if (!strcmp(attr, "lens")) { m_camdata.m_lens = PyFloat_AsDouble(pyvalue); m_set_projection_matrix = false; return 0; } - if (attr == "near") + if (!strcmp(attr, "near")) { m_camdata.m_clipstart = PyFloat_AsDouble(pyvalue); m_set_projection_matrix = false; return 0; } - if (attr == "far") + if (!strcmp(attr, "far")) { m_camdata.m_clipend = PyFloat_AsDouble(pyvalue); m_set_projection_matrix = false; @@ -610,7 +614,7 @@ int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue) if (PyObject_IsMT_Matrix(pyvalue, 4)) { - if (attr == "projection_matrix") + if (!strcmp(attr, "projection_matrix")) { MT_Matrix4x4 mat; if (PyMatTo(pyvalue, mat)) @@ -624,7 +628,7 @@ int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue) return KX_GameObject::_setattr(attr, pyvalue); } -KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum, +KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum, "sphereInsideFrustum(center, radius) -> Integer\n" "\treturns INSIDE, OUTSIDE or INTERSECT if the given sphere is\n" "\tinside/outside/intersects this camera's viewing frustum.\n\n" @@ -658,7 +662,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum, return NULL; } -KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum, +KX_PYMETHODDEF_DOC_O(KX_Camera, boxInsideFrustum, "boxInsideFrustum(box) -> Integer\n" "\treturns INSIDE, OUTSIDE or INTERSECT if the given box is\n" "\tinside/outside/intersects this camera's viewing frustum.\n\n" @@ -683,34 +687,27 @@ KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum, "\t\t# Box is outside the frustum !\n" ) { - PyObject *pybox; - if (PyArg_ParseTuple(args, "O", &pybox)) + unsigned int num_points = PySequence_Size(value); + if (num_points != 8) { - unsigned int num_points = PySequence_Size(pybox); - if (num_points != 8) - { - PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points); + PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points); + return NULL; + } + + MT_Point3 box[8]; + for (unsigned int p = 0; p < 8 ; p++) + { + PyObject *item = PySequence_GetItem(value, p); /* new ref */ + bool error = !PyVecTo(item, box[p]); + Py_DECREF(item); + if (error) return NULL; - } - - MT_Point3 box[8]; - for (unsigned int p = 0; p < 8 ; p++) - { - PyObject *item = PySequence_GetItem(pybox, p); /* new ref */ - bool error = !PyVecTo(item, box[p]); - Py_DECREF(item); - if (error) - return NULL; - } - - return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */ } - PyErr_SetString(PyExc_TypeError, "boxInsideFrustum: Expected argument: list of points."); - return NULL; + return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */ } -KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum, +KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum, "pointInsideFrustum(point) -> Bool\n" "\treturns 1 if the given point is inside this camera's viewing frustum.\n\n" "\tpoint = The point to test (in world coordinates.)\n\n" @@ -727,7 +724,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum, ) { MT_Point3 point; - if (PyVecArgTo(args, point)) + if (PyVecTo(value, point)) { return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */ } @@ -736,7 +733,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum, return NULL; } -KX_PYMETHODDEF_DOC(KX_Camera, getCameraToWorld, +KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getCameraToWorld, "getCameraToWorld() -> Matrix4x4\n" "\treturns the camera to world transformation matrix, as a list of four lists of four values.\n\n" "\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n" @@ -745,7 +742,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, getCameraToWorld, return PyObjectFrom(GetCameraToWorld()); /* new ref */ } -KX_PYMETHODDEF_DOC(KX_Camera, getWorldToCamera, +KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getWorldToCamera, "getWorldToCamera() -> Matrix4x4\n" "\treturns the world to camera transformation matrix, as a list of four lists of four values.\n\n" "\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n" @@ -754,7 +751,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, getWorldToCamera, return PyObjectFrom(GetWorldToCamera()); /* new ref */ } -KX_PYMETHODDEF_DOC(KX_Camera, getProjectionMatrix, +KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getProjectionMatrix, "getProjectionMatrix() -> Matrix4x4\n" "\treturns this camera's projection matrix, as a list of four lists of four values.\n\n" "\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n" @@ -763,7 +760,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, getProjectionMatrix, return PyObjectFrom(GetProjectionMatrix()); /* new ref */ } -KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix, +KX_PYMETHODDEF_DOC_O(KX_Camera, setProjectionMatrix, "setProjectionMatrix(MT_Matrix4x4 m) -> None\n" "\tSets this camera's projection matrix\n" "\n" @@ -805,56 +802,50 @@ KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix, "\tcam = co.getOwner()\n" "\tcam.setProjectionMatrix(Perspective(-1.0, 1.0, -1.0, 1.0, 0.1, 1))\n") { - PyObject *pymat; - if (PyArg_ParseTuple(args, "O", &pymat)) + MT_Matrix4x4 mat; + if (!PyMatTo(value, mat)) { - MT_Matrix4x4 mat; - if (PyMatTo(pymat, mat)) - { - SetProjectionMatrix(mat); - Py_Return; - } + PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument."); + return NULL; } - - PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument."); - return NULL; + + SetProjectionMatrix(mat); + Py_RETURN_NONE; } -KX_PYMETHODDEF_DOC(KX_Camera, enableViewport, +KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport, "enableViewport(viewport)\n" "Sets this camera's viewport status\n" ) { - int viewport; - if (PyArg_ParseTuple(args,"i",&viewport)) - { - if(viewport) - EnableViewport(true); - else - EnableViewport(false); - } - else { + int viewport = PyObject_IsTrue(value); + + if (viewport == -1) { + PyErr_SetString(PyExc_ValueError, "expected True/False or 0/1"); return NULL; } - Py_Return; + if(viewport) + EnableViewport(true); + else + EnableViewport(false); + + Py_RETURN_NONE; } -KX_PYMETHODDEF_DOC(KX_Camera, setViewport, +KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, setViewport, "setViewport(left, bottom, right, top)\n" "Sets this camera's viewport\n") { int left, bottom, right, top; - if (PyArg_ParseTuple(args,"iiii",&left, &bottom, &right, &top)) - { - SetViewport(left, bottom, right, top); - } else { + if (!PyArg_ParseTuple(args,"iiii:setViewport",&left, &bottom, &right, &top)) return NULL; - } - Py_Return; + + SetViewport(left, bottom, right, top); + Py_RETURN_NONE; } -KX_PYMETHODDEF_DOC(KX_Camera, setOnTop, +KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, setOnTop, "setOnTop()\n" "Sets this camera's viewport on top\n") { @@ -863,5 +854,5 @@ KX_PYMETHODDEF_DOC(KX_Camera, setOnTop, scene = KX_GetActiveScene(); MT_assert(scene); scene->SetCameraOnTop(this); - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 75d574cd697..efd18f99390 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -126,7 +126,7 @@ protected: void ExtractFrustumSphere(); public: - typedef enum { INSIDE, INTERSECT, OUTSIDE } ; + enum { INSIDE, INTERSECT, OUTSIDE } ; KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, PyTypeObject *T = &Type); virtual ~KX_Camera(); @@ -257,21 +257,21 @@ public: int GetViewportTop() const; - KX_PYMETHOD_DOC(KX_Camera, sphereInsideFrustum); - KX_PYMETHOD_DOC(KX_Camera, boxInsideFrustum); - KX_PYMETHOD_DOC(KX_Camera, pointInsideFrustum); + KX_PYMETHOD_DOC_VARARGS(KX_Camera, sphereInsideFrustum); + KX_PYMETHOD_DOC_O(KX_Camera, boxInsideFrustum); + KX_PYMETHOD_DOC_O(KX_Camera, pointInsideFrustum); - KX_PYMETHOD_DOC(KX_Camera, getCameraToWorld); - KX_PYMETHOD_DOC(KX_Camera, getWorldToCamera); - KX_PYMETHOD_DOC(KX_Camera, getProjectionMatrix); - KX_PYMETHOD_DOC(KX_Camera, setProjectionMatrix); + KX_PYMETHOD_DOC_NOARGS(KX_Camera, getCameraToWorld); + KX_PYMETHOD_DOC_NOARGS(KX_Camera, getWorldToCamera); + KX_PYMETHOD_DOC_NOARGS(KX_Camera, getProjectionMatrix); + KX_PYMETHOD_DOC_O(KX_Camera, setProjectionMatrix); - KX_PYMETHOD_DOC(KX_Camera, enableViewport); - KX_PYMETHOD_DOC(KX_Camera, setViewport); - KX_PYMETHOD_DOC(KX_Camera, setOnTop); + KX_PYMETHOD_DOC_O(KX_Camera, enableViewport); + KX_PYMETHOD_DOC_VARARGS(KX_Camera, setViewport); + KX_PYMETHOD_DOC_NOARGS(KX_Camera, setOnTop); - virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */ - virtual int _setattr(const STR_String& attr, PyObject *pyvalue); + virtual PyObject* _getattr(const char *attr); /* lens, near, far, projection_matrix */ + virtual int _setattr(const char *attr, PyObject *pyvalue); }; diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 4d24e83843e..30ecc5ad441 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -33,6 +33,7 @@ #include "KX_CameraActuator.h" #include <iostream> #include <math.h> +#include <float.h> #include "KX_GameObject.h" #include "PyObjectPlus.h" @@ -52,9 +53,9 @@ STR_String KX_CameraActuator::Y_AXIS_STRING = "y"; KX_CameraActuator::KX_CameraActuator( SCA_IObject* gameobj, SCA_IObject *obj, - MT_Scalar hght, - MT_Scalar minhght, - MT_Scalar maxhght, + float hght, + float minhght, + float maxhght, bool xytog, PyTypeObject* T ): @@ -397,6 +398,7 @@ PyParentObject KX_CameraActuator::Parents[] = { }; PyMethodDef KX_CameraActuator::Methods[] = { + // ---> deprecated (all) {"setObject",(PyCFunction) KX_CameraActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, {"getObject",(PyCFunction) KX_CameraActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, {"setMin" ,(PyCFunction) KX_CameraActuator::sPySetMin, METH_VARARGS, (PY_METHODCHAR)SetMin_doc}, @@ -410,9 +412,54 @@ PyMethodDef KX_CameraActuator::Methods[] = { {NULL,NULL,NULL,NULL} //Sentinel }; -PyObject* KX_CameraActuator::_getattr(const STR_String& attr) { +PyAttributeDef KX_CameraActuator::Attributes[] = { + KX_PYATTRIBUTE_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_minHeight), + KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_maxHeight), + KX_PYATTRIBUTE_FLOAT_RW("height",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_height), + KX_PYATTRIBUTE_BOOL_RW("xy",KX_CameraActuator,m_x), + {NULL} +}; + +PyObject* KX_CameraActuator::_getattr(const char *attr) { + PyObject* object; + + if (!strcmp(attr, "object")) { + if (!m_ob) Py_RETURN_NONE; + else return m_ob->AddRef(); + } + + object = _getattr_self(Attributes, this, attr); + if (object != NULL) + return object; _getattr_up(SCA_IActuator); } + +int KX_CameraActuator::_setattr(const char *attr, PyObject* value) { + int ret; + + if (!strcmp(attr, "object")) { + KX_GameObject *gameobj; + + if (!ConvertPythonToGameObject(value, &gameobj, true)) + return 1; // ConvertPythonToGameObject sets the error + + if (m_ob != NULL) + m_ob->UnregisterActuator(this); + + m_ob = (SCA_IObject*)gameobj; + + if (m_ob) + m_ob->RegisterActuator(this); + + return 0; + } + + ret = _setattr_self(Attributes, this, attr, value); + if (ret >= 0) + return ret; + return SCA_IActuator::_setattr(attr, value); +} + /* get obj ---------------------------------------------------------- */ const char KX_CameraActuator::GetObject_doc[] = "getObject(name_only = 1)\n" @@ -421,6 +468,9 @@ const char KX_CameraActuator::GetObject_doc[] = PyObject* KX_CameraActuator::PyGetObject(PyObject* self, PyObject* args) { int ret_name_only = 1; + + ShowDeprecationWarning("getObject()", "the object property"); + if (!PyArg_ParseTuple(args, "|i", &ret_name_only)) return NULL; @@ -441,6 +491,8 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self, PyObject* value) { KX_GameObject *gameobj; + ShowDeprecationWarning("setObject()", "the object property"); + if (!ConvertPythonToGameObject(value, &gameobj, true)) return NULL; // ConvertPythonToGameObject sets the error @@ -462,6 +514,7 @@ PyObject* KX_CameraActuator::PyGetMin(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("getMin()", "the min property"); return PyFloat_FromDouble(m_minHeight); } /* set min ---------------------------------------------------------- */ @@ -472,11 +525,12 @@ PyObject* KX_CameraActuator::PySetMin(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("setMin()", "the min property"); float min; if(PyArg_ParseTuple(args,"f", &min)) { m_minHeight = min; - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -488,6 +542,7 @@ PyObject* KX_CameraActuator::PyGetMax(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("getMax()", "the max property"); return PyFloat_FromDouble(m_maxHeight); } /* set min ---------------------------------------------------------- */ @@ -498,11 +553,12 @@ PyObject* KX_CameraActuator::PySetMax(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("getMax()", "the max property"); float max; if(PyArg_ParseTuple(args,"f", &max)) { m_maxHeight = max; - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -514,6 +570,7 @@ PyObject* KX_CameraActuator::PyGetHeight(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("getHeight()", "the height property"); return PyFloat_FromDouble(m_height); } /* set height ---------------------------------------------------------- */ @@ -524,11 +581,12 @@ PyObject* KX_CameraActuator::PySetHeight(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("getHeight()", "the height property"); float height; if(PyArg_ParseTuple(args,"f", &height)) { m_height = height; - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -541,11 +599,12 @@ PyObject* KX_CameraActuator::PySetXY(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("setXY()", "the xy property"); int value; if(PyArg_ParseTuple(args,"i", &value)) { m_x = value != 0; - Py_Return; + Py_RETURN_NONE; } return NULL; } @@ -559,6 +618,7 @@ PyObject* KX_CameraActuator::PyGetXY(PyObject* self, PyObject* args, PyObject* kwds) { + ShowDeprecationWarning("getXY()", "the xy property"); return PyInt_FromLong(m_x); } diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index d53d12b3b82..3b08536fc21 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -59,13 +59,13 @@ private : //const MT_Scalar m_maxHeight; /** height (float), */ - MT_Scalar m_height; + float m_height; /** min (float), */ - MT_Scalar m_minHeight; + float m_minHeight; /** max (float), */ - MT_Scalar m_maxHeight; + float m_maxHeight; /** xy toggle (pick one): true == x, false == y */ bool m_x; @@ -88,9 +88,9 @@ private : SCA_IObject *gameobj, //const CValue *ob, SCA_IObject *ob, - MT_Scalar hght, - MT_Scalar minhght, - MT_Scalar maxhght, + float hght, + float minhght, + float maxhght, bool xytog, PyTypeObject* T=&Type @@ -120,8 +120,9 @@ private : /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); - + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); + /* set object to look at */ KX_PYMETHOD_DOC_O(KX_CameraActuator,SetObject); /* get current object */ diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 5e8af0f040c..7345edb054b 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -29,7 +29,10 @@ #ifndef __KX_CLIENTOBJECT_INFO_H #define __KX_CLIENTOBJECT_INFO_H +/* Note, the way this works with/without sumo is a bit odd */ +#ifdef USE_SUMO_SOLID #include <SM_Object.h> +#endif //USE_SUMO_SOLID #include <list> @@ -38,7 +41,10 @@ class KX_GameObject; /** * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks */ -struct KX_ClientObjectInfo : public SM_ClientObject +struct KX_ClientObjectInfo +#ifdef USE_SUMO_SOLID + : public SM_ClientObject +#endif { enum clienttype { STATIC, @@ -52,14 +58,18 @@ struct KX_ClientObjectInfo : public SM_ClientObject std::list<SCA_ISensor*> m_sensors; public: KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC, void *auxilary_info = NULL) : +#ifdef USE_SUMO_SOLID SM_ClientObject(), +#endif m_type(type), m_gameobject(gameobject), m_auxilary_info(auxilary_info) {} - KX_ClientObjectInfo(const KX_ClientObjectInfo ©) - : SM_ClientObject(copy), + KX_ClientObjectInfo(const KX_ClientObjectInfo ©) : +#ifdef USE_SUMO_SOLID + SM_ClientObject(copy), +#endif m_type(copy.m_type), m_gameobject(copy.m_gameobject), m_auxilary_info(copy.m_auxilary_info) diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp index 76357e9c58f..fba9544d702 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -56,9 +56,9 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj, int option, char *property, PyTypeObject* T) : + SCA_IActuator(gameobj, T), m_refDirection(refDir), - m_currentTime(0), - SCA_IActuator(gameobj, T) + m_currentTime(0) { m_posDampTime = posDampTime; m_rotDampTime = rotDampTime; @@ -612,7 +612,11 @@ PyMethodDef KX_ConstraintActuator::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* KX_ConstraintActuator::_getattr(const STR_String& attr) { +PyAttributeDef KX_ConstraintActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_ConstraintActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -633,7 +637,7 @@ PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self, m_posDampTime = dampArg; if (m_posDampTime < 0) m_posDampTime = 0; - Py_Return; + Py_RETURN_NONE; } /* 3. getDamp */ const char KX_ConstraintActuator::GetDamp_doc[] = @@ -660,7 +664,7 @@ PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self, m_rotDampTime = dampArg; if (m_rotDampTime < 0) m_rotDampTime = 0; - Py_Return; + Py_RETURN_NONE; } /* 3. getRotDamp */ const char KX_ConstraintActuator::GetRotDamp_doc[] = @@ -695,7 +699,7 @@ PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self, } m_refDirection = dir/len; - Py_Return; + Py_RETURN_NONE; } /* 3. getDirection */ const char KX_ConstraintActuator::GetDirection_doc[] = @@ -730,7 +734,7 @@ PyObject* KX_ConstraintActuator::PySetOption(PyObject* self, m_option = option; - Py_Return; + Py_RETURN_NONE; } /* 3. getOption */ const char KX_ConstraintActuator::GetOption_doc[] = @@ -759,7 +763,7 @@ PyObject* KX_ConstraintActuator::PySetTime(PyObject* self, t = 0; m_activeTime = t; - Py_Return; + Py_RETURN_NONE; } /* 3. getTime */ const char KX_ConstraintActuator::GetTime_doc[] = @@ -789,7 +793,7 @@ PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self, m_property[sizeof(m_property)-1] = 0; } - Py_Return; + Py_RETURN_NONE; } /* 3. getProperty */ const char KX_ConstraintActuator::GetProperty_doc[] = @@ -829,7 +833,7 @@ PyObject* KX_ConstraintActuator::PySetMin(PyObject* self, break; } - Py_Return; + Py_RETURN_NONE; } /* 5. getDistance */ const char KX_ConstraintActuator::GetDistance_doc[] = @@ -874,7 +878,7 @@ PyObject* KX_ConstraintActuator::PySetMax(PyObject* self, break; } - Py_Return; + Py_RETURN_NONE; } /* 7. getRayLength */ const char KX_ConstraintActuator::GetRayLength_doc[] = @@ -918,7 +922,7 @@ PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self, if (IsValidMode((KX_CONSTRAINTTYPE)locrotArg)) m_locrot = locrotArg; - Py_Return; + Py_RETURN_NONE; } /* 9. getLimit */ const char KX_ConstraintActuator::GetLimit_doc[] = diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 28b9b1e6a0b..132b8a7328a 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -142,7 +142,7 @@ protected: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp); KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetDamp); diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index c9095ff34f6..f014c1896fe 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -92,32 +92,30 @@ PyParentObject KX_ConstraintWrapper::Parents[] = { NULL }; -PyObject* KX_ConstraintWrapper::_getattr(const STR_String& attr) +PyObject* KX_ConstraintWrapper::_getattr(const char *attr) { //here you can search for existing data members (like mass,friction etc.) _getattr_up(PyObjectPlus); } -int KX_ConstraintWrapper::_setattr(const STR_String& attr,PyObject* pyobj) +int KX_ConstraintWrapper::_setattr(const char *attr,PyObject* pyobj) { - - PyTypeObject* type = pyobj->ob_type; int result = 1; - if (type == &PyList_Type) + if (PyList_Check(pyobj)) { result = 0; } - if (type == &PyFloat_Type) + if (PyFloat_Check(pyobj)) { result = 0; } - if (type == &PyInt_Type) + if (PyInt_Check(pyobj)) { result = 0; } - if (type == &PyString_Type) + if (PyString_Check(pyobj)) { result = 0; } @@ -132,3 +130,7 @@ PyMethodDef KX_ConstraintWrapper::Methods[] = { {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS}, {NULL,NULL} //Sentinel }; + +PyAttributeDef KX_ConstraintWrapper::Attributes[] = { + { NULL } //Sentinel +}; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 79fb3dc21aa..36606d2d67b 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -35,8 +35,8 @@ class KX_ConstraintWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); public: KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); virtual ~KX_ConstraintWrapper (); diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 53486cecf73..3534500e619 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -32,7 +32,7 @@ /* These are defined by the build system... */ //but the build system is broken, because it doesn't allow for 2 or more defines at once. //Please leave Sumo _AND_ Bullet enabled -#define USE_SUMO_SOLID +//#define USE_SUMO_SOLID // scons defines this #define USE_BULLET //#define USE_ODE @@ -127,6 +127,14 @@ struct KX_ObjectProperties ///////////////////////// + bool m_lockXaxis; + bool m_lockYaxis; + bool m_lockZaxis; + bool m_lockXRotaxis; + bool m_lockYRotaxis; + bool m_lockZRotaxis; + + ///////////////////////// double m_margin; KX_BoundBoxClass m_boundclass; union { diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 46e46b014b5..602486e0017 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -1101,8 +1101,24 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, { btRigidBody* rbody = physicscontroller->GetRigidBody(); - if (rbody && objprop->m_disableSleeping) - rbody->setActivationState(DISABLE_DEACTIVATION); + if (rbody) + { + btVector3 linearFactor( + objprop->m_lockXaxis? 0 : 1, + objprop->m_lockYaxis? 0 : 1, + objprop->m_lockZaxis? 0 : 1); + btVector3 angularFactor( + objprop->m_lockXRotaxis? 0 : 1, + objprop->m_lockYRotaxis? 0 : 1, + objprop->m_lockZRotaxis? 0 : 1); + rbody->setLinearFactor(linearFactor); + rbody->setAngularFactor(angularFactor); + + if (rbody && objprop->m_disableSleeping) + { + rbody->setActivationState(DISABLE_DEACTIVATION); + } + } } CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0; diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 76459e46731..3c0695b5952 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -132,7 +132,7 @@ bool KX_GameActuator::Update() { char mashal_path[512]; char *marshal_buffer = NULL; - int marshal_length; + unsigned int marshal_length; FILE *fp = NULL; pathGamePythonConfig(mashal_path); @@ -246,6 +246,10 @@ PyMethodDef KX_GameActuator::Methods[] = {NULL,NULL} //Sentinel }; +PyAttributeDef KX_GameActuator::Attributes[] = { + { NULL } //Sentinel +}; + /* getFile */ const char KX_GameActuator::GetFile_doc[] = "getFile()\n" @@ -270,13 +274,13 @@ PyObject* KX_GameActuator::PySetFile(PyObject* self, PyObject* args, PyObject* k m_filename = STR_String(new_file); - Py_Return; + Py_RETURN_NONE; } -PyObject* KX_GameActuator::_getattr(const STR_String& attr) +PyObject* KX_GameActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h index bb3448995dc..856fa0c24e9 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.h +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -77,7 +77,7 @@ protected: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD_DOC(KX_GameActuator,GetFile); KX_PYMETHOD_DOC(KX_GameActuator,SetFile); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 42316c6c873..95df9d51a26 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -521,7 +521,7 @@ KX_GameObject::UpdateMaterialData( { KX_BlenderMaterial *m = static_cast<KX_BlenderMaterial*>(poly); - if (matname_hash == NULL) + if (matname_hash == 0) { m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha); // if mesh has only one material attached to it then use original hack with no need to edit vertices (better performance) @@ -690,9 +690,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) switch (axis) { case 0: //x axis - ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis + ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) //is the vector paralell to the pivot? - ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot! + ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot! if (fac == 1.0) { x = vect; } else { @@ -705,9 +705,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) z = x.cross(y); break; case 1: //y axis - ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]); + ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]); if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) - ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); + ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); if (fac == 1.0) { y = vect; } else { @@ -720,9 +720,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) x = y.cross(z); break; case 2: //z axis - ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); + ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) - ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]); + ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]); if (fac == 1.0) { z = vect; } else { @@ -741,9 +741,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) x.normalize(); //normalize the vectors y.normalize(); z.normalize(); - orimat = MT_Matrix3x3( x[0],y[0],z[0], - x[1],y[1],z[1], - x[2],y[2],z[2]); + orimat.setValue( x[0],y[0],z[0], + x[1],y[1],z[1], + x[2],y[2],z[2]); if (GetSGNode()->GetSGParent() != NULL) { // the object is a child, adapt its local orientation so that @@ -945,13 +945,11 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const const MT_Point3& KX_GameObject::NodeGetWorldPosition() const { - static MT_Point3 defaultPosition = MT_Point3(0.0, 0.0, 0.0); - // check on valid node in case a python controller holds a reference to a deleted object - if (!GetSGNode()) - return defaultPosition; - - return GetSGNode()->GetWorldPosition(); + if (GetSGNode()) + return GetSGNode()->GetWorldPosition(); + else + return MT_Point3(0.0, 0.0, 0.0); } /* Suspend/ resume: for the dynamic behaviour, there is a simple @@ -1030,11 +1028,14 @@ PyMethodDef KX_GameObject::Methods[] = { {"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS}, KX_PYMETHODTABLE(KX_GameObject, rayCastTo), KX_PYMETHODTABLE(KX_GameObject, rayCast), - KX_PYMETHODTABLE(KX_GameObject, getDistanceTo), - KX_PYMETHODTABLE(KX_GameObject, getVectTo), + KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo), + KX_PYMETHODTABLE_O(KX_GameObject, getVectTo), {NULL,NULL} //Sentinel }; +PyAttributeDef KX_GameObject::Attributes[] = { + { NULL } //Sentinel +}; /* @@ -1124,40 +1125,39 @@ PyParentObject KX_GameObject::Parents[] = { -PyObject* KX_GameObject::_getattr(const STR_String& attr) +PyObject* KX_GameObject::_getattr(const char *attr) { if (m_pPhysicsController1) { - if (attr == "mass") + if (!strcmp(attr, "mass")) return PyFloat_FromDouble(m_pPhysicsController1->GetMass()); } - if (attr == "parent") + if (!strcmp(attr, "parent")) { KX_GameObject* parent = GetParent(); if (parent) - { - parent->AddRef(); - return parent; - } + return parent->AddRef(); Py_RETURN_NONE; } - if (attr == "visible") + if (!strcmp(attr, "visible")) return PyInt_FromLong(m_bVisible); - if (attr == "position") + if (!strcmp(attr, "position")) return PyObjectFrom(NodeGetWorldPosition()); - if (attr == "orientation") + if (!strcmp(attr, "orientation")) return PyObjectFrom(NodeGetWorldOrientation()); - if (attr == "scaling") + if (!strcmp(attr, "scaling")) return PyObjectFrom(NodeGetWorldScaling()); - if (attr == "name") + if (!strcmp(attr, "name")) return PyString_FromString(m_name.ReadPtr()); - if (attr == "timeOffset") { + + if (!strcmp(attr, "timeOffset")) + { if (m_pSGNode->GetSGParent()->IsSlowParent()) { return PyFloat_FromDouble(static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->GetTimeOffset()); } else { @@ -1169,18 +1169,18 @@ PyObject* KX_GameObject::_getattr(const STR_String& attr) _getattr_up(SCA_IObject); } -int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr method +int KX_GameObject::_setattr(const char *attr, PyObject *value) // _setattr method { - if (attr == "parent") { - PyErr_SetString(PyExc_AttributeError, "attribute \"mass\" is read only\nUse setParent()"); + if (!strcmp(attr, "parent")) { + PyErr_SetString(PyExc_AttributeError, "attribute \"parent\" is read only\nUse setParent()"); return 1; } if (PyInt_Check(value)) { int val = PyInt_AsLong(value); - if (attr == "visible") + if (!strcmp(attr, "visible")) { SetVisible(val != 0, false); UpdateBuckets(false); @@ -1191,7 +1191,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr if (PyFloat_Check(value)) { MT_Scalar val = PyFloat_AsDouble(value); - if (attr == "timeOffset") { + if (!strcmp(attr, "timeOffset")) { if (m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsSlowParent()) { static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->SetTimeOffset(val); return 0; @@ -1199,7 +1199,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr return 0; } } - if (attr == "mass") { + if (!strcmp(attr, "mass")) { if (m_pPhysicsController1) m_pPhysicsController1->SetMass(val); return 0; @@ -1208,7 +1208,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr if (PySequence_Check(value)) { - if (attr == "orientation") + if (!strcmp(attr, "orientation")) { MT_Matrix3x3 rot; if (PyObject_IsMT_Matrix(value, 3)) @@ -1251,7 +1251,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr return 1; } - if (attr == "position") + if (!strcmp(attr, "position")) { MT_Point3 pos; if (PyVecTo(value, pos)) @@ -1263,7 +1263,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr return 1; } - if (attr == "scaling") + if (!strcmp(attr, "scaling")) { MT_Vector3 scale; if (PyVecTo(value, scale)) @@ -1278,10 +1278,16 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr if (PyString_Check(value)) { - if (attr == "name") + if (!strcmp(attr, "name")) { +#if 0 // was added in revision 2832, but never took into account Object name mappings from revision 2 + // unlikely anyone ever used this successfully , removing. m_name = PyString_AsString(value); return 0; +#else + PyErr_SetString(PyExc_AttributeError, "object name readonly"); + return 1; +#endif } } @@ -1295,7 +1301,7 @@ PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args) int local = 0; PyObject* pyvect; - if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + if (PyArg_ParseTuple(args, "O|i:applyForce", &pyvect, &local)) { MT_Vector3 force; if (PyVecTo(pyvect, force)) { ApplyForce(force, (local!=0)); @@ -1310,7 +1316,7 @@ PyObject* KX_GameObject::PyApplyTorque(PyObject* self, PyObject* args) int local = 0; PyObject* pyvect; - if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + if (PyArg_ParseTuple(args, "O|i:applyTorque", &pyvect, &local)) { MT_Vector3 torque; if (PyVecTo(pyvect, torque)) { ApplyTorque(torque, (local!=0)); @@ -1325,7 +1331,7 @@ PyObject* KX_GameObject::PyApplyRotation(PyObject* self, PyObject* args) int local = 0; PyObject* pyvect; - if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + if (PyArg_ParseTuple(args, "O|i:applyRotation", &pyvect, &local)) { MT_Vector3 rotation; if (PyVecTo(pyvect, rotation)) { ApplyRotation(rotation, (local!=0)); @@ -1340,7 +1346,7 @@ PyObject* KX_GameObject::PyApplyMovement(PyObject* self, PyObject* args) int local = 0; PyObject* pyvect; - if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + if (PyArg_ParseTuple(args, "O|i:applyMovement", &pyvect, &local)) { MT_Vector3 movement; if (PyVecTo(pyvect, movement)) { ApplyMovement(movement, (local!=0)); @@ -1354,7 +1360,7 @@ PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args) { // only can get the velocity if we have a physics object connected to us... int local = 0; - if (PyArg_ParseTuple(args,"|i",&local)) + if (PyArg_ParseTuple(args,"|i:getLinearVelocity",&local)) { return PyObjectFrom(GetLinearVelocity((local!=0))); } @@ -1369,7 +1375,7 @@ PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self, PyObject* args) int local = 0; PyObject* pyvect; - if (PyArg_ParseTuple(args,"O|i",&pyvect,&local)) { + if (PyArg_ParseTuple(args,"O|i:setLinearVelocity",&pyvect,&local)) { MT_Vector3 velocity; if (PyVecTo(pyvect, velocity)) { setLinearVelocity(velocity, (local!=0)); @@ -1383,7 +1389,7 @@ PyObject* KX_GameObject::PyGetAngularVelocity(PyObject* self, PyObject* args) { // only can get the velocity if we have a physics object connected to us... int local = 0; - if (PyArg_ParseTuple(args,"|i",&local)) + if (PyArg_ParseTuple(args,"|i:getAngularVelocity",&local)) { return PyObjectFrom(GetAngularVelocity((local!=0))); } @@ -1398,7 +1404,7 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args) int local = 0; PyObject* pyvect; - if (PyArg_ParseTuple(args,"O|i",&pyvect,&local)) { + if (PyArg_ParseTuple(args,"O|i:setAngularVelocity",&pyvect,&local)) { MT_Vector3 velocity; if (PyVecTo(pyvect, velocity)) { setAngularVelocity(velocity, (local!=0)); @@ -1411,7 +1417,7 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args) PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args) { int visible, recursive = 0; - if (!PyArg_ParseTuple(args,"i|i",&visible, &recursive)) + if (!PyArg_ParseTuple(args,"i|i:setVisible",&visible, &recursive)) return NULL; SetVisible(visible ? true:false, recursive ? true:false); @@ -1457,12 +1463,10 @@ PyObject* KX_GameObject::PySetState(PyObject* self, PyObject* value) PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args) { // only can get the velocity if we have a physics object connected to us... - MT_Vector3 velocity(0.0,0.0,0.0); MT_Point3 point(0.0,0.0,0.0); - - PyObject* pypos = NULL; - if (PyArg_ParseTuple(args, "|O", &pypos)) + + if (PyArg_ParseTuple(args, "|O:getVelocity", &pypos)) { if (pypos) PyVecTo(pypos, point); @@ -1473,10 +1477,11 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args) if (m_pPhysicsController1) { - velocity = m_pPhysicsController1->GetVelocity(point); + return PyObjectFrom(m_pPhysicsController1->GetVelocity(point)); + } + else { + return PyObjectFrom(MT_Vector3(0.0,0.0,0.0)); } - - return PyObjectFrom(velocity); } @@ -1518,10 +1523,7 @@ PyObject* KX_GameObject::PyGetParent(PyObject* self) { KX_GameObject* parent = this->GetParent(); if (parent) - { - parent->AddRef(); - return parent; - } + return parent->AddRef(); Py_RETURN_NONE; } @@ -1590,7 +1592,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args) { int mesh = 0; - if (!PyArg_ParseTuple(args, "|i", &mesh)) + if (!PyArg_ParseTuple(args, "|i:getMesh", &mesh)) return NULL; // python sets a simple error if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0) @@ -1636,7 +1638,7 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, PyObject* args) return NULL; } - if (PyArg_ParseTuple(args, "OO", &pyattach, &pyimpulse)) + if (PyArg_ParseTuple(args, "OO:applyImpulse", &pyattach, &pyimpulse)) { MT_Point3 attach; MT_Vector3 impulse; @@ -1703,7 +1705,7 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, PyObject* args) int axis = 2; //z axis is the default float fac = 1.0; - if (PyArg_ParseTuple(args,"O|if",&pyvect,&axis, &fac)) + if (PyArg_ParseTuple(args,"O|if:alignAxisToVect",&pyvect,&axis, &fac)) { MT_Vector3 vect; if (PyVecTo(pyvect, vect)) @@ -1771,19 +1773,18 @@ PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self) return ConvertKeysToPython(); } -KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo, +KX_PYMETHODDEF_DOC_O(KX_GameObject, getDistanceTo, "getDistanceTo(other): get distance to another point/KX_GameObject") { MT_Point3 b; - if (PyVecArgTo(args, b)) + if (PyVecTo(value, b)) { return PyFloat_FromDouble(NodeGetWorldPosition().distance(b)); } PyErr_Clear(); - PyObject *pyother; KX_GameObject *other; - if (PyArg_ParseTuple(args, "O", &pyother) && ConvertPythonToGameObject(pyother, &other, false)) + if (ConvertPythonToGameObject(value, &other, false)) { return PyFloat_FromDouble(NodeGetWorldPosition().distance(other->NodeGetWorldPosition())); } @@ -1791,7 +1792,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo, return NULL; } -KX_PYMETHODDEF_DOC(KX_GameObject, getVectTo, +KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo, "getVectTo(other): get vector and the distance to another point/KX_GameObject\n" "Returns a 3-tuple with (distance,worldVector,localVector)\n") { @@ -1800,14 +1801,13 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getVectTo, MT_Scalar distance; PyObject *returnValue; - PyObject *pyother; - if (!PyVecArgTo(args, toPoint)) + if (!PyVecTo(value, toPoint)) { PyErr_Clear(); KX_GameObject *other; - if (PyArg_ParseTuple(args, "O", &pyother) && ConvertPythonToGameObject(pyother, &other, false)) + if (ConvertPythonToGameObject(value, &other, false)) { toPoint = other->NodeGetWorldPosition(); } else @@ -1892,7 +1892,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, float dist = 0.0f; char *propName = NULL; - if (!PyArg_ParseTuple(args,"O|fs", &pyarg, &dist, &propName)) { + if (!PyArg_ParseTuple(args,"O|fs:rayCastTo", &pyarg, &dist, &propName)) { return NULL; // python sets simple error } @@ -1935,10 +1935,8 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, KX_RayCast::RayTest(pe, fromPoint, toPoint, callback); if (m_pHitObject) - { - m_pHitObject->AddRef(); - return m_pHitObject; - } + return m_pHitObject->AddRef(); + Py_RETURN_NONE; } @@ -1971,7 +1969,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, KX_GameObject *other; int face=0, xray=0, poly=0; - if (!PyArg_ParseTuple(args,"O|Ofsiii", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) { + if (!PyArg_ParseTuple(args,"O|Ofsiii:rayCast", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) { return NULL; // Python sets a simple error } @@ -2047,8 +2045,8 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, if (callback.m_hitMesh) { // if this field is set, then we can trust that m_hitPolygon is a valid polygon - RAS_Polygon* poly = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon); - KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, poly); + RAS_Polygon* polygon = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon); + KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, polygon); PyTuple_SET_ITEM(returnValue, 3, polyproxy); } else diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 4f26031356f..211c9b7ca7d 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -756,19 +756,10 @@ public: * @section Python interface functions. */ - virtual - PyObject* - _getattr( - const STR_String& attr - ); - - virtual - int - _setattr( - const STR_String& attr, - PyObject *value - ); // _setattr method - + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); // _setattr method + virtual PyObject* _repr(void) { return PyString_FromString(GetName().ReadPtr()); } + KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition); KX_PYMETHOD_O(KX_GameObject,SetPosition); KX_PYMETHOD_O(KX_GameObject,SetWorldPosition); @@ -809,8 +800,8 @@ public: KX_PYMETHOD_NOARGS(KX_GameObject,EndObject); KX_PYMETHOD_DOC(KX_GameObject,rayCastTo); KX_PYMETHOD_DOC(KX_GameObject,rayCast); - KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo); - KX_PYMETHOD_DOC(KX_GameObject,getVectTo); + KX_PYMETHOD_DOC_O(KX_GameObject,getDistanceTo); + KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo); private : diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 67d54cf0b0b..55a7e2ade60 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -58,8 +58,8 @@ KX_IpoSGController::KX_IpoSGController() m_ipo_add(false), m_ipo_local(false), m_modified(true), - m_ipo_start_initialized(false), m_ipotime(1.0), + m_ipo_start_initialized(false), m_ipo_start_euler(0.0,0.0,0.0), m_ipo_euler_initialized(false) { diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index f5e17118ffb..623a939bf62 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -457,7 +457,11 @@ PyMethodDef KX_IpoActuator::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* KX_IpoActuator::_getattr(const STR_String& attr) { +PyAttributeDef KX_IpoActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_IpoActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -503,7 +507,7 @@ PyObject* KX_IpoActuator::PySet(PyObject* self, ; /* error */ } - Py_Return; + Py_RETURN_NONE; } /* set property ----------------------------------------------------------- */ @@ -523,7 +527,7 @@ PyObject* KX_IpoActuator::PySetProperty(PyObject* self, m_propname = propertyName; - Py_Return; + Py_RETURN_NONE; } /* 4. setStart: */ @@ -541,7 +545,7 @@ PyObject* KX_IpoActuator::PySetStart(PyObject* self, m_startframe = startArg; - Py_Return; + Py_RETURN_NONE; } /* 5. getStart: */ const char KX_IpoActuator::GetStart_doc[] = @@ -566,7 +570,7 @@ PyObject* KX_IpoActuator::PySetEnd(PyObject* self, m_endframe = endArg; - Py_Return; + Py_RETURN_NONE; } /* 7. getEnd: */ const char KX_IpoActuator::GetEnd_doc[] = @@ -594,7 +598,7 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self, if (m_ipo_as_force) m_ipo_add = false; - Py_Return; + Py_RETURN_NONE; } /* 7. getIpoAsForce: */ const char KX_IpoActuator::GetIpoAsForce_doc[] = @@ -622,7 +626,7 @@ PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self, if (m_ipo_add) m_ipo_as_force = false; - Py_Return; + Py_RETURN_NONE; } /* 7. getIpoAsForce: */ const char KX_IpoActuator::GetIpoAdd_doc[] = @@ -651,7 +655,7 @@ PyObject* KX_IpoActuator::PySetType(PyObject* self, m_type = (IpoActType) typeArg; } - Py_Return; + Py_RETURN_NONE; } /* 9. getType: */ const char KX_IpoActuator::GetType_doc[] = @@ -679,7 +683,7 @@ PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self, m_ipo_local = PyArgToBool(boolArg); - Py_Return; + Py_RETURN_NONE; } /* 11. getForceIpoActsLocal: */ const char KX_IpoActuator::GetForceIpoActsLocal_doc[] = diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 8e5baed0530..12e1835ab49 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -141,7 +141,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC(KX_IpoActuator,Set); KX_PYMETHOD_DOC(KX_IpoActuator,SetProperty); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 1271474802c..97b4213b8bd 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -59,7 +59,10 @@ #include "KX_PythonInit.h" #include "KX_PyConstraintBinding.h" #include "PHY_IPhysicsEnvironment.h" + +#ifdef USE_SUMO_SOLID #include "SumoPhysicsEnvironment.h" +#endif #include "SND_Scene.h" #include "SND_IAudioDevice.h" @@ -713,7 +716,7 @@ void KX_KetsjiEngine::Render() if (!BeginFrame()) return; - KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) // for each scene, call the proceed functions { @@ -1109,6 +1112,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + if (scene->GetPhysicsEnvironment()) + scene->GetPhysicsEnvironment()->debugDrawWorld(); + + m_rasterizer->FlushDebugLines(); + PostRenderFrame(); } diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index e0f171e78e0..a2e93ecdd36 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -172,65 +172,59 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) GPU_lamp_shadow_buffer_unbind(lamp); } -PyObject* KX_LightObject::_getattr(const STR_String& attr) +PyObject* KX_LightObject::_getattr(const char *attr) { - if (attr == "layer") + if (!strcmp(attr, "layer")) return PyInt_FromLong(m_lightobj.m_layer); - if (attr == "energy") + if (!strcmp(attr, "energy")) return PyFloat_FromDouble(m_lightobj.m_energy); - if (attr == "distance") + if (!strcmp(attr, "distance")) return PyFloat_FromDouble(m_lightobj.m_distance); - if (attr == "colour" || attr == "color") + if (!strcmp(attr, "colour") || !strcmp(attr, "color")) return Py_BuildValue("[fff]", m_lightobj.m_red, m_lightobj.m_green, m_lightobj.m_blue); - if (attr == "lin_attenuation") + if (!strcmp(attr, "lin_attenuation")) return PyFloat_FromDouble(m_lightobj.m_att1); - if (attr == "quad_attenuation") + if (!strcmp(attr, "quad_attenuation")) return PyFloat_FromDouble(m_lightobj.m_att2); - if (attr == "spotsize") + if (!strcmp(attr, "spotsize")) return PyFloat_FromDouble(m_lightobj.m_spotsize); - if (attr == "spotblend") + if (!strcmp(attr, "spotblend")) return PyFloat_FromDouble(m_lightobj.m_spotblend); - if (attr == "SPOT") + if (!strcmp(attr, "SPOT")) return PyInt_FromLong(RAS_LightObject::LIGHT_SPOT); - if (attr == "SUN") + if (!strcmp(attr, "SUN")) return PyInt_FromLong(RAS_LightObject::LIGHT_SUN); - if (attr == "NORMAL") + if (!strcmp(attr, "NORMAL")) return PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL); - if (attr == "type") + if (!strcmp(attr, "type")) return PyInt_FromLong(m_lightobj.m_type); _getattr_up(KX_GameObject); } -int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue) -{ - if (attr == "SPOT" || attr == "SUN" || attr == "NORMAL") - { - PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr.ReadPtr()); - return 1; - } - +int KX_LightObject::_setattr(const char *attr, PyObject *pyvalue) +{ if (PyInt_Check(pyvalue)) { int value = PyInt_AsLong(pyvalue); - if (attr == "layer") + if (!strcmp(attr, "layer")) { m_lightobj.m_layer = value; return 0; } - if (attr == "type") + if (!strcmp(attr, "type")) { if (value >= RAS_LightObject::LIGHT_SPOT && value <= RAS_LightObject::LIGHT_NORMAL) m_lightobj.m_type = (RAS_LightObject::LightType) value; @@ -241,37 +235,37 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue) if (PyFloat_Check(pyvalue)) { float value = PyFloat_AsDouble(pyvalue); - if (attr == "energy") + if (!strcmp(attr, "energy")) { m_lightobj.m_energy = value; return 0; } - if (attr == "distance") + if (!strcmp(attr, "distance")) { m_lightobj.m_distance = value; return 0; } - if (attr == "lin_attenuation") + if (!strcmp(attr, "lin_attenuation")) { m_lightobj.m_att1 = value; return 0; } - if (attr == "quad_attenuation") + if (!strcmp(attr, "quad_attenuation")) { m_lightobj.m_att2 = value; return 0; } - if (attr == "spotsize") + if (!strcmp(attr, "spotsize")) { m_lightobj.m_spotsize = value; return 0; } - if (attr == "spotblend") + if (!strcmp(attr, "spotblend")) { m_lightobj.m_spotblend = value; return 0; @@ -280,7 +274,7 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue) if (PySequence_Check(pyvalue)) { - if (attr == "colour" || attr == "color") + if (!strcmp(attr, "colour") || !strcmp(attr, "color")) { MT_Vector3 color; if (PyVecTo(pyvalue, color)) @@ -294,6 +288,12 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue) } } + if (!strcmp(attr, "SPOT") || !strcmp(attr, "SUN") || !strcmp(attr, "NORMAL")) + { + PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr); + return 1; + } + return KX_GameObject::_setattr(attr, pyvalue); } @@ -301,6 +301,10 @@ PyMethodDef KX_LightObject::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef KX_LightObject::Attributes[] = { + { NULL } //Sentinel +}; + char KX_LightObject::doc[] = "Module KX_LightObject\n\n" "Constants:\n" "\tSPOT\n" diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index e5dbf0b7f4a..47edd09b5b9 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -63,8 +63,8 @@ public: void UnbindShadowBuffer(class RAS_IRasterizer *ras); void Update(); - virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */ - virtual int _setattr(const STR_String& attr, PyObject *pyvalue); + virtual PyObject* _getattr(const char *attr); /* lens, near, far, projection_matrix */ + virtual int _setattr(const char *attr, PyObject *pyvalue); virtual bool IsLight(void) { return true; } }; diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 5cc102248f2..a0c0a496c06 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -86,6 +86,10 @@ KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh), {NULL,NULL} //Sentinel }; +PyAttributeDef KX_MeshProxy::Attributes[] = { + { NULL } //Sentinel +}; + void KX_MeshProxy::SetMeshModified(bool v) { m_meshobj->SetMeshModified(v); @@ -93,9 +97,9 @@ void KX_MeshProxy::SetMeshModified(bool v) PyObject* -KX_MeshProxy::_getattr(const STR_String& attr) +KX_MeshProxy::_getattr(const char *attr) { - if (attr == "materials") + if (!strcmp(attr, "materials")) { PyObject *materials = PyList_New(0); list<RAS_MeshMaterial>::iterator mit = m_meshobj->GetFirstMaterial(); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index 3335c349673..34f60a54a3a 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -53,7 +53,7 @@ public: virtual CValue* GetReplica(); // stuff for python integration - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD(KX_MeshProxy,GetNumMaterials); KX_PYMETHOD(KX_MeshProxy,GetMaterialName); KX_PYMETHOD(KX_MeshProxy,GetTextureName); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 28279b9a6b8..384034485e7 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -42,6 +42,7 @@ #include "KX_Scene.h" #include "KX_Camera.h" #include "KX_MouseFocusSensor.h" +#include "KX_PyMath.h" #include "KX_RayCast.h" #include "KX_IPhysicsController.h" @@ -320,18 +321,22 @@ PyParentObject KX_MouseFocusSensor::Parents[] = { }; PyMethodDef KX_MouseFocusSensor::Methods[] = { - {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget, METH_VARARGS, (PY_METHODCHAR)GetRayTarget_doc}, - {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource, METH_VARARGS, (PY_METHODCHAR)GetRaySource_doc}, - {"getHitObject",(PyCFunction) KX_MouseFocusSensor::sPyGetHitObject,METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc}, - {"getHitPosition",(PyCFunction) KX_MouseFocusSensor::sPyGetHitPosition,METH_VARARGS, (PY_METHODCHAR)GetHitPosition_doc}, - {"getHitNormal",(PyCFunction) KX_MouseFocusSensor::sPyGetHitNormal,METH_VARARGS, (PY_METHODCHAR)GetHitNormal_doc}, - {"getRayDirection",(PyCFunction) KX_MouseFocusSensor::sPyGetRayDirection,METH_VARARGS, (PY_METHODCHAR)GetRayDirection_doc}, + {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget, METH_NOARGS, (PY_METHODCHAR)GetRayTarget_doc}, + {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource, METH_NOARGS, (PY_METHODCHAR)GetRaySource_doc}, + {"getHitObject",(PyCFunction) KX_MouseFocusSensor::sPyGetHitObject,METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc}, + {"getHitPosition",(PyCFunction) KX_MouseFocusSensor::sPyGetHitPosition,METH_NOARGS, (PY_METHODCHAR)GetHitPosition_doc}, + {"getHitNormal",(PyCFunction) KX_MouseFocusSensor::sPyGetHitNormal,METH_NOARGS, (PY_METHODCHAR)GetHitNormal_doc}, + {"getRayDirection",(PyCFunction) KX_MouseFocusSensor::sPyGetRayDirection,METH_NOARGS, (PY_METHODCHAR)GetRayDirection_doc}, {NULL,NULL} //Sentinel }; -PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) { +PyAttributeDef KX_MouseFocusSensor::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_MouseFocusSensor::_getattr(const char *attr) { _getattr_up(SCA_MouseSensor); } @@ -339,76 +344,40 @@ PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) { const char KX_MouseFocusSensor::GetHitObject_doc[] = "getHitObject()\n" "\tReturns the name of the object that was hit by this ray.\n"; -PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self) { if (m_hitObject) - { return m_hitObject->AddRef(); - } - Py_Return; + + Py_RETURN_NONE; } const char KX_MouseFocusSensor::GetHitPosition_doc[] = "getHitPosition()\n" "\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n"; -PyObject* KX_MouseFocusSensor::PyGetHitPosition(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_MouseFocusSensor::PyGetHitPosition(PyObject* self) { - - MT_Point3 pos = m_hitPosition; - - PyObject* resultlist = PyList_New(3); - int index; - for (index=0;index<3;index++) - { - PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); - } - return resultlist; - + return PyObjectFrom(m_hitPosition); } const char KX_MouseFocusSensor::GetRayDirection_doc[] = "getRayDirection()\n" "\tReturns the direction from the ray (in worldcoordinates) .\n"; -PyObject* KX_MouseFocusSensor::PyGetRayDirection(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_MouseFocusSensor::PyGetRayDirection(PyObject* self) { MT_Vector3 dir = m_prevTargetPoint - m_prevSourcePoint; dir.normalize(); - - PyObject* resultlist = PyList_New(3); - int index; - for (index=0;index<3;index++) - { - PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index])); - } - return resultlist; - + return PyObjectFrom(dir); } const char KX_MouseFocusSensor::GetHitNormal_doc[] = "getHitNormal()\n" "\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n"; -PyObject* KX_MouseFocusSensor::PyGetHitNormal(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_MouseFocusSensor::PyGetHitNormal(PyObject* self) { - MT_Vector3 pos = m_hitNormal; - - PyObject* resultlist = PyList_New(3); - int index; - for (index=0;index<3;index++) - { - PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); - } - return resultlist; - + return PyObjectFrom(m_hitNormal); } @@ -417,16 +386,8 @@ const char KX_MouseFocusSensor::GetRayTarget_doc[] = "getRayTarget()\n" "\tReturns the target of the ray that seeks the focus object,\n" "\tin worldcoordinates."; -PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self, - PyObject* args, - PyObject* kwds) { - PyObject *retVal = PyList_New(3); - - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevTargetPoint[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevTargetPoint[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevTargetPoint[2])); - - return retVal; +PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self) { + return PyObjectFrom(m_prevTargetPoint); } /* getRayTarget */ @@ -434,16 +395,8 @@ const char KX_MouseFocusSensor::GetRaySource_doc[] = "getRaySource()\n" "\tReturns the source of the ray that seeks the focus object,\n" "\tin worldcoordinates."; -PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self, - PyObject* args, - PyObject* kwds) { - PyObject *retVal = PyList_New(3); - - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevSourcePoint[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevSourcePoint[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevSourcePoint[2])); - - return retVal; +PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self) { + return PyObjectFrom(m_prevSourcePoint); } /* eof */ diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 6731444699b..4979783032c 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -87,15 +87,15 @@ class KX_MouseFocusSensor : public SCA_MouseSensor /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); - KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayTarget); - KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRaySource); + KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayTarget); + KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRaySource); - KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitObject); - KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitPosition); - KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitNormal); - KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayDirection); + KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitObject); + KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitPosition); + KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitNormal); + KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayDirection); /* --------------------------------------------------------------------- */ SCA_IObject* m_hitObject; diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index bae87c28123..993a6b3d86c 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -37,14 +37,13 @@ #include "PHY_IPhysicsEnvironment.h" #include "PHY_IPhysicsController.h" - #ifdef HAVE_CONFIG_H #include <config.h> #endif KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, KX_GameObject* gameobj, - double margin, - double resetmargin, + float margin, + float resetmargin, bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, @@ -53,6 +52,7 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, :KX_TouchSensor(eventmgr, gameobj, bFindMaterial, + false, touchedpropname, /* scene, */ T), @@ -240,7 +240,7 @@ bool KX_NearSensor::BroadPhaseFilterCollision(void*obj1,void*obj2) bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData * coll_data) { // KX_TouchEventManager* toucheventmgr = static_cast<KX_TouchEventManager*>(m_eventmgr); - KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent()); +// KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent()); // need the mapping from PHY_IPhysicsController to gameobjects now @@ -272,12 +272,20 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData //} } - return DT_CONTINUE; + return false; // was DT_CONTINUE; but this was defined in Sumo as false } +/* ------------------------------------------------------------------------- */ +/* Python Functions */ +/* ------------------------------------------------------------------------- */ + +//No methods + +/* ------------------------------------------------------------------------- */ +/* Python Integration Hooks */ +/* ------------------------------------------------------------------------- */ -// python embedding PyTypeObject KX_NearSensor::Type = { PyObject_HEAD_INIT(&PyType_Type) 0, @@ -311,17 +319,31 @@ PyParentObject KX_NearSensor::Parents[] = { PyMethodDef KX_NearSensor::Methods[] = { - {"setProperty", (PyCFunction) KX_NearSensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc}, - {"getProperty", (PyCFunction) KX_NearSensor::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc}, - {"getHitObject",(PyCFunction) KX_NearSensor::sPyGetHitObject, METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc}, - {"getHitObjectList", (PyCFunction) KX_NearSensor::sPyGetHitObjectList, METH_VARARGS, (PY_METHODCHAR)GetHitObjectList_doc}, + //No methods {NULL,NULL} //Sentinel }; +PyAttributeDef KX_NearSensor::Attributes[] = { + KX_PYATTRIBUTE_FLOAT_RW_CHECK("distance", 0, 100, KX_NearSensor, m_Margin, CheckResetDistance), + KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 100, KX_NearSensor, m_ResetMargin, CheckResetDistance), + {NULL} //Sentinel +}; -PyObject* -KX_NearSensor::_getattr(const STR_String& attr) + +PyObject* KX_NearSensor::_getattr(const char *attr) { - _getattr_up(KX_TouchSensor); + PyObject* object = _getattr_self(Attributes, this, attr); + if (object != NULL) + return object; + + _getattr_up(KX_TouchSensor); } +int KX_NearSensor::_setattr(const char *attr, PyObject* value) +{ + int ret = _setattr_self(Attributes, this, attr, value); + if (ret >= 0) + return ret; + + return KX_TouchSensor::_setattr(attr, value); +} diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 3f7078ef9fd..ee03992e734 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -42,15 +42,15 @@ class KX_NearSensor : public KX_TouchSensor { Py_Header; protected: - double m_Margin; - double m_ResetMargin; + float m_Margin; + float m_ResetMargin; KX_Scene* m_scene; KX_ClientObjectInfo* m_client_info; public: KX_NearSensor(class SCA_EventManager* eventmgr, class KX_GameObject* gameobj, - double margin, - double resetmargin, + float margin, + float resetmargin, bool bFindMaterial, const STR_String& touchedpropname, class KX_Scene* scene, @@ -78,8 +78,25 @@ public: virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2); virtual void RegisterSumo(KX_TouchEventManager *touchman); virtual void UnregisterSumo(KX_TouchEventManager* touchman); - - virtual PyObject* _getattr(const STR_String& attr); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); + + //No methods + + //This method is used to make sure the distance does not exceed the reset distance + static int CheckResetDistance(void *self, const PyAttributeDef*) + { + KX_NearSensor* sensor = reinterpret_cast<KX_NearSensor*>(self); + + if (sensor->m_Margin > sensor->m_ResetMargin) + sensor->m_ResetMargin = sensor->m_Margin; + + return 0; + } }; diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index 98e73d4f0d7..0666261b470 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -65,12 +65,12 @@ KX_ObjectActuator( m_current_linear_factor(0.0), m_current_angular_factor(0.0), m_damping(damping), + m_previous_error(0.0,0.0,0.0), + m_error_accumulator(0.0,0.0,0.0), m_bitLocalFlag (flag), m_active_combined_velocity (false), m_linear_damping_active(false), - m_angular_damping_active(false), - m_error_accumulator(0.0,0.0,0.0), - m_previous_error(0.0,0.0,0.0) + m_angular_damping_active(false) { if (m_bitLocalFlag.ServoControl) { @@ -332,7 +332,11 @@ PyMethodDef KX_ObjectActuator::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* KX_ObjectActuator::_getattr(const STR_String& attr) { +PyAttributeDef KX_ObjectActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_ObjectActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); }; @@ -365,7 +369,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self, m_force.setValue(vecArg); m_bitLocalFlag.Force = PyArgToBool(bToggle); UpdateFuzzyFlags(); - Py_Return; + Py_RETURN_NONE; } /* 4. getTorque */ @@ -394,7 +398,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self, m_torque.setValue(vecArg); m_bitLocalFlag.Torque = PyArgToBool(bToggle); UpdateFuzzyFlags(); - Py_Return; + Py_RETURN_NONE; } /* 6. getDLoc */ @@ -423,7 +427,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self, m_dloc.setValue(vecArg); m_bitLocalFlag.DLoc = PyArgToBool(bToggle); UpdateFuzzyFlags(); - Py_Return; + Py_RETURN_NONE; } /* 8. getDRot */ @@ -452,7 +456,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self, m_drot.setValue(vecArg); m_bitLocalFlag.DRot = PyArgToBool(bToggle); UpdateFuzzyFlags(); - Py_Return; + Py_RETURN_NONE; } /* 10. getLinearVelocity */ @@ -480,7 +484,7 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self, m_linear_velocity.setValue(vecArg); m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle); UpdateFuzzyFlags(); - Py_Return; + Py_RETURN_NONE; } @@ -508,7 +512,7 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self, m_angular_velocity.setValue(vecArg); m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle); UpdateFuzzyFlags(); - Py_Return; + Py_RETURN_NONE; } /* 13. setDamping */ @@ -520,7 +524,7 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* self, return NULL; } m_damping = damping; - Py_Return; + Py_RETURN_NONE; } /* 13. getVelocityDamping */ @@ -551,7 +555,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self, m_drot[0] = vecArg[0]; m_dloc[0] = vecArg[1]; m_bitLocalFlag.Torque = PyArgToBool(bToggle); - Py_Return; + Py_RETURN_NONE; } /* 6. getForceLimitY */ @@ -578,7 +582,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self, m_drot[1] = vecArg[0]; m_dloc[1] = vecArg[1]; m_bitLocalFlag.DLoc = PyArgToBool(bToggle); - Py_Return; + Py_RETURN_NONE; } /* 6. getForceLimitZ */ @@ -605,7 +609,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self, m_drot[2] = vecArg[0]; m_dloc[2] = vecArg[1]; m_bitLocalFlag.DRot = PyArgToBool(bToggle); - Py_Return; + Py_RETURN_NONE; } /* 4. getPID */ @@ -629,7 +633,7 @@ PyObject* KX_ObjectActuator::PySetPID(PyObject* self, return NULL; } m_torque.setValue(vecArg); - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index aa686f41233..0331c67617c 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -153,7 +153,7 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce); KX_PYMETHOD(KX_ObjectActuator,SetForce); diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 89549ca6b57..84d7ccb9c05 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -166,15 +166,48 @@ PyParentObject KX_ParentActuator::Parents[] = { }; PyMethodDef KX_ParentActuator::Methods[] = { + // ---> deprecated (all) {"setObject", (PyCFunction) KX_ParentActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, {"getObject", (PyCFunction) KX_ParentActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, {NULL,NULL} //Sentinel }; -PyObject* KX_ParentActuator::_getattr(const STR_String& attr) { +PyAttributeDef KX_ParentActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_ParentActuator::_getattr(const char *attr) { + + if (!strcmp(attr, "object")) { + if (!m_ob) Py_RETURN_NONE; + else return m_ob->AddRef(); + } + _getattr_up(SCA_IActuator); } +int KX_ParentActuator::_setattr(const char *attr, PyObject* value) { + + if (!strcmp(attr, "object")) { + KX_GameObject *gameobj; + + if (!ConvertPythonToGameObject(value, &gameobj, true)) + return 1; // ConvertPythonToGameObject sets the error + + if (m_ob != NULL) + m_ob->UnregisterActuator(this); + + m_ob = (SCA_IObject*)gameobj; + + if (m_ob) + m_ob->RegisterActuator(this); + + return 0; + } + + return SCA_IActuator::_setattr(attr, value); +} + /* 1. setObject */ const char KX_ParentActuator::SetObject_doc[] = "setObject(object)\n" @@ -183,6 +216,8 @@ const char KX_ParentActuator::SetObject_doc[] = PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* value) { KX_GameObject *gameobj; + ShowDeprecationWarning("setObject()", "the object property"); + if (!ConvertPythonToGameObject(value, &gameobj, true)) return NULL; // ConvertPythonToGameObject sets the error @@ -206,6 +241,9 @@ const char KX_ParentActuator::GetObject_doc[] = PyObject* KX_ParentActuator::PyGetObject(PyObject* self, PyObject* args) { int ret_name_only = 1; + + ShowDeprecationWarning("getObject()", "the object property"); + if (!PyArg_ParseTuple(args, "|i", &ret_name_only)) return NULL; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index e2b30ba2d0f..c974001c0d0 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -76,7 +76,8 @@ class KX_ParentActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); /* 1. setObject */ KX_PYMETHOD_DOC_O(KX_ParentActuator,SetObject); diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp index da4f05ced7c..246c63feb21 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp @@ -142,23 +142,21 @@ PyParentObject KX_PhysicsObjectWrapper::Parents[] = { NULL }; -PyObject* KX_PhysicsObjectWrapper::_getattr(const STR_String& attr) +PyObject* KX_PhysicsObjectWrapper::_getattr(const char *attr) { _getattr_up(PyObjectPlus); } -int KX_PhysicsObjectWrapper::_setattr(const STR_String& attr,PyObject* pyobj) +int KX_PhysicsObjectWrapper::_setattr(const char *attr,PyObject *pyobj) { - PyTypeObject* type = pyobj->ob_type; int result = 1; - - if (type == &PyInt_Type) + if (PyInt_Check(pyobj)) { result = 0; } - if (type == &PyString_Type) + if (PyString_Check(pyobj)) { result = 0; } diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h index 3dbd1be9323..95560698896 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -36,8 +36,8 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); public: KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); virtual ~KX_PhysicsObjectWrapper(); diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index bb9072b34dc..b4bdd77fb66 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -77,18 +77,21 @@ PyMethodDef KX_PolyProxy::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* -KX_PolyProxy::_getattr(const STR_String& attr) +PyAttributeDef KX_PolyProxy::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_PolyProxy::_getattr(const char *attr) { - if (attr == "matname") + if (!strcmp(attr, "matname")) { return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); } - if (attr == "texture") + if (!strcmp(attr, "texture")) { return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); } - if (attr == "material") + if (!strcmp(attr, "material")) { RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial(); if(polymat->GetFlag() & RAS_BLENDERMAT) @@ -104,7 +107,7 @@ KX_PolyProxy::_getattr(const STR_String& attr) return mat; } } - if (attr == "matid") + if (!strcmp(attr, "matid")) { // we'll have to scan through the material bucket of the mes and compare with // the one of the polygon @@ -119,27 +122,27 @@ KX_PolyProxy::_getattr(const STR_String& attr) } return PyInt_FromLong(matid); } - if (attr == "v1") + if (!strcmp(attr, "v1")) { return PyInt_FromLong(m_polygon->GetVertexOffset(0)); } - if (attr == "v2") + if (!strcmp(attr, "v2")) { return PyInt_FromLong(m_polygon->GetVertexOffset(1)); } - if (attr == "v3") + if (!strcmp(attr, "v3")) { return PyInt_FromLong(m_polygon->GetVertexOffset(2)); } - if (attr == "v4") + if (!strcmp(attr, "v4")) { return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0)); } - if (attr == "visible") + if (!strcmp(attr, "visible")) { return PyInt_FromLong(m_polygon->IsVisible()); } - if (attr == "collide") + if (!strcmp(attr, "collide")) { return PyInt_FromLong(m_polygon->IsCollider()); } @@ -147,8 +150,8 @@ KX_PolyProxy::_getattr(const STR_String& attr) } KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon) -: m_mesh((RAS_MeshObject*)mesh), - m_polygon(polygon) +: m_polygon(polygon), + m_mesh((RAS_MeshObject*)mesh) { } diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index 506e2c2a656..9b548f9490d 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -53,7 +53,7 @@ public: // stuff for python integration - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialIndex) KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getNumVertex) diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index c9180bf3a80..bbaf697b168 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -180,6 +180,9 @@ PyMethodDef KX_PolygonMaterial::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef KX_PolygonMaterial::Attributes[] = { + { NULL } //Sentinel +}; PyTypeObject KX_PolygonMaterial::Type = { PyObject_HEAD_INIT(&PyType_Type) @@ -202,17 +205,17 @@ PyParentObject KX_PolygonMaterial::Parents[] = { NULL }; -PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr) +PyObject* KX_PolygonMaterial::_getattr(const char *attr) { - if (attr == "texture") + if (!strcmp(attr, "texture")) return PyString_FromString(m_texturename.ReadPtr()); - if (attr == "material") + if (!strcmp(attr, "material")) return PyString_FromString(m_materialname.ReadPtr()); - if (attr == "tface") + if (!strcmp(attr, "tface")) return PyCObject_FromVoidPtr(m_tface, NULL); - if (attr == "gl_texture") + if (!strcmp(attr, "gl_texture")) { Image *ima = m_tface->tpage; int bind = 0; @@ -222,49 +225,49 @@ PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr) return PyInt_FromLong(bind); } - if (attr == "tile") + if (!strcmp(attr, "tile")) return PyInt_FromLong(m_tile); - if (attr == "tilexrep") + if (!strcmp(attr, "tilexrep")) return PyInt_FromLong(m_tilexrep); - if (attr == "tileyrep") + if (!strcmp(attr, "tileyrep")) return PyInt_FromLong(m_tileyrep); - if (attr == "drawingmode") + if (!strcmp(attr, "drawingmode")) return PyInt_FromLong(m_drawingmode); - if (attr == "transparent") + if (!strcmp(attr, "transparent")) return PyInt_FromLong(m_alpha); - if (attr == "zsort") + if (!strcmp(attr, "zsort")) return PyInt_FromLong(m_zsort); - if (attr == "lightlayer") + if (!strcmp(attr, "lightlayer")) return PyInt_FromLong(m_lightlayer); - if (attr == "triangle") + if (!strcmp(attr, "triangle")) // deprecated, triangle/quads shouldn't have been a material property return 0; - if (attr == "diffuse") + if (!strcmp(attr, "diffuse")) return PyObjectFrom(m_diffuse); - if (attr == "shininess") + if (!strcmp(attr, "shininess")) return PyFloat_FromDouble(m_shininess); - if (attr == "specular") + if (!strcmp(attr, "specular")) return PyObjectFrom(m_specular); - if (attr == "specularity") + if (!strcmp(attr, "specularity")) return PyFloat_FromDouble(m_specularity); _getattr_up(PyObjectPlus); } -int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue) +int KX_PolygonMaterial::_setattr(const char *attr, PyObject *pyvalue) { if (PyFloat_Check(pyvalue)) { float value = PyFloat_AsDouble(pyvalue); - if (attr == "shininess") + if (!strcmp(attr, "shininess")) { m_shininess = value; return 0; } - if (attr == "specularity") + if (!strcmp(attr, "specularity")) { m_specularity = value; return 0; @@ -274,50 +277,50 @@ int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue) if (PyInt_Check(pyvalue)) { int value = PyInt_AsLong(pyvalue); - if (attr == "tile") + if (!strcmp(attr, "tile")) { m_tile = value; return 0; } - if (attr == "tilexrep") + if (!strcmp(attr, "tilexrep")) { m_tilexrep = value; return 0; } - if (attr == "tileyrep") + if (!strcmp(attr, "tileyrep")) { m_tileyrep = value; return 0; } - if (attr == "drawingmode") + if (!strcmp(attr, "drawingmode")) { m_drawingmode = value; return 0; } - if (attr == "transparent") + if (!strcmp(attr, "transparent")) { m_alpha = value; return 0; } - if (attr == "zsort") + if (!strcmp(attr, "zsort")) { m_zsort = value; return 0; } - if (attr == "lightlayer") + if (!strcmp(attr, "lightlayer")) { m_lightlayer = value; return 0; } // This probably won't work... - if (attr == "triangle") + if (!strcmp(attr, "triangle")) { // deprecated, triangle/quads shouldn't have been a material property return 0; @@ -331,13 +334,13 @@ int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue) MT_Vector3 value; if (PyVecTo(pyvalue, value)) { - if (attr == "diffuse") + if (!strcmp(attr, "diffuse")) { m_diffuse = value; return 0; } - if (attr == "specular") + if (!strcmp(attr, "specular")) { m_specular = value; return 0; @@ -354,12 +357,12 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(mat PyObject *material; if (PyArg_ParseTuple(args, "O", &material)) { - if (m_pymaterial) + if (m_pymaterial) { Py_DECREF(m_pymaterial); - + } m_pymaterial = material; Py_INCREF(m_pymaterial); - Py_Return; + Py_RETURN_NONE; } return NULL; @@ -375,7 +378,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, updateTexture, "updateTexture(tface, rast Image *ima = (Image*)tface->tpage; GPU_update_image_time(ima, rasty->GetTime()); - Py_Return; + Py_RETURN_NONE; } return NULL; @@ -388,7 +391,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)") { MTFace *tface = (MTFace*) PyCObject_AsVoidPtr(pytface); GPU_set_tpage(tface); - Py_Return; + Py_RETURN_NONE; } return NULL; @@ -404,7 +407,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)") if (rasty && cachingInfo) { DefaultActivate(rasty, *cachingInfo); - Py_Return; + Py_RETURN_NONE; } } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index fe116f757db..a3ef4ca51ef 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -115,8 +115,8 @@ public: KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial); KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram); - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *pyvalue); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *pyvalue); }; #endif // __KX_POLYGONMATERIAL_H__ diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index afb20acec2d..92f18590a7e 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -77,35 +77,92 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank) PyObject* PyObjectFrom(const MT_Matrix4x4 &mat) { +#if 0 return Py_BuildValue("[[ffff][ffff][ffff][ffff]]", mat[0][0], mat[0][1], mat[0][2], mat[0][3], mat[1][0], mat[1][1], mat[1][2], mat[1][3], mat[2][0], mat[2][1], mat[2][2], mat[2][3], mat[3][0], mat[3][1], mat[3][2], mat[3][3]); +#else + PyObject *list = PyList_New(4); + PyObject *sublist; + int i; + + for(i=0; i < 4; i++) { + sublist = PyList_New(4); + PyList_SET_ITEM(sublist, 0, PyFloat_FromDouble(mat[i][0])); + PyList_SET_ITEM(sublist, 1, PyFloat_FromDouble(mat[i][1])); + PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][2])); + PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][3])); + PyList_SET_ITEM(list, i, sublist); + } + + return list; +#endif } PyObject* PyObjectFrom(const MT_Matrix3x3 &mat) { +#if 0 return Py_BuildValue("[[fff][fff][fff]]", mat[0][0], mat[0][1], mat[0][2], mat[1][0], mat[1][1], mat[1][2], mat[2][0], mat[2][1], mat[2][2]); +#else + PyObject *list = PyList_New(3); + PyObject *sublist; + int i; + + for(i=0; i < 3; i++) { + sublist = PyList_New(3); + PyList_SET_ITEM(sublist, 0, PyFloat_FromDouble(mat[i][0])); + PyList_SET_ITEM(sublist, 1, PyFloat_FromDouble(mat[i][1])); + PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][2])); + PyList_SET_ITEM(list, i, sublist); + } + + return list; +#endif } PyObject* PyObjectFrom(const MT_Tuple4 &vec) { +#if 0 return Py_BuildValue("[ffff]", vec[0], vec[1], vec[2], vec[3]); +#else + PyObject *list = PyList_New(4); + PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); + PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1])); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(vec[2])); + PyList_SET_ITEM(list, 3, PyFloat_FromDouble(vec[3])); + return list; +#endif } PyObject* PyObjectFrom(const MT_Tuple3 &vec) { +#if 0 return Py_BuildValue("[fff]", vec[0], vec[1], vec[2]); +#else + PyObject *list = PyList_New(3); + PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); + PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1])); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(vec[2])); + return list; +#endif } PyObject* PyObjectFrom(const MT_Tuple2 &vec) { +#if 0 return Py_BuildValue("[ff]", vec[0], vec[1]); +#else + PyObject *list = PyList_New(2); + PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0])); + PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1])); + return list; +#endif } diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index 4e383e9b3d4..39c9c358792 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -131,20 +131,6 @@ bool PyVecTo(PyObject* pyval, T& vec) } /** - * Converts a python argument to an MT class. - * This paramater expects arguments as passed to a python method. - */ -template<class T> -bool PyVecArgTo(PyObject* args, T& vec) -{ - PyObject* pylist; - if (PyArg_ParseTuple(args,"O",&pylist)) - return PyVecTo(pylist, vec); - - return false; -} - -/** * Converts an MT_Matrix4x4 to a python object. */ PyObject* PyObjectFrom(const MT_Matrix4x4 &mat); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 60921449037..965c4ed2ba3 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -47,6 +47,7 @@ #include "KX_PyConstraintBinding.h" #include "KX_KetsjiEngine.h" +#include "KX_RadarSensor.h" #include "SCA_IInputDevice.h" #include "SCA_PropertySensor.h" @@ -128,10 +129,10 @@ static PyObject* gPyGetRandomFloat(PyObject*) return PyFloat_FromDouble(MT_random()); } -static PyObject* gPySetGravity(PyObject*, PyObject* args) +static PyObject* gPySetGravity(PyObject*, PyObject* value) { - MT_Vector3 vec = MT_Vector3(0., 0., 0.); - if (!PyVecArgTo(args, vec)) + MT_Vector3 vec; + if (!PyVecTo(value, vec)) return NULL; if (gp_KetsjiScene) @@ -199,7 +200,7 @@ static PyObject* gPyGetSpectrum(PyObject*) } - +#if 0 // unused static PyObject* gPyStartDSP(PyObject*, PyObject* args) { SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance(); @@ -216,7 +217,7 @@ static PyObject* gPyStartDSP(PyObject*, PyObject* args) Py_RETURN_NONE; } - +#endif static PyObject* gPyStopDSP(PyObject*, PyObject* args) @@ -260,7 +261,7 @@ static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args) PHY_GetActiveEnvironment()->setFixedTimeStep(true,ticrate); Py_RETURN_NONE; } - +#if 0 // unused static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args) { int debugMode; @@ -270,7 +271,7 @@ static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args) PHY_GetActiveEnvironment()->setDebugMode(debugMode); Py_RETURN_NONE; } - +#endif static PyObject* gPyGetPhysicsTicRate(PyObject*) @@ -332,6 +333,32 @@ static PyObject* gPyGetCurrentScene(PyObject* self) return (PyObject*) gp_KetsjiScene; } +static STR_String gPyGetSceneList_doc = +"getSceneList()\n" +"Return a list of converted scenes.\n"; +static PyObject* gPyGetSceneList(PyObject* self) +{ + KX_KetsjiEngine* m_engine = KX_GetActiveEngine(); + //CListValue* list = new CListValue(); + PyObject* list; + KX_SceneList* scenes = m_engine->CurrentScenes(); + int numScenes = scenes->size(); + int i; + + list = PyList_New(numScenes); + + for (i=0;i<numScenes;i++) + { + KX_Scene* scene = scenes->at(i); + //list->Add(scene); + PyList_SET_ITEM(list, i, scene); + Py_INCREF(scene); + + } + + return (PyObject*)list; +} + static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) { #define pprint(x) std::cout << x << std::endl; @@ -411,11 +438,13 @@ static struct PyMethodDef game_methods[] = { METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::sPyGetCurrentController__doc__}, {"getCurrentScene", (PyCFunction) gPyGetCurrentScene, METH_NOARGS, (PY_METHODCHAR)gPyGetCurrentScene_doc.Ptr()}, + {"getSceneList", (PyCFunction) gPyGetSceneList, + METH_NOARGS, (PY_METHODCHAR)gPyGetSceneList_doc.Ptr()}, {"addActiveActuator",(PyCFunction) SCA_PythonController::sPyAddActiveActuator, METH_VARARGS, (PY_METHODCHAR)SCA_PythonController::sPyAddActiveActuator__doc__}, {"getRandomFloat",(PyCFunction) gPyGetRandomFloat, METH_NOARGS, (PY_METHODCHAR)gPyGetRandomFloat_doc.Ptr()}, - {"setGravity",(PyCFunction) gPySetGravity, METH_VARARGS, (PY_METHODCHAR)"set Gravitation"}, + {"setGravity",(PyCFunction) gPySetGravity, METH_O, (PY_METHODCHAR)"set Gravitation"}, {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS, (PY_METHODCHAR)"get audio spectrum"}, {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (PY_METHODCHAR)"stop using the audio dsp (for performance reasons)"}, {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the logic tic rate"}, @@ -545,11 +574,11 @@ static PyObject* gPyGetFocalLength(PyObject*, PyObject*, PyObject*) Py_RETURN_NONE; } -static PyObject* gPySetBackgroundColor(PyObject*, PyObject* args) +static PyObject* gPySetBackgroundColor(PyObject*, PyObject* value) { - MT_Vector4 vec = MT_Vector4(0., 0., 0.3, 0.); - if (!PyVecArgTo(args, vec)) + MT_Vector4 vec; + if (!PyVecTo(value, vec)) return NULL; if (gp_Canvas) @@ -561,11 +590,11 @@ static PyObject* gPySetBackgroundColor(PyObject*, PyObject* args) -static PyObject* gPySetMistColor(PyObject*, PyObject* args) +static PyObject* gPySetMistColor(PyObject*, PyObject* value) { - MT_Vector3 vec = MT_Vector3(0., 0., 0.); - if (!PyVecArgTo(args, vec)) + MT_Vector3 vec; + if (!PyVecTo(value, vec)) return NULL; if (!gp_Rasterizer) { @@ -616,11 +645,11 @@ static PyObject* gPySetMistEnd(PyObject*, PyObject* args) } -static PyObject* gPySetAmbientColor(PyObject*, PyObject* args) +static PyObject* gPySetAmbientColor(PyObject*, PyObject* value) { - MT_Vector3 vec = MT_Vector3(0., 0., 0.); - if (!PyVecArgTo(args, vec)) + MT_Vector3 vec; + if (!PyVecTo(value, vec)) return NULL; if (!gp_Rasterizer) { @@ -815,9 +844,9 @@ static PyObject* gPyDrawLine(PyObject*, PyObject* args) if (!PyArg_ParseTuple(args,"OOO",&ob_from,&ob_to,&ob_color)) return NULL; - MT_Vector3 from(0., 0., 0.); - MT_Vector3 to(0., 0., 0.); - MT_Vector3 color(0., 0., 0.); + MT_Vector3 from; + MT_Vector3 to; + MT_Vector3 color; if (!PyVecTo(ob_from, from)) return NULL; if (!PyVecTo(ob_to, to)) @@ -843,9 +872,9 @@ static struct PyMethodDef rasterizer_methods[] = { METH_VARARGS, "showMouse(bool visible)"}, {"setMousePosition",(PyCFunction) gPySetMousePosition, METH_VARARGS, "setMousePosition(int x,int y)"}, - {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_VARARGS,"set Background Color (rgb)"}, - {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_VARARGS,"set Ambient Color (rgb)"}, - {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"}, + {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"}, + {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"}, + {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"}, {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"}, @@ -1035,6 +1064,14 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack KX_MACRO_addTypesToDict(d, KX_STATE29, (1<<28)); KX_MACRO_addTypesToDict(d, KX_STATE30, (1<<29)); + /* Radar Sensor */ + KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_X, KX_RadarSensor::KX_RADAR_AXIS_POS_X); + KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_Y, KX_RadarSensor::KX_RADAR_AXIS_POS_Y); + KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_Z, KX_RadarSensor::KX_RADAR_AXIS_POS_Z); + KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_X, KX_RadarSensor::KX_RADAR_AXIS_NEG_Y); + KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Y, KX_RadarSensor::KX_RADAR_AXIS_NEG_X); + KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Z, KX_RadarSensor::KX_RADAR_AXIS_NEG_Z); + // Check for errors if (PyErr_Occurred()) { diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp index 244e9b75d8e..fa8998cd81d 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.cpp +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -28,6 +28,7 @@ #include "KX_RadarSensor.h" #include "KX_GameObject.h" +#include "KX_PyMath.h" #include "PHY_IPhysicsController.h" #ifdef HAVE_CONFIG_H @@ -170,8 +171,18 @@ void KX_RadarSensor::SynchronizeTransform() { } } - m_cone_origin = trans.getOrigin(); - m_cone_target = trans(MT_Point3(0, -m_coneheight/2.0 ,0)); + + //Using a temp variable to translate MT_Point3 to float[3]. + //float[3] works better for the Python interface. + MT_Point3 temp = trans.getOrigin(); + m_cone_origin[0] = temp[0]; + m_cone_origin[1] = temp[1]; + m_cone_origin[2] = temp[2]; + + temp = trans(MT_Point3(0, -m_coneheight/2.0 ,0)); + m_cone_target[0] = temp[0]; + m_cone_target[1] = temp[1]; + m_cone_target[2] = temp[2]; if (m_physCtrl) @@ -186,10 +197,58 @@ void KX_RadarSensor::SynchronizeTransform() } /* ------------------------------------------------------------------------- */ -/* Python functions */ +/* Python Functions */ /* ------------------------------------------------------------------------- */ -/* Integration hooks ------------------------------------------------------- */ +//Deprecated -----> +/* getConeOrigin */ +const char KX_RadarSensor::GetConeOrigin_doc[] = +"getConeOrigin()\n" +"\tReturns the origin of the cone with which to test. The origin\n" +"\tis in the middle of the cone."; +PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self) { + ShowDeprecationWarning("getConeOrigin()", "the coneOrigin property"); + + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2])); + + return retVal; +} + +/* getConeOrigin */ +const char KX_RadarSensor::GetConeTarget_doc[] = +"getConeTarget()\n" +"\tReturns the center of the bottom face of the cone with which to test.\n"; +PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self) { + ShowDeprecationWarning("getConeTarget()", "the coneTarget property"); + + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2])); + + return retVal; +} + +/* getConeHeight */ +const char KX_RadarSensor::GetConeHeight_doc[] = +"getConeHeight()\n" +"\tReturns the height of the cone with which to test.\n"; +PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self) { + + ShowDeprecationWarning("getConeHeight()", "the distance property"); + + return PyFloat_FromDouble(m_coneheight); +} +//<----- Deprecated + +/* ------------------------------------------------------------------------- */ +/* Python Integration Hooks */ +/* ------------------------------------------------------------------------- */ PyTypeObject KX_RadarSensor::Type = { PyObject_HEAD_INIT(&PyType_Type) 0, @@ -220,60 +279,39 @@ PyParentObject KX_RadarSensor::Parents[] = { }; PyMethodDef KX_RadarSensor::Methods[] = { + //Deprecated -----> {"getConeOrigin", (PyCFunction) KX_RadarSensor::sPyGetConeOrigin, METH_VARARGS, (PY_METHODCHAR)GetConeOrigin_doc}, {"getConeTarget", (PyCFunction) KX_RadarSensor::sPyGetConeTarget, METH_VARARGS, (PY_METHODCHAR)GetConeTarget_doc}, {"getConeHeight", (PyCFunction) KX_RadarSensor::sPyGetConeHeight, METH_VARARGS, (PY_METHODCHAR)GetConeHeight_doc}, - {NULL,NULL,NULL,NULL} //Sentinel + //<----- + {NULL} //Sentinel }; -PyObject* KX_RadarSensor::_getattr(const STR_String& attr) { - _getattr_up(KX_TouchSensor); -} - -/* getConeOrigin */ -const char KX_RadarSensor::GetConeOrigin_doc[] = -"getConeOrigin()\n" -"\tReturns the origin of the cone with which to test. The origin\n" -"\tis in the middle of the cone."; -PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self, - PyObject* args, - PyObject* kwds) { - PyObject *retVal = PyList_New(3); - - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2])); - - return retVal; -} +PyAttributeDef KX_RadarSensor::Attributes[] = { + KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneOrigin", KX_RadarSensor, m_cone_origin, 3), + KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneTarget", KX_RadarSensor, m_cone_target, 3), + KX_PYATTRIBUTE_FLOAT_RW("angle", 0, 360, KX_RadarSensor, m_coneradius), + KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RadarSensor, m_axis), + {NULL} //Sentinel +}; -/* getConeOrigin */ -const char KX_RadarSensor::GetConeTarget_doc[] = -"getConeTarget()\n" -"\tReturns the center of the bottom face of the cone with which to test.\n"; -PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self, - PyObject* args, - PyObject* kwds) { - PyObject *retVal = PyList_New(3); - - PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0])); - PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1])); - PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2])); - - return retVal; -} +PyObject* KX_RadarSensor::_getattr(const char *attr) +{ + PyObject* object = _getattr_self(Attributes, this, attr); + if (object != NULL) + return object; -/* getConeOrigin */ -const char KX_RadarSensor::GetConeHeight_doc[] = -"getConeHeight()\n" -"\tReturns the height of the cone with which to test.\n"; -PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self, - PyObject* args, - PyObject* kwds) { - return PyFloat_FromDouble(m_coneheight); + _getattr_up(KX_NearSensor); } +int KX_RadarSensor::_setattr(const char *attr, PyObject* value) +{ + int ret = _setattr_self(Attributes, this, attr, value); + if (ret >= 0) + return ret; + return KX_NearSensor::_setattr(attr, value); +} diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 7272b219e37..6dfe0c42f5d 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -40,23 +40,23 @@ class KX_RadarSensor : public KX_NearSensor protected: Py_Header; - MT_Scalar m_coneradius; + float m_coneradius; /** * Height of the cone. */ - MT_Scalar m_coneheight; + float m_coneheight; int m_axis; /** * The previous position of the origin of the cone. */ - MT_Point3 m_cone_origin; + float m_cone_origin[3]; /** * The previous direction of the cone (origin to bottom plane). */ - MT_Point3 m_cone_target; + float m_cone_target[3]; public: @@ -80,13 +80,23 @@ public: /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - - virtual PyObject* _getattr(const STR_String& attr); + enum RadarAxis { + KX_RADAR_AXIS_POS_X = 0, + KX_RADAR_AXIS_POS_Y, + KX_RADAR_AXIS_POS_Z, + KX_RADAR_AXIS_NEG_X, + KX_RADAR_AXIS_NEG_Y, + KX_RADAR_AXIS_NEG_Z + }; - KX_PYMETHOD_DOC(KX_RadarSensor,GetConeOrigin); - KX_PYMETHOD_DOC(KX_RadarSensor,GetConeTarget); - KX_PYMETHOD_DOC(KX_RadarSensor,GetConeHeight); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); + //Deprecated -----> + KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin); + KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeTarget); + KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeHeight); + //<----- }; #endif //__KX_RADAR_SENSOR_H diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index e24fb773eac..ce12b983147 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -38,6 +38,7 @@ #include "KX_GameObject.h" #include "KX_Scene.h" #include "KX_RayCast.h" +#include "KX_PyMath.h" #include "PHY_IPhysicsEnvironment.h" #include "KX_IPhysicsController.h" #include "PHY_IPhysicsController.h" @@ -179,8 +180,8 @@ bool KX_RaySensor::Evaluate(CValue* event) bool reset = m_reset && m_level; m_rayHit = false; m_hitObject = NULL; - m_hitPosition = MT_Vector3(0,0,0); - m_hitNormal = MT_Vector3(1,0,0); + m_hitPosition.setValue(0,0,0); + m_hitNormal.setValue(1,0,0); KX_GameObject* obj = (KX_GameObject*)GetParent(); MT_Point3 frompoint = obj->NodeGetWorldPosition(); @@ -335,89 +336,56 @@ PyParentObject KX_RaySensor::Parents[] = { }; PyMethodDef KX_RaySensor::Methods[] = { - {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc}, - {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, (PY_METHODCHAR)GetHitPosition_doc}, - {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, (PY_METHODCHAR)GetHitNormal_doc}, - {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_VARARGS, (PY_METHODCHAR)GetRayDirection_doc}, + {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc}, + {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_NOARGS, (PY_METHODCHAR)GetHitPosition_doc}, + {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_NOARGS, (PY_METHODCHAR)GetHitNormal_doc}, + {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_NOARGS, (PY_METHODCHAR)GetRayDirection_doc}, {NULL,NULL} //Sentinel }; +PyAttributeDef KX_RaySensor::Attributes[] = { + { NULL } //Sentinel +}; + const char KX_RaySensor::GetHitObject_doc[] = "getHitObject()\n" "\tReturns the name of the object that was hit by this ray.\n"; -PyObject* KX_RaySensor::PyGetHitObject(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_RaySensor::PyGetHitObject(PyObject* self) { if (m_hitObject) { return m_hitObject->AddRef(); } - Py_Return; + Py_RETURN_NONE; } const char KX_RaySensor::GetHitPosition_doc[] = "getHitPosition()\n" "\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n"; -PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self) { - - MT_Point3 pos = m_hitPosition; - - PyObject* resultlist = PyList_New(3); - int index; - for (index=0;index<3;index++) - { - PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); - } - return resultlist; - + return PyObjectFrom(m_hitPosition); } const char KX_RaySensor::GetRayDirection_doc[] = "getRayDirection()\n" "\tReturns the direction from the ray (in worldcoordinates) .\n"; -PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self) { - - MT_Vector3 dir = m_rayDirection; - - PyObject* resultlist = PyList_New(3); - int index; - for (index=0;index<3;index++) - { - PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index])); - } - return resultlist; - + return PyObjectFrom(m_rayDirection); } const char KX_RaySensor::GetHitNormal_doc[] = "getHitNormal()\n" "\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n"; -PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self) { - MT_Vector3 pos = m_hitNormal; - - PyObject* resultlist = PyList_New(3); - int index; - for (index=0;index<3;index++) - { - PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); - } - return resultlist; - + return PyObjectFrom(m_hitNormal); } -PyObject* KX_RaySensor::_getattr(const STR_String& attr) { +PyObject* KX_RaySensor::_getattr(const char *attr) { _getattr_up(SCA_ISensor); } diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 02a755fedc1..09d8bc1369a 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -74,12 +74,12 @@ public: bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); bool NeedRayCast(KX_ClientObjectInfo* client); - KX_PYMETHOD_DOC(KX_RaySensor,GetHitObject); - KX_PYMETHOD_DOC(KX_RaySensor,GetHitPosition); - KX_PYMETHOD_DOC(KX_RaySensor,GetHitNormal); - KX_PYMETHOD_DOC(KX_RaySensor,GetRayDirection); + KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitObject); + KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitPosition); + KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitNormal); + KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetRayDirection); - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); }; diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 5777f54b799..68b704f4889 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -188,9 +188,7 @@ PyParentObject KX_SCA_AddObjectActuator::Parents[] = { NULL }; PyMethodDef KX_SCA_AddObjectActuator::Methods[] = { - {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, (PY_METHODCHAR)SetTime_doc}, - {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_NOARGS, (PY_METHODCHAR)GetTime_doc}, {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_NOARGS, (PY_METHODCHAR)GetLinearVelocity_doc}, {"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, (PY_METHODCHAR)SetLinearVelocity_doc}, @@ -199,15 +197,52 @@ PyMethodDef KX_SCA_AddObjectActuator::Methods[] = { {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_NOARGS,"getLastCreatedObject() : get the object handle to the last created object\n"}, {"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_NOARGS,"instantAddObject() : immediately add object without delay\n"}, + // ---> deprecated + {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, + {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, + {NULL,NULL} //Sentinel }; +PyAttributeDef KX_SCA_AddObjectActuator::Attributes[] = { + { NULL } //Sentinel +}; -PyObject* KX_SCA_AddObjectActuator::_getattr(const STR_String& attr) +PyObject* KX_SCA_AddObjectActuator::_getattr(const char *attr) { + if (!strcmp(attr, "object")) { + if (!m_OriginalObject) Py_RETURN_NONE; + else return m_OriginalObject->AddRef(); + } else if (!strcmp(attr, "objectLastCreated")) { + if (!m_OriginalObject) Py_RETURN_NONE; + else return m_lastCreatedObject->AddRef(); + } + _getattr_up(SCA_IActuator); } +int KX_SCA_AddObjectActuator::_setattr(const char *attr, PyObject* value) { + + if (!strcmp(attr, "object")) { + KX_GameObject *gameobj; + + if (!ConvertPythonToGameObject(value, &gameobj, true)) + return 1; // ConvertPythonToGameObject sets the error + + if (m_OriginalObject != NULL) + m_OriginalObject->UnregisterActuator(this); + + m_OriginalObject = (SCA_IObject*)gameobj; + + if (m_OriginalObject) + m_OriginalObject->RegisterActuator(this); + + return 0; + } + + return SCA_IActuator::_setattr(attr, value); +} + /* 1. setObject */ const char KX_SCA_AddObjectActuator::SetObject_doc[] = "setObject(object)\n" @@ -218,6 +253,8 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self, PyObject* value) { KX_GameObject *gameobj; + ShowDeprecationWarning("setObject()", "the object property"); + if (!ConvertPythonToGameObject(value, &gameobj, true)) return NULL; // ConvertPythonToGameObject sets the error @@ -277,6 +314,9 @@ const char KX_SCA_AddObjectActuator::GetObject_doc[] = PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, PyObject* args) { int ret_name_only = 1; + + ShowDeprecationWarning("getObject()", "the object property"); + if (!PyArg_ParseTuple(args, "|i", &ret_name_only)) return NULL; diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 278d4180284..18298cbcb0c 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -60,13 +60,16 @@ class KX_SCA_AddObjectActuator : public SCA_IActuator /// Linear velocity upon creation of the object. MT_Vector3 m_linear_velocity; + /// Apply the velocity locally + bool m_localLinvFlag; /// Angular velocity upon creation of the object. MT_Vector3 m_angular_velocity; - /// Apply the velocity locally - bool m_localLinvFlag; - bool m_localAngvFlag; + bool m_localAngvFlag; + + + SCA_IObject* m_lastCreatedObject; @@ -107,10 +110,8 @@ public: virtual bool Update(); - virtual PyObject* - _getattr( - const STR_String& attr - ); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); SCA_IObject* GetLastCreatedObject( diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp index 176ccf1a84a..394bb667728 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp @@ -85,9 +85,12 @@ PyMethodDef KX_SCA_DynamicActuator::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = { + { NULL } //Sentinel +}; -PyObject* KX_SCA_DynamicActuator::_getattr(const STR_String& attr) +PyObject* KX_SCA_DynamicActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -115,7 +118,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation, return NULL; } m_dyn_operation= dyn_operation; - Py_Return; + Py_RETURN_NONE; } KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation, diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h index de2fab68d15..a82cddd66a7 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h @@ -64,10 +64,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator virtual bool Update(); - virtual PyObject* - _getattr( - const STR_String& attr - ); + virtual PyObject* _getattr(const char *attr); /* 1. setOperation */ KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,setOperation); diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp index ec29448907f..9268a1df5f0 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -127,8 +127,11 @@ PyMethodDef KX_SCA_EndObjectActuator::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef KX_SCA_EndObjectActuator::Attributes[] = { + { NULL } //Sentinel +}; -PyObject* KX_SCA_EndObjectActuator::_getattr(const STR_String& attr) +PyObject* KX_SCA_EndObjectActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h index add9c05b000..12118743f0a 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h @@ -64,10 +64,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* - _getattr( - const STR_String& attr - ); + virtual PyObject* _getattr(const char *attr); }; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 261d9ec8f0c..502990b2b27 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -89,9 +89,11 @@ PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef KX_SCA_ReplaceMeshActuator::Attributes[] = { + { NULL } //Sentinel +}; - -PyObject* KX_SCA_ReplaceMeshActuator::_getattr(const STR_String& attr) +PyObject* KX_SCA_ReplaceMeshActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 1da154cc222..0ba60650683 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -69,10 +69,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator virtual bool Update(); - virtual PyObject* - _getattr( - const STR_String& attr - ); + virtual PyObject* _getattr(const char *attr); void InstantReplaceMesh(); /* 1. setMesh */ diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp index d651373869a..151270cbd68 100644 --- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp +++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp @@ -97,11 +97,11 @@ UpdateChildCoordinates( child_transform = parent_matrix * child_transform; // Recompute the child transform components from the transform. - child_w_scale = MT_Vector3( + child_w_scale.setValue( MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(), MT_Vector3(child_transform[1][0], child_transform[1][1], child_transform[1][2]).length(), MT_Vector3(child_transform[2][0], child_transform[2][1], child_transform[2][2]).length()); - child_w_rotation = MT_Matrix3x3(child_transform[0][0], child_transform[0][1], child_transform[0][2], + child_w_rotation.setValue(child_transform[0][0], child_transform[0][1], child_transform[0][2], child_transform[1][0], child_transform[1][1], child_transform[1][2], child_transform[2][0], child_transform[2][1], child_transform[2][2]); child_w_rotation.scale(1.0/child_w_scale[0], 1.0/child_w_scale[1], 1.0/child_w_scale[2]); @@ -113,16 +113,15 @@ UpdateChildCoordinates( } } - if (!valid_parent_transform) + if (valid_parent_transform) { - child_w_scale = child_scale; - child_w_pos = child_pos; - child_w_rotation = child_rotation; + child->SetWorldScale(child_w_scale); + child->SetWorldPosition(child_w_pos); + child->SetWorldOrientation(child_w_rotation); + } + else { + child->SetWorldFromLocalTransform(); } - - child->SetWorldScale(child_w_scale); - child->SetWorldPosition(child_w_pos); - child->SetWorldOrientation(child_w_rotation); return valid_parent_transform; } diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp index 0c8e7e28771..0729ec8a902 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp @@ -55,43 +55,21 @@ UpdateChildCoordinates( ){ MT_assert(child != NULL); - // This way of accessing child coordinates is a bit cumbersome - // be nice to have non constant reference access to these values. - - const MT_Vector3 & child_scale = child->GetLocalScale(); - const MT_Point3 & child_pos = child->GetLocalPosition(); - const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); - - // the childs world locations which we will update. - - MT_Vector3 child_w_scale; - MT_Point3 child_w_pos; - MT_Matrix3x3 child_w_rotation; - - if (parent) { - + if (parent==NULL) { /* Simple case */ + child->SetWorldFromLocalTransform(); + return false; + } + else { + // the childs world locations which we will update. const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); const MT_Point3 & p_world_pos = parent->GetWorldPosition(); const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); - child_w_scale = p_world_scale * child_scale; - child_w_rotation = p_world_rotation * child_rotation; - - child_w_pos = p_world_pos + p_world_scale * - (p_world_rotation * child_pos); - - } else { - - child_w_scale = child_scale; - child_w_pos = child_pos; - child_w_rotation = child_rotation; + child->SetWorldScale(p_world_scale * child->GetLocalScale()); + child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation()); + child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition())); + return true; } - - child->SetWorldScale(child_w_scale); - child->SetWorldPosition(child_w_pos); - child->SetWorldOrientation(child_w_rotation); - - return parent != NULL; } SG_ParentRelation * @@ -138,40 +116,14 @@ UpdateChildCoordinates( ){ MT_assert(child != NULL); - - const MT_Vector3 & child_scale = child->GetLocalScale(); - const MT_Point3 & child_pos = child->GetLocalPosition(); - const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); - - // the childs world locations which we will update. + child->SetWorldScale(child->GetLocalScale()); - MT_Vector3 child_w_scale; - MT_Point3 child_w_pos; - MT_Matrix3x3 child_w_rotation; - - if (parent) { - - // This is a vertex parent so we do not inherit orientation - // information. - - // const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); /*unused*/ - const MT_Point3 & p_world_pos = parent->GetWorldPosition(); - // const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); /*unused*/ - - child_w_scale = child_scale; - child_w_rotation = child_rotation; - child_w_pos = p_world_pos + child_pos; - } else { - - child_w_scale = child_scale; - child_w_pos = child_pos; - child_w_rotation = child_rotation; - } - - child->SetWorldScale(child_w_scale); - child->SetWorldPosition(child_w_pos); - child->SetWorldOrientation(child_w_rotation); + if (parent) + child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition()); + else + child->SetWorldPosition(child->GetLocalPosition()); + child->SetWorldOrientation(child->GetLocalOrientation()); return parent != NULL; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 476a931355f..0fded15f1a1 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1014,6 +1014,12 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) blendmesh->dvert!=NULL; // mesh has vertex group bool releaseParent = true; + + if (oldblendobj==NULL) { + std::cout << "warning: ReplaceMesh() new mesh is not used in an object from the current scene, you will get incorrect behavior" << std::endl; + bHasShapeKey= bHasDvert= bHasArmature= false; + } + if (bHasShapeKey) { BL_ShapeDeformer* shapeDeformer; @@ -1511,14 +1517,6 @@ double KX_Scene::getSuspendedDelta() //---------------------------------------------------------------------------- //Python -PyMethodDef KX_Scene::Methods[] = { - KX_PYMETHODTABLE(KX_Scene, getLightList), - KX_PYMETHODTABLE(KX_Scene, getObjectList), - KX_PYMETHODTABLE(KX_Scene, getName), - - {NULL,NULL} //Sentinel -}; - PyTypeObject KX_Scene::Type = { PyObject_HEAD_INIT(&PyType_Type) 0, @@ -1544,28 +1542,40 @@ PyParentObject KX_Scene::Parents[] = { NULL }; -PyObject* KX_Scene::_getattr(const STR_String& attr) +PyMethodDef KX_Scene::Methods[] = { + KX_PYMETHODTABLE(KX_Scene, getLightList), + KX_PYMETHODTABLE(KX_Scene, getObjectList), + KX_PYMETHODTABLE(KX_Scene, getName), + KX_PYMETHODTABLE(KX_Scene, addObject), + + {NULL,NULL} //Sentinel +}; + +PyAttributeDef KX_Scene::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_Scene::_getattr(const char *attr) { - if (attr == "name") + if (!strcmp(attr, "name")) return PyString_FromString(GetName()); - if (attr == "active_camera") - { - KX_Camera *camera = GetActiveCamera(); - camera->AddRef(); - return (PyObject*) camera; - } + if (!strcmp(attr, "objects")) + return (PyObject*) m_objectlist->AddRef(); - if (attr == "suspended") + if (!strcmp(attr, "active_camera")) + return (PyObject*) GetActiveCamera()->AddRef(); + + if (!strcmp(attr, "suspended")) return PyInt_FromLong(m_suspend); - if (attr == "activity_culling") + if (!strcmp(attr, "activity_culling")) return PyInt_FromLong(m_activity_culling); - if (attr == "activity_culling_radius") + if (!strcmp(attr, "activity_culling_radius")) return PyFloat_FromDouble(m_activity_box_radius); - PyObject* value = PyDict_GetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr())); + PyObject* value = PyDict_GetItemString(m_attrlist, attr); if (value) { Py_INCREF(value); @@ -1575,43 +1585,63 @@ PyObject* KX_Scene::_getattr(const STR_String& attr) _getattr_up(PyObjectPlus); } -int KX_Scene::_delattr(const STR_String &attr) +int KX_Scene::_delattr(const char *attr) { - PyDict_DelItemString(m_attrlist, const_cast<char *>(attr.ReadPtr())); + PyDict_DelItemString(m_attrlist, attr); return 0; } -int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue) +int KX_Scene::_setattr(const char *attr, PyObject *pyvalue) { - - if (!PyDict_SetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()), pyvalue)) + if (!PyDict_SetItemString(m_attrlist, attr, pyvalue)) return 0; return PyObjectPlus::_setattr(attr, pyvalue); } -KX_PYMETHODDEF_DOC(KX_Scene, getLightList, +KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList, "getLightList() -> list [KX_Light]\n" "Returns a list of all lights in the scene.\n" ) { - m_lightlist->AddRef(); - return (PyObject*) m_lightlist; + return (PyObject*) m_lightlist->AddRef(); } -KX_PYMETHODDEF_DOC(KX_Scene, getObjectList, +KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList, "getObjectList() -> list [KX_GameObject]\n" "Returns a list of all game objects in the scene.\n" ) { - m_objectlist->AddRef(); - return (PyObject*) m_objectlist; + // ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work? + return (PyObject*) m_objectlist->AddRef(); } -KX_PYMETHODDEF_DOC(KX_Scene, getName, +KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName, "getName() -> string\n" "Returns the name of the scene.\n" ) { return PyString_FromString(GetName()); } + +KX_PYMETHODDEF_DOC(KX_Scene, addObject, +"addObject(object, other, time=0)\n" +"Returns the added object.\n") +{ + PyObject *pyob, *pyother; + KX_GameObject *ob, *other; + + int time = 0; + + if (!PyArg_ParseTuple(args, "OO|i", &pyob, &pyother, &time)) + return NULL; + + if (!ConvertPythonToGameObject(pyob, &ob, false) + || !ConvertPythonToGameObject(pyother, &other, false)) + return NULL; + + + SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time); + replica->AddRef(); + return replica; +}
\ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 5f7e1167e27..962db1a9b96 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -547,9 +547,10 @@ public: */ void SetNodeTree(SG_Tree* root); - KX_PYMETHOD_DOC(KX_Scene, getLightList); - KX_PYMETHOD_DOC(KX_Scene, getObjectList); - KX_PYMETHOD_DOC(KX_Scene, getName); + KX_PYMETHOD_DOC_NOARGS(KX_Scene, getLightList); + KX_PYMETHOD_DOC_NOARGS(KX_Scene, getObjectList); + KX_PYMETHOD_DOC_NOARGS(KX_Scene, getName); + KX_PYMETHOD_DOC(KX_Scene, addObject); /* KX_PYMETHOD_DOC(KX_Scene, getActiveCamera); KX_PYMETHOD_DOC(KX_Scene, getActiveCamera); @@ -564,10 +565,12 @@ public: KX_PYMETHOD_DOC(KX_Scene, setSceneViewport); */ - virtual PyObject* _getattr(const STR_String& attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ - virtual int _setattr(const STR_String &attr, PyObject *pyvalue); - virtual int _delattr(const STR_String &attr); + virtual PyObject* _getattr(const char *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */ + virtual int _setattr(const char *attr, PyObject *pyvalue); + virtual int _delattr(const char *attr); + virtual PyObject* _repr(void) { return PyString_FromString(GetName().ReadPtr()); } + /** * Sets the time the scene was suspended */ diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 35484699b17..1cad4e21352 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -268,9 +268,11 @@ PyMethodDef KX_SceneActuator::Methods[] = {NULL,NULL} //Sentinel }; +PyAttributeDef KX_SceneActuator::Attributes[] = { + { NULL } //Sentinel +}; - -PyObject* KX_SceneActuator::_getattr(const STR_String& attr) +PyObject* KX_SceneActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -295,7 +297,7 @@ PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self, m_restart = boolArg != 0; - Py_Return; + Py_RETURN_NONE; } @@ -333,7 +335,7 @@ PyObject* KX_SceneActuator::PySetScene(PyObject* self, /* Scene switch is done by name. */ m_nextSceneName = scene_name; - Py_Return; + Py_RETURN_NONE; } @@ -368,7 +370,7 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self, m_camera = (KX_Camera*) cam; if (m_camera) m_camera->RegisterActuator(this); - Py_Return; + Py_RETURN_NONE; } PyErr_Clear(); @@ -388,7 +390,7 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self, m_camera->RegisterActuator(this); } - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 55aaf629d7c..af11af955bf 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -92,7 +92,7 @@ class KX_SceneActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); /* 1. set */ /* Removed */ diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index afa5af3bc04..6de1d67bfdb 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -285,9 +285,11 @@ PyMethodDef KX_SoundActuator::Methods[] = { {NULL,NULL,NULL,NULL} //Sentinel }; +PyAttributeDef KX_SoundActuator::Attributes[] = { + { NULL } //Sentinel +}; - -PyObject* KX_SoundActuator::_getattr(const STR_String& attr) +PyObject* KX_SoundActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); } @@ -302,7 +304,7 @@ PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObje if (!PyArg_ParseTuple(args, "s", &soundName)) return NULL; - Py_Return; + Py_RETURN_NONE; } @@ -332,7 +334,7 @@ PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObjec // To start the sound you must activate the actuator. // This function is to restart the sound. m_soundObject->StartSound(); - Py_Return; + Py_RETURN_NONE; } @@ -342,7 +344,7 @@ PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObjec if (m_soundObject) // unfortunately, openal does not implement pause correctly, it is equivalent to a stop m_soundObject->PauseSound(); - Py_Return; + Py_RETURN_NONE; } @@ -351,7 +353,7 @@ PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject { if (m_soundObject) m_soundObject->StopSound(); - Py_Return; + Py_RETURN_NONE; } @@ -365,7 +367,7 @@ PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject* if (m_soundObject) m_soundObject->SetGain(gain); - Py_Return; + Py_RETURN_NONE; } @@ -389,7 +391,7 @@ PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject* if (m_soundObject) m_soundObject->SetPitch(pitch); - Py_Return; + Py_RETURN_NONE; } @@ -413,7 +415,7 @@ PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, P if (m_soundObject) m_soundObject->SetRollOffFactor(rollofffactor); - Py_Return; + Py_RETURN_NONE; } @@ -437,14 +439,14 @@ PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObjec if (m_soundObject) m_soundObject->SetLoopMode(looping); - Py_Return; + Py_RETURN_NONE; } PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds) { - int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : SND_LOOP_OFF; + int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF; PyObject* result = PyInt_FromLong(looping); return result; @@ -465,7 +467,7 @@ PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObje if (m_soundObject) m_soundObject->SetPosition(pos); - Py_Return; + Py_RETURN_NONE; } @@ -483,7 +485,7 @@ PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObje if (m_soundObject) m_soundObject->SetVelocity(vel); - Py_Return; + Py_RETURN_NONE; } @@ -507,7 +509,7 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyO if (m_soundObject) m_soundObject->SetOrientation(ori); - Py_Return; + Py_RETURN_NONE; } PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject* kwds) @@ -523,7 +525,7 @@ PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject* m_type = (KX_SOUNDACT_TYPE) typeArg; } - Py_Return; + Py_RETURN_NONE; } PyObject* KX_SoundActuator::PyGetType(PyObject* self, PyObject* args, PyObject* kwds) diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index 5a9edbc4c5e..68d5b792729 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -80,7 +80,7 @@ public: /* Python interface --------------------------------------------------- */ /* -------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); KX_PYMETHOD(KX_SoundActuator,SetFilename); KX_PYMETHOD(KX_SoundActuator,GetFilename); diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp index e360c4bac1f..0de4da79bd8 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.cpp +++ b/source/gameengine/Ketsji/KX_StateActuator.cpp @@ -146,10 +146,11 @@ KX_StateActuator::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* -KX_StateActuator::_getattr( - const STR_String& attr - ) +PyAttributeDef KX_StateActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_StateActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); }; @@ -176,7 +177,7 @@ KX_StateActuator::PySetOperation(PyObject* self, m_operation = oper; - Py_Return; + Py_RETURN_NONE; } /* set mask ---------------------------------------------------------- */ @@ -201,7 +202,7 @@ KX_StateActuator::PySetMask(PyObject* self, m_mask = mask; - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index 8698e51b2c1..023b8993d7c 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -73,7 +73,7 @@ class KX_StateActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC(KX_StateActuator,SetOperation); KX_PYMETHOD_DOC(KX_StateActuator,SetMask); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 1935a0bde39..705b54edd37 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -34,7 +34,9 @@ #include "SCA_LogicManager.h" #include "KX_GameObject.h" #include "KX_TouchEventManager.h" -#include "KX_SumoPhysicsController.h" + +#include "PHY_IPhysicsController.h" + #include <iostream> #include "PHY_IPhysicsEnvironment.h" @@ -57,6 +59,7 @@ void KX_TouchSensor::EndFrame() { m_colliders->ReleaseAndRemoveAll(); m_hitObject = NULL; m_bTriggered = false; + m_bColliderHash = 0; } void KX_TouchSensor::UnregisterToManager() @@ -70,7 +73,6 @@ bool KX_TouchSensor::Evaluate(CValue* event) { bool result = false; bool reset = m_reset && m_level; - m_reset = false; if (m_bTriggered != m_bLastTriggered) { @@ -82,13 +84,24 @@ bool KX_TouchSensor::Evaluate(CValue* event) if (reset) // force an event result = true; + + if (m_bTouchPulse) { /* pulse on changes to the colliders */ + int count = m_colliders->GetCount(); + + if (m_bLastCount!=count || m_bColliderHash!=m_bLastColliderHash) { + m_bLastCount = count; + m_bLastColliderHash= m_bColliderHash; + result = true; + } + } return result; } -KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T) +KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,bool bTouchPulse,const STR_String& touchedpropname,PyTypeObject* T) :SCA_ISensor(gameobj,eventmgr,T), m_touchedpropname(touchedpropname), m_bFindMaterial(bFindMaterial), +m_bTouchPulse(bTouchPulse), m_eventmgr(eventmgr) /*m_sumoObj(sumoObj),*/ { @@ -100,8 +113,8 @@ m_eventmgr(eventmgr) m_colliders = new CListValue(); KX_ClientObjectInfo *client_info = gameobj->getClientInfo(); - client_info->m_gameobject = gameobj; - client_info->m_auxilary_info = NULL; + //client_info->m_gameobject = gameobj; + //client_info->m_auxilary_info = NULL; client_info->m_sensors.push_back(this); m_physCtrl = dynamic_cast<PHY_IPhysicsController*>(gameobj->GetPhysicsController()); @@ -114,6 +127,8 @@ void KX_TouchSensor::Init() m_bCollision = false; m_bTriggered = false; m_bLastTriggered = (m_invert)?true:false; + m_bLastCount = 0; + m_bColliderHash = m_bLastColliderHash = 0; m_hitObject = NULL; m_reset = true; } @@ -143,8 +158,8 @@ void KX_TouchSensor::ReParent(SCA_IObject* parent) // m_solidHandle = m_sumoObj->getObjectHandle(); KX_ClientObjectInfo *client_info = gameobj->getClientInfo(); - client_info->m_gameobject = gameobj; - client_info->m_auxilary_info = NULL; + //client_info->m_gameobject = gameobj; + //client_info->m_auxilary_info = NULL; client_info->m_sensors.push_back(this); SCA_ISensor::ReParent(parent); @@ -189,8 +204,6 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll if (m_links && !m_suspended && gameobj && (gameobj != parent) && client_info->isActor()) { - if (!m_colliders->SearchValue(gameobj)) - m_colliders->Add(gameobj->AddRef()); bool found = m_touchedpropname.IsEmpty(); if (!found) @@ -199,7 +212,7 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll { if (client_info->m_auxilary_info) { - found = (m_touchedpropname == STR_String((char*)client_info->m_auxilary_info)); + found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info)); } } else { @@ -208,13 +221,19 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll } if (found) { + if (!m_colliders->SearchValue(gameobj)) { + m_colliders->Add(gameobj->AddRef()); + + if (m_bTouchPulse) + m_bColliderHash += (uint_ptr)(static_cast<void *>(&gameobj)); + } m_bTriggered = true; m_hitObject = gameobj; //printf("KX_TouchSensor::HandleCollision\n"); } } - return DT_CONTINUE; + return false; // was DT_CONTINUE but this was defined in sumo as false. } @@ -250,21 +269,53 @@ PyParentObject KX_TouchSensor::Parents[] = { }; PyMethodDef KX_TouchSensor::Methods[] = { + //Deprecated -----> {"setProperty", - (PyCFunction) KX_TouchSensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc}, + (PyCFunction) KX_TouchSensor::sPySetProperty, METH_O, (PY_METHODCHAR)SetProperty_doc}, {"getProperty", - (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc}, + (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_NOARGS, (PY_METHODCHAR)GetProperty_doc}, {"getHitObject", - (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc}, + (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc}, {"getHitObjectList", - (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_VARARGS, (PY_METHODCHAR)GetHitObjectList_doc}, + (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_NOARGS, (PY_METHODCHAR)GetHitObjectList_doc}, + //<----- {NULL,NULL} //Sentinel }; -PyObject* KX_TouchSensor::_getattr(const STR_String& attr) { +PyAttributeDef KX_TouchSensor::Attributes[] = { + KX_PYATTRIBUTE_STRING_RW("property",0,100,false,KX_TouchSensor,m_touchedpropname), + KX_PYATTRIBUTE_BOOL_RW("useMaterial",KX_TouchSensor,m_bFindMaterial), + KX_PYATTRIBUTE_BOOL_RW("pulseCollisions",KX_TouchSensor,m_bTouchPulse), + KX_PYATTRIBUTE_DUMMY("objectHit"), + KX_PYATTRIBUTE_DUMMY("objectHitList"), + { NULL } //Sentinel +}; + +PyObject* KX_TouchSensor::_getattr(const char *attr) +{ + if (!strcmp(attr, "objectHit")) { + if (m_hitObject) return m_hitObject->AddRef(); + else Py_RETURN_NONE; + } + if (!strcmp(attr, "objectHitList")) { + return m_colliders->AddRef(); + } + + PyObject* object= _getattr_self(Attributes, this, attr); + if (object != NULL) + return object; _getattr_up(SCA_ISensor); } +int KX_TouchSensor::_setattr(const char *attr, PyObject *value) +{ + int ret = _setattr_self(Attributes, this, attr, value); + if (ret >= 0) + return ret; + + return SCA_ISensor::_setattr(attr, value); +} + /* Python API */ /* 1. setProperty */ @@ -274,24 +325,17 @@ const char KX_TouchSensor::SetProperty_doc[] = "\tSet the property or material to collide with. Use\n" "\tsetTouchMaterial() to switch between properties and\n" "\tmaterials."; -PyObject* KX_TouchSensor::PySetProperty(PyObject* self, - PyObject* args, - PyObject* kwds) { - char *nameArg; - if (!PyArg_ParseTuple(args, "s", &nameArg)) { +PyObject* KX_TouchSensor::PySetProperty(PyObject* self, PyObject* value) +{ + ShowDeprecationWarning("setProperty()", "the propertyName property"); + char *nameArg= PyString_AsString(value); + if (nameArg==NULL) { + PyErr_SetString(PyExc_ValueError, "expected a "); return NULL; } - - CValue* prop = GetParent()->FindIdentifier(nameArg); - - if (!prop->IsError()) { - m_touchedpropname = nameArg; - } else { - ; /* not found ... */ - } - prop->Release(); - Py_Return; + m_touchedpropname = nameArg; + Py_RETURN_NONE; } /* 2. getProperty */ const char KX_TouchSensor::GetProperty_doc[] = @@ -299,111 +343,71 @@ const char KX_TouchSensor::GetProperty_doc[] = "\tReturns the property or material to collide with. Use\n" "\tgetTouchMaterial() to find out whether this sensor\n" "\tlooks for properties or materials."; -PyObject* KX_TouchSensor::PyGetProperty(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* KX_TouchSensor::PyGetProperty(PyObject* self) { return PyString_FromString(m_touchedpropname); } const char KX_TouchSensor::GetHitObject_doc[] = "getHitObject()\n" ; -PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self) { + ShowDeprecationWarning("getHitObject()", "the objectHit property"); /* to do: do Py_IncRef if the object is already known in Python */ /* otherwise, this leaks memory */ if (m_hitObject) { return m_hitObject->AddRef(); } - Py_Return; + Py_RETURN_NONE; } const char KX_TouchSensor::GetHitObjectList_doc[] = "getHitObjectList()\n" "\tReturn a list of the objects this object collided with,\n" "\tbut only those matching the property/material condition.\n"; -PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self) { - + ShowDeprecationWarning("getHitObjectList()", "the objectHitList property"); /* to do: do Py_IncRef if the object is already known in Python */ - /* otherwise, this leaks memory */ - - if ( m_touchedpropname.IsEmpty() ) { - return m_colliders->AddRef(); - } else { - CListValue* newList = new CListValue(); - int i = 0; - while (i < m_colliders->GetCount()) { - if (m_bFindMaterial) { - /* need to associate the CValues from the list to material - * names. The collider list _should_ contains only - * KX_GameObjects. I am loathe to cast them, though... The - * material name must be retrieved from Sumo. To a Sumo - * object, a client-info block is attached. This block - * contains the material name. - * - this also doesn't work (obviously) for multi-materials... - */ - KX_GameObject* gameob = (KX_GameObject*) m_colliders->GetValue(i); - PHY_IPhysicsController* spc = dynamic_cast<PHY_IPhysicsController*>(gameob->GetPhysicsController()); - - if (spc) { - KX_ClientObjectInfo* cl_inf = static_cast<KX_ClientObjectInfo*>(spc->getNewClientInfo()); - - if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) { - newList->Add(m_colliders->GetValue(i)->AddRef()); - } - } - - } else { - CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname); - if (!val->IsError()) { - newList->Add(m_colliders->GetValue(i)->AddRef()); - } - val->Release(); - } - - i++; - } - return newList->AddRef(); - } - + /* otherwise, this leaks memory */ /* Edit, this seems ok and not to leak memory - Campbell */ + return m_colliders->AddRef(); } +/*getTouchMaterial and setTouchMaterial were never added to the api, +they can probably be removed with out anyone noticing*/ + /* 5. getTouchMaterial */ const char KX_TouchSensor::GetTouchMaterial_doc[] = "getTouchMaterial()\n" "\tReturns KX_TRUE if this sensor looks for a specific material,\n" "\tKX_FALSE if it looks for a specific property.\n" ; -PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self, - PyObject* args, - PyObject* kwds) +PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self) { + ShowDeprecationWarning("getTouchMaterial()", "the materialCheck property"); return PyInt_FromLong(m_bFindMaterial); } /* 6. setTouchMaterial */ +#if 0 const char KX_TouchSensor::SetTouchMaterial_doc[] = "setTouchMaterial(flag)\n" "\t- flag: KX_TRUE or KX_FALSE.\n" "\tSet flag to KX_TRUE to switch on positive pulse mode,\n" "\tKX_FALSE to switch off positive pulse mode.\n" ; -PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject* args, PyObject* kwds) +PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject *value) { - int pulseArg = 0; + int pulseArg = PyInt_AsLong(value); - if(!PyArg_ParseTuple(args, "i", &pulseArg)) { + if(pulseArg ==-1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, "expected a bool"); return NULL; } m_bFindMaterial = pulseArg != 0; - Py_Return; + Py_RETURN_NONE; } - +#endif /* eof */ diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index 8fbb1c676ba..18ce9406a9b 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -39,6 +39,12 @@ struct PHY_CollData; #include "KX_ClientObjectInfo.h" +#if defined(_WIN64) +typedef unsigned __int64 uint_ptr; +#else +typedef unsigned long uint_ptr; +#endif + class KX_TouchEventManager; class KX_TouchSensor : public SCA_ISensor @@ -51,6 +57,7 @@ protected: */ STR_String m_touchedpropname; bool m_bFindMaterial; + bool m_bTouchPulse; /* changes in the colliding objects trigger pulses */ class SCA_EventManager* m_eventmgr; class PHY_IPhysicsController* m_physCtrl; @@ -58,13 +65,20 @@ protected: bool m_bCollision; bool m_bTriggered; bool m_bLastTriggered; + + // Use with m_bTouchPulse to detect changes + int m_bLastCount; /* size of m_colliders last tick */ + uint_ptr m_bColliderHash; /* hash collision objects pointers to trigger incase one object collides and another takes its place */ + uint_ptr m_bLastColliderHash; + SCA_IObject* m_hitObject; class CListValue* m_colliders; public: KX_TouchSensor(class SCA_EventManager* eventmgr, class KX_GameObject* gameobj, - bool fFindMaterial, + bool bFindMaterial, + bool bTouchPulse, const STR_String& touchedpropname, PyTypeObject* T=&Type) ; virtual ~KX_TouchSensor(); @@ -106,20 +120,25 @@ public: /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); + //Deprecated -----> /* 1. setProperty */ - KX_PYMETHOD_DOC(KX_TouchSensor,SetProperty); + KX_PYMETHOD_DOC_O(KX_TouchSensor,SetProperty); /* 2. getProperty */ - KX_PYMETHOD_DOC(KX_TouchSensor,GetProperty); + KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetProperty); /* 3. getHitObject */ - KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObject); + KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetHitObject); /* 4. getHitObject */ - KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObjectList); + KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetHitObjectList); /* 5. getTouchMaterial */ - KX_PYMETHOD_DOC(KX_TouchSensor,GetTouchMaterial); + KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetTouchMaterial); +#if 0 /* 6. setTouchMaterial */ - KX_PYMETHOD_DOC(KX_TouchSensor,SetTouchMaterial); + KX_PYMETHOD_DOC_O(KX_TouchSensor,SetTouchMaterial); +#endif + //<----- }; diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index acc4a6ab5d7..8637bc92d39 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -258,18 +258,18 @@ bool KX_TrackToActuator::Update(double curtime, bool frame) { case 0: { - up = MT_Vector3(1.0,0,0); + up.setValue(1.0,0,0); break; } case 1: { - up = MT_Vector3(0,1.0,0); + up.setValue(0,1.0,0); break; } case 2: default: { - up = MT_Vector3(0,0,1.0); + up.setValue(0,0,1.0); } } #endif @@ -456,23 +456,54 @@ PyParentObject KX_TrackToActuator::Parents[] = { PyMethodDef KX_TrackToActuator::Methods[] = { - {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, - {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, {"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, (PY_METHODCHAR)SetTime_doc}, {"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_VARARGS, (PY_METHODCHAR)GetTime_doc}, {"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, (PY_METHODCHAR)SetUse3D_doc}, {"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_VARARGS, (PY_METHODCHAR)GetUse3D_doc}, + + // ---> deprecated + {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc}, + {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc}, + {NULL,NULL} //Sentinel }; +PyAttributeDef KX_TrackToActuator::Attributes[] = { + { NULL } //Sentinel +}; -PyObject* KX_TrackToActuator::_getattr(const STR_String& attr) +PyObject* KX_TrackToActuator::_getattr(const char *attr) { + if (!strcmp(attr, "object")) { + if (!m_object) Py_RETURN_NONE; + else return m_object->AddRef(); + } + _getattr_up(SCA_IActuator); } +int KX_TrackToActuator::_setattr(const char *attr, PyObject* value) +{ + if (!strcmp(attr, "object")) { + KX_GameObject *gameobj; + + if (!ConvertPythonToGameObject(value, &gameobj, true)) + return 1; // ConvertPythonToGameObject sets the error + + if (m_object != NULL) + m_object->UnregisterActuator(this); + m_object = (SCA_IObject*)gameobj; + + if (m_object) + m_object->RegisterActuator(this); + + return 0; + } + + return SCA_IActuator::_setattr(attr, value); +} /* 1. setObject */ const char KX_TrackToActuator::SetObject_doc[] = @@ -483,6 +514,8 @@ PyObject* KX_TrackToActuator::PySetObject(PyObject* self, PyObject* value) { KX_GameObject *gameobj; + ShowDeprecationWarning("setObject()", "the object property"); + if (!ConvertPythonToGameObject(value, &gameobj, true)) return NULL; // ConvertPythonToGameObject sets the error @@ -506,6 +539,9 @@ const char KX_TrackToActuator::GetObject_doc[] = PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args) { int ret_name_only = 1; + + ShowDeprecationWarning("getObject()", "the object property"); + if (!PyArg_ParseTuple(args, "|i", &ret_name_only)) return NULL; @@ -536,7 +572,7 @@ PyObject* KX_TrackToActuator::PySetTime(PyObject* self, PyObject* args, PyObject m_time= timeArg; - Py_Return; + Py_RETURN_NONE; } @@ -580,7 +616,7 @@ PyObject* KX_TrackToActuator::PySetUse3D(PyObject* self, PyObject* args, PyObjec m_allow3D = !(boolArg == 0); - Py_Return; + Py_RETURN_NONE; } /* eof */ diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 445132a6094..392e55402f1 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -72,7 +72,8 @@ class KX_TrackToActuator : public SCA_IActuator virtual bool Update(double curtime, bool frame); /* Python part */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject* value); /* 1. setObject */ KX_PYMETHOD_DOC_O(KX_TrackToActuator,SetObject); diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 028f96f6c5b..8d5af1b9216 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -322,13 +322,13 @@ PyParentObject KX_VehicleWrapper::Parents[] = { NULL }; -PyObject* KX_VehicleWrapper::_getattr(const STR_String& attr) +PyObject* KX_VehicleWrapper::_getattr(const char *attr) { //here you can search for existing data members (like mass,friction etc.) _getattr_up(PyObjectPlus); } -int KX_VehicleWrapper::_setattr(const STR_String& attr,PyObject* pyobj) +int KX_VehicleWrapper::_setattr(const char *attr,PyObject* pyobj) { PyTypeObject* type = pyobj->ob_type; @@ -382,3 +382,6 @@ PyMethodDef KX_VehicleWrapper::Methods[] = { {NULL,NULL} //Sentinel }; +PyAttributeDef KX_VehicleWrapper::Attributes[] = { + { NULL } //Sentinel +}; diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index b98369d401a..cad926ce85a 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -12,8 +12,8 @@ class PHY_IMotionState; class KX_VehicleWrapper : public PyObjectPlus { Py_Header; - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *value); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *value); std::vector<PHY_IMotionState*> m_motionStates; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 25205714308..da0e3dbdd8d 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -63,31 +63,63 @@ PyParentObject KX_VertexProxy::Parents[] = { }; PyMethodDef KX_VertexProxy::Methods[] = { -{"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_VARARGS}, -{"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_VARARGS}, -{"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_VARARGS}, -{"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_VARARGS}, +{"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_NOARGS}, +{"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_O}, +{"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_NOARGS}, +{"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_O}, -{"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_VARARGS}, +{"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_NOARGS}, {"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2,METH_VARARGS}, -{"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_VARARGS}, -{"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_VARARGS}, -{"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_VARARGS}, -{"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_VARARGS}, +{"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_NOARGS}, +{"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_O}, +{"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_NOARGS}, +{"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_O}, {NULL,NULL} //Sentinel }; +PyAttributeDef KX_VertexProxy::Attributes[] = { + { NULL } //Sentinel +}; + PyObject* -KX_VertexProxy::_getattr(const STR_String& attr) +KX_VertexProxy::_getattr(const char *attr) { - if (attr == "XYZ") + + if (attr[1]=='\0') { // Group single letters + // pos + if (attr[0]=='x') + return PyFloat_FromDouble(m_vertex->getXYZ()[0]); + if (attr[0]=='y') + return PyFloat_FromDouble(m_vertex->getXYZ()[1]); + if (attr[0]=='z') + return PyFloat_FromDouble(m_vertex->getXYZ()[2]); + + // Col + if (attr[0]=='r') + return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0); + if (attr[0]=='g') + return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0); + if (attr[0]=='b') + return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0); + if (attr[0]=='a') + return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0); + + // UV + if (attr[0]=='u') + return PyFloat_FromDouble(m_vertex->getUV1()[0]); + if (attr[0]=='v') + return PyFloat_FromDouble(m_vertex->getUV1()[1]); + } + + + if (!strcmp(attr, "XYZ")) return PyObjectFrom(MT_Vector3(m_vertex->getXYZ())); - if (attr == "UV") + if (!strcmp(attr, "UV")) return PyObjectFrom(MT_Point2(m_vertex->getUV1())); - if (attr == "colour" || attr == "color") + if (!strcmp(attr, "color") || !strcmp(attr, "colour")) { const unsigned char *colp = m_vertex->getRGBA(); MT_Vector4 color(colp[0], colp[1], colp[2], colp[3]); @@ -95,43 +127,19 @@ KX_VertexProxy::_getattr(const STR_String& attr) return PyObjectFrom(color); } - if (attr == "normal") + if (!strcmp(attr, "normal")) { return PyObjectFrom(MT_Vector3(m_vertex->getNormal())); } - - // pos - if (attr == "x") - return PyFloat_FromDouble(m_vertex->getXYZ()[0]); - if (attr == "y") - return PyFloat_FromDouble(m_vertex->getXYZ()[1]); - if (attr == "z") - return PyFloat_FromDouble(m_vertex->getXYZ()[2]); - - // Col - if (attr == "r") - return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0); - if (attr == "g") - return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0); - if (attr == "b") - return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0); - if (attr == "a") - return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0); - - // UV - if (attr == "u") - return PyFloat_FromDouble(m_vertex->getUV1()[0]); - if (attr == "v") - return PyFloat_FromDouble(m_vertex->getUV1()[1]); - + _getattr_up(SCA_IObject); } -int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) +int KX_VertexProxy::_setattr(const char *attr, PyObject *pyvalue) { if (PySequence_Check(pyvalue)) { - if (attr == "XYZ") + if (!strcmp(attr, "XYZ")) { MT_Point3 vec; if (PyVecTo(pyvalue, vec)) @@ -143,7 +151,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 1; } - if (attr == "UV") + if (!strcmp(attr, "UV")) { MT_Point2 vec; if (PyVecTo(pyvalue, vec)) @@ -155,7 +163,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 1; } - if (attr == "colour" || attr == "color") + if (!strcmp(attr, "color") || !strcmp(attr, "colour")) { MT_Vector4 vec; if (PyVecTo(pyvalue, vec)) @@ -167,7 +175,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 1; } - if (attr == "normal") + if (!strcmp(attr, "normal")) { MT_Vector3 vec; if (PyVecTo(pyvalue, vec)) @@ -185,7 +193,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) float val = PyFloat_AsDouble(pyvalue); // pos MT_Point3 pos(m_vertex->getXYZ()); - if (attr == "x") + if (!strcmp(attr, "x")) { pos.x() = val; m_vertex->SetXYZ(pos); @@ -193,7 +201,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 0; } - if (attr == "y") + if (!strcmp(attr, "y")) { pos.y() = val; m_vertex->SetXYZ(pos); @@ -201,7 +209,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 0; } - if (attr == "z") + if (!strcmp(attr, "z")) { pos.z() = val; m_vertex->SetXYZ(pos); @@ -211,7 +219,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) // uv MT_Point2 uv = m_vertex->getUV1(); - if (attr == "u") + if (!strcmp(attr, "u")) { uv[0] = val; m_vertex->SetUV(uv); @@ -219,7 +227,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 0; } - if (attr == "v") + if (!strcmp(attr, "v")) { uv[1] = val; m_vertex->SetUV(uv); @@ -229,7 +237,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) // uv MT_Point2 uv2 = m_vertex->getUV2(); - if (attr == "u2") + if (!strcmp(attr, "u2")) { uv[0] = val; m_vertex->SetUV2(uv); @@ -237,7 +245,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) return 0; } - if (attr == "v2") + if (!strcmp(attr, "v2")) { uv[1] = val; m_vertex->SetUV2(uv); @@ -249,28 +257,28 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue) unsigned int icol = *((const unsigned int *)m_vertex->getRGBA()); unsigned char *cp = (unsigned char*) &icol; val *= 255.0; - if (attr == "r") + if (!strcmp(attr, "r")) { cp[0] = (unsigned char) val; m_vertex->SetRGBA(icol); m_mesh->SetMeshModified(true); return 0; } - if (attr == "g") + if (!strcmp(attr, "g")) { cp[1] = (unsigned char) val; m_vertex->SetRGBA(icol); m_mesh->SetMeshModified(true); return 0; } - if (attr == "b") + if (!strcmp(attr, "b")) { cp[2] = (unsigned char) val; m_vertex->SetRGBA(icol); m_mesh->SetMeshModified(true); return 0; } - if (attr == "a") + if (!strcmp(attr, "a")) { cp[3] = (unsigned char) val; m_vertex->SetRGBA(icol); @@ -308,130 +316,103 @@ void KX_VertexProxy::ReplicaSetName(STR_String) {}; // stuff for python integration -PyObject* KX_VertexProxy::PyGetXYZ(PyObject*, - PyObject*, - PyObject*) +PyObject* KX_VertexProxy::PyGetXYZ(PyObject*) { return PyObjectFrom(MT_Point3(m_vertex->getXYZ())); } -PyObject* KX_VertexProxy::PySetXYZ(PyObject*, - PyObject* args, - PyObject*) +PyObject* KX_VertexProxy::PySetXYZ(PyObject*, PyObject* value) { MT_Point3 vec; - if (PyVecArgTo(args, vec)) - { - m_vertex->SetXYZ(vec); - m_mesh->SetMeshModified(true); - Py_Return; - } - - return NULL; + if (!PyVecTo(value, vec)) + return NULL; + + m_vertex->SetXYZ(vec); + m_mesh->SetMeshModified(true); + Py_RETURN_NONE; } -PyObject* KX_VertexProxy::PyGetNormal(PyObject*, - PyObject*, - PyObject*) +PyObject* KX_VertexProxy::PyGetNormal(PyObject*) { return PyObjectFrom(MT_Vector3(m_vertex->getNormal())); } -PyObject* KX_VertexProxy::PySetNormal(PyObject*, - PyObject* args, - PyObject*) +PyObject* KX_VertexProxy::PySetNormal(PyObject*, PyObject* value) { MT_Vector3 vec; - if (PyVecArgTo(args, vec)) - { - m_vertex->SetNormal(vec); - m_mesh->SetMeshModified(true); - Py_Return; - } + if (!PyVecTo(value, vec)) + return NULL; - return NULL; + m_vertex->SetNormal(vec); + m_mesh->SetMeshModified(true); + Py_RETURN_NONE; } -PyObject* KX_VertexProxy::PyGetRGBA(PyObject*, - PyObject*, - PyObject*) +PyObject* KX_VertexProxy::PyGetRGBA(PyObject*) { int *rgba = (int *) m_vertex->getRGBA(); return PyInt_FromLong(*rgba); } -PyObject* KX_VertexProxy::PySetRGBA(PyObject*, - PyObject* args, - PyObject*) +PyObject* KX_VertexProxy::PySetRGBA(PyObject*, PyObject* value) { - float r, g, b, a; - if (PyArg_ParseTuple(args, "(ffff)", &r, &g, &b, &a)) - { - m_vertex->SetRGBA(MT_Vector4(r, g, b, a)); - m_mesh->SetMeshModified(true); - Py_Return; - } - PyErr_Clear(); - - int rgba; - if (PyArg_ParseTuple(args,"i",&rgba)) - { + if PyInt_Check(value) { + int rgba = PyInt_AsLong(value); m_vertex->SetRGBA(rgba); m_mesh->SetMeshModified(true); - Py_Return; + Py_RETURN_NONE; + } + else { + MT_Vector4 vec; + if (PyVecTo(value, vec)) + { + m_vertex->SetRGBA(vec); + m_mesh->SetMeshModified(true); + Py_RETURN_NONE; + } } + PyErr_SetString(PyExc_TypeError, "expected a 4D vector or an int"); return NULL; } -PyObject* KX_VertexProxy::PyGetUV(PyObject*, - PyObject*, - PyObject*) +PyObject* KX_VertexProxy::PyGetUV(PyObject*) { return PyObjectFrom(MT_Vector2(m_vertex->getUV1())); } -PyObject* KX_VertexProxy::PySetUV(PyObject*, - PyObject* args, - PyObject*) +PyObject* KX_VertexProxy::PySetUV(PyObject*, PyObject* value) { MT_Point2 vec; - if (PyVecArgTo(args, vec)) - { - m_vertex->SetUV(vec); - m_mesh->SetMeshModified(true); - Py_Return; - } + if (!PyVecTo(value, vec)) + return NULL; - return NULL; + m_vertex->SetUV(vec); + m_mesh->SetMeshModified(true); + Py_RETURN_NONE; } -PyObject* KX_VertexProxy::PyGetUV2(PyObject*, - PyObject*, - PyObject*) +PyObject* KX_VertexProxy::PyGetUV2(PyObject*) { return PyObjectFrom(MT_Vector2(m_vertex->getUV2())); } -PyObject* KX_VertexProxy::PySetUV2(PyObject*, - PyObject* args, - PyObject*) +PyObject* KX_VertexProxy::PySetUV2(PyObject*, PyObject* args) { MT_Point2 vec; unsigned int unit=0; - PyObject* list=0; - if(PyArg_ParseTuple(args, "Oi", &list, &unit)) - { - if (PyVecTo(list, vec)) - { - m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV)); - m_vertex->SetUnit(unit); - m_vertex->SetUV2(vec); - m_mesh->SetMeshModified(true); - Py_Return; - } - } - return NULL; + PyObject* list= NULL; + if(!PyArg_ParseTuple(args, "Oi:setUV2", &list, &unit)) + return NULL; + + if (!PyVecTo(list, vec)) + return NULL; + + m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV)); + m_vertex->SetUnit(unit); + m_vertex->SetUV2(vec); + m_mesh->SetMeshModified(true); + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index e154ea11b40..28196075904 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -54,21 +54,21 @@ public: // stuff for python integration - virtual PyObject* _getattr(const STR_String& attr); - virtual int _setattr(const STR_String& attr, PyObject *pyvalue); + virtual PyObject* _getattr(const char *attr); + virtual int _setattr(const char *attr, PyObject *pyvalue); - KX_PYMETHOD(KX_VertexProxy,GetXYZ); - KX_PYMETHOD(KX_VertexProxy,SetXYZ); - KX_PYMETHOD(KX_VertexProxy,GetUV); - KX_PYMETHOD(KX_VertexProxy,SetUV); + KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ); + KX_PYMETHOD_O(KX_VertexProxy,SetXYZ); + KX_PYMETHOD_NOARGS(KX_VertexProxy,GetUV); + KX_PYMETHOD_O(KX_VertexProxy,SetUV); - KX_PYMETHOD(KX_VertexProxy,GetUV2); - KX_PYMETHOD(KX_VertexProxy,SetUV2); + KX_PYMETHOD_NOARGS(KX_VertexProxy,GetUV2); + KX_PYMETHOD_VARARGS(KX_VertexProxy,SetUV2); - KX_PYMETHOD(KX_VertexProxy,GetRGBA); - KX_PYMETHOD(KX_VertexProxy,SetRGBA); - KX_PYMETHOD(KX_VertexProxy,GetNormal); - KX_PYMETHOD(KX_VertexProxy,SetNormal); + KX_PYMETHOD_NOARGS(KX_VertexProxy,GetRGBA); + KX_PYMETHOD_O(KX_VertexProxy,SetRGBA); + KX_PYMETHOD_NOARGS(KX_VertexProxy,GetNormal); + KX_PYMETHOD_O(KX_VertexProxy,SetNormal); }; diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index 4b0db5a7953..0ec280080bd 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -126,10 +126,11 @@ KX_VisibilityActuator::Methods[] = { {NULL,NULL} //Sentinel }; -PyObject* -KX_VisibilityActuator::_getattr( - const STR_String& attr - ) +PyAttributeDef KX_VisibilityActuator::Attributes[] = { + { NULL } //Sentinel +}; + +PyObject* KX_VisibilityActuator::_getattr(const char *attr) { _getattr_up(SCA_IActuator); }; @@ -155,7 +156,7 @@ KX_VisibilityActuator::PySetVisible(PyObject* self, m_visible = PyArgToBool(vis); - Py_Return; + Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h index d1b85ab998c..323280de8cb 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.h +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -67,7 +67,7 @@ class KX_VisibilityActuator : public SCA_IActuator /* Python interface ---------------------------------------------------- */ /* --------------------------------------------------------------------- */ - virtual PyObject* _getattr(const STR_String& attr); + virtual PyObject* _getattr(const char *attr); //KX_PYMETHOD_DOC KX_PYMETHOD_DOC(KX_VisibilityActuator,SetVisible); diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 13a0d321cff..950c82b2795 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -4,6 +4,7 @@ import sys Import ('env') sources = env.Glob('*.cpp') +defs = '' #XXX # Mathutils C files. @@ -31,21 +32,27 @@ incs += ' #source/blender/makesdna #source/blender/python #source/gameengine/Ras incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/gameengine/Network' incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common #source/gameengine/Physics/Bullet' incs += ' #source/gameengine/Physics/BlOde #source/gameengine/Physics/Dummy' -incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include' -incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include #source/blender/gpu' -cflags = [] -if env['OURPLATFORM'] == 'win32-vc': - cflags.append('/GR') - cflags.append('/Ox') +if env['WITH_BF_SOLID']: + incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include' + incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork' + incs += ' ' + env['BF_SOLID_INC'] + defs += ' USE_SUMO_SOLID' + -incs += ' ' + env['BF_SOLID_INC'] incs += ' ' + env['BF_PYTHON_INC'] incs += ' ' + env['BF_BULLET_INC'] incs += ' ' + env['BF_OPENGL_INC'] if env['WITH_BF_SDL']: incs += ' ' + env['BF_SDL_INC'] - -env.BlenderLib ( 'bf_ketsji', sources, Split(incs), [], libtype=['core','player'], priority=[320, 60], compileflags = cflags ) +else: + defs += ' DISABLE_SDL' + +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_ketsji', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[320, 60], cxx_compileflags = cxxflags ) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index d09ad58fe3b..eecdea55349 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1240,7 +1240,7 @@ void DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,flo void DefaultMotionState::setWorldPosition(float posX,float posY,float posZ) { - btPoint3 pos(posX,posY,posZ); + btVector3 pos(posX,posY,posZ); m_worldTransform.setOrigin( pos ); } @@ -1328,7 +1328,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo for (int i=0;i<poly->VertexCount();i++) { const float* vtx = poly->GetVertex(i)->getXYZ(); - btPoint3 point(vtx[0],vtx[1],vtx[2]); + btVector3 point(vtx[0],vtx[1],vtx[2]); //avoid duplicates (could better directly use vertex offsets, rather than a vertex compare) bool found = false; for (int j=0;j<m_vertexArray.size();j++) @@ -1348,13 +1348,13 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo { { const float* vtx = poly->GetVertex(2)->getXYZ(); - btPoint3 vertex0(vtx[0],vtx[1],vtx[2]); + btVector3 vertex0(vtx[0],vtx[1],vtx[2]); vtx = poly->GetVertex(1)->getXYZ(); - btPoint3 vertex1(vtx[0],vtx[1],vtx[2]); + btVector3 vertex1(vtx[0],vtx[1],vtx[2]); vtx = poly->GetVertex(0)->getXYZ(); - btPoint3 vertex2(vtx[0],vtx[1],vtx[2]); + btVector3 vertex2(vtx[0],vtx[1],vtx[2]); m_vertexArray.push_back(vertex0); m_vertexArray.push_back(vertex1); @@ -1365,13 +1365,13 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo if (poly->VertexCount() == 4) { const float* vtx = poly->GetVertex(3)->getXYZ(); - btPoint3 vertex0(vtx[0],vtx[1],vtx[2]); + btVector3 vertex0(vtx[0],vtx[1],vtx[2]); vtx = poly->GetVertex(2)->getXYZ(); - btPoint3 vertex1(vtx[0],vtx[1],vtx[2]); + btVector3 vertex1(vtx[0],vtx[1],vtx[2]); vtx = poly->GetVertex(0)->getXYZ(); - btPoint3 vertex2(vtx[0],vtx[1],vtx[2]); + btVector3 vertex2(vtx[0],vtx[1],vtx[2]); m_vertexArray.push_back(vertex0); m_vertexArray.push_back(vertex1); @@ -1442,7 +1442,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() break; case PHY_SHAPE_POLYTOPE: - collisionShape = new btConvexHullShape(&m_vertexArray.begin()->getX(), m_vertexArray.size()); + collisionShape = new btConvexHullShape(&m_vertexArray[0].getX(), m_vertexArray.size()); break; case PHY_SHAPE_MESH: @@ -1457,12 +1457,14 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() { collisionMeshData = new btTriangleMesh(); + bool removeDuplicateVertices=true; // m_vertexArray is necessarily a multiple of 3 - for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); ) + for (int i=0;i<m_vertexArray.size(); i+=3 ) { - collisionMeshData->addTriangle(*it++,*it++,*it++); + collisionMeshData->addTriangle(m_vertexArray[i+2],m_vertexArray[i+1],m_vertexArray[i],removeDuplicateVertices); } + btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(collisionMeshData); collisionShape = gimpactShape; @@ -1475,10 +1477,11 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape() collisionMeshData = new btTriangleMesh(true,false); collisionMeshData->m_weldingThreshold = m_weldingThreshold; + bool removeDuplicateVertices=true; // m_vertexArray is necessarily a multiple of 3 - for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); ) + for (int i=0;i<m_vertexArray.size(); i+=3 ) { - collisionMeshData->addTriangle(*it++,*it++,*it++); + collisionMeshData->addTriangle(m_vertexArray[i+2],m_vertexArray[i+1],m_vertexArray[i],removeDuplicateVertices); } // this shape will be shared and not deleted until shapeInfo is deleted m_unscaledShape = new btBvhTriangleMeshShape( collisionMeshData, true ); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index c771aa2624b..deb3c0880e9 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -161,7 +161,7 @@ public: btTransform m_childTrans; btVector3 m_childScale; void* m_userData; - std::vector<btPoint3> m_vertexArray; // Contains both vertex array for polytope shape and + btAlignedObjectArray<btVector3> m_vertexArray; // Contains both vertex array for polytope shape and // triangle array for concave mesh shape. // In this case a triangle is made of 3 consecutive points std::vector<int> m_polygonIndexArray; // Contains the array of polygon index in the diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index d2274c1e8d6..dd21e58bd68 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -317,8 +317,8 @@ static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVec CcdPhysicsEnvironment::CcdPhysicsEnvironment(btDispatcher* dispatcher,btOverlappingPairCache* pairCache) -:m_scalingPropagated(false), -m_numIterations(10), +:m_numIterations(10), +m_scalingPropagated(false), m_numTimeSubSteps(1), m_ccdMode(0), m_solverType(-1), @@ -326,8 +326,8 @@ m_profileTimings(0), m_enableSatCollisionDetection(false), m_solver(NULL), m_ownPairCache(NULL), -m_ownDispatcher(NULL), -m_filterCallback(NULL) +m_filterCallback(NULL), +m_ownDispatcher(NULL) { for (int i=0;i<PHY_NUM_RESPONSE;i++) @@ -337,6 +337,7 @@ m_filterCallback(NULL) // m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + //m_collisionConfiguration->setConvexConvexMultipointIterations(); if (!dispatcher) { @@ -356,6 +357,8 @@ m_filterCallback(NULL) setSolverType(1);//issues with quickstep and memory allocations // m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + //m_dynamicsWorld->getSolverInfo().m_linearSlop = 0.01f; + //m_dynamicsWorld->getSolverInfo().m_solverMode= SOLVER_USE_WARMSTARTING + SOLVER_USE_2_FRICTION_DIRECTIONS + SOLVER_RANDMIZE_ORDER + SOLVER_USE_FRICTION_WARMSTARTING; m_debugDrawer = 0; m_gravity = btVector3(0.f,-10.f,0.f); @@ -414,7 +417,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl) const btTransform& t = ctrl->GetCollisionObject()->getWorldTransform(); - btPoint3 minAabb,maxAabb; + btVector3 minAabb,maxAabb; shapeinterface->getAabb(t,minAabb,maxAabb); @@ -560,6 +563,11 @@ void CcdPhysicsEnvironment::beginFrame() } +void CcdPhysicsEnvironment::debugDrawWorld() +{ + if (m_dynamicsWorld->getDebugDrawer() && m_dynamicsWorld->getDebugDrawer()->getDebugMode() >0) + m_dynamicsWorld->debugDrawWorld(); +} bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) { @@ -596,9 +604,6 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep) veh->SyncWheels(); } - if (m_dynamicsWorld->getDebugDrawer() && m_dynamicsWorld->getDebugDrawer()->getDebugMode() >0) - m_dynamicsWorld->debugDrawWorld(); - CallbackTriggers(); @@ -845,7 +850,8 @@ void CcdPhysicsEnvironment::setSolverType(int solverType) { m_solver = new btSequentialImpulseConstraintSolver(); -// ((btSequentialImpulseConstraintSolver*)m_solver)->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); + + break; } } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 4b28d3fddfc..2f1f0bb254b 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -110,6 +110,8 @@ protected: virtual void endFrame() {}; /// Perform an integration step of duration 'timeStep'. virtual bool proceedDeltaTime(double curTime,float timeStep); + + virtual void debugDrawWorld(); // virtual bool proceedDeltaTimeOneStep(float timeStep); virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep){}; diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index 51dbb4d86da..db9f3387bfe 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -7,9 +7,9 @@ incs = '. ../common #source/kernel/gen_system #intern/string #intern/moto/includ incs += ' ' + env['BF_BULLET_INC'] -cflags = [] +cxxflags = [] if env['OURPLATFORM']=='win32-vc': - cflags.append('/GR') - cflags.append('/O2') + cxxflags.append ('/GR') + cxxflags.append ('/O2') -env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360,80] ) +env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,80], cxx_compileflags=cxxflags ) diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h index 2326bdee523..3d8eef2bae0 100644 --- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h +++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h @@ -46,7 +46,7 @@ #include "SM_Object.h" -typedef enum +enum { FH_RESPONSE, SENSOR_RESPONSE, /* Touch Sensors */ diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h index 09126264dcc..c5cf92b553a 100644 --- a/source/gameengine/Physics/common/PHY_DynamicTypes.h +++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h @@ -36,7 +36,7 @@ struct PHY__Vector3 }; //typedef float PHY__Vector3[4]; -typedef enum +enum { PHY_FH_RESPONSE, PHY_SENSOR_RESPONSE, /* Touch Sensors */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 0e9c571924c..226ba3a7e74 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -90,6 +90,8 @@ class PHY_IPhysicsEnvironment virtual void endFrame() = 0; /// Perform an integration step of duration 'timeStep'. virtual bool proceedDeltaTime(double curTime,float timeStep)=0; + ///draw debug lines (make sure to call this during the render phase, otherwise lines are not drawn properly) + virtual void debugDrawWorld(){} virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)=0; //returns 0.f if no fixed timestep is used virtual float getFixedTimeStep()=0; diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index aead31fb73e..4d7c808f49b 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/SConscript @@ -5,4 +5,9 @@ sources = 'PHY_IMotionState.cpp PHY_IPhysicsController.cpp PHY_IPhysicsEnvironme incs = '. ../Dummy #intern/moto/include' -env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 90] ) +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags = cxxflags ) diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 9dab7db6081..0524a9df355 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -140,6 +140,14 @@ Documentation for the GameLogic Module. @var KX_SOUNDACT_LOOPEND: See L{KX_SoundActuator} @var KX_SOUNDACT_LOOPBIDIRECTIONAL: See L{KX_SoundActuator} @var KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: See L{KX_SoundActuator} + +@group Radar Sensor: KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z +@var KX_RADAR_AXIS_POS_X: See L{KX_RadarSensor} +@var KX_RADAR_AXIS_POS_Y: See L{KX_RadarSensor} +@var KX_RADAR_AXIS_POS_Z: See L{KX_RadarSensor} +@var KX_RADAR_AXIS_NEG_X: See L{KX_RadarSensor} +@var KX_RADAR_AXIS_NEG_Y: See L{KX_RadarSensor} +@var KX_RADAR_AXIS_NEG_Z: See L{KX_RadarSensor} """ @@ -159,7 +167,7 @@ def addActiveActuator(actuator, activate): """ Activates the given actuator. - @type actuator: L{SCA_IActuator} + @type actuator: L{SCA_IActuator} or the actuator name as a string. @type activate: boolean @param activate: whether to activate or deactivate the given actuator. """ diff --git a/source/gameengine/PyDoc/KX_CameraActuator.py b/source/gameengine/PyDoc/KX_CameraActuator.py index 9a9abaf3d57..6ffc55a5854 100644 --- a/source/gameengine/PyDoc/KX_CameraActuator.py +++ b/source/gameengine/PyDoc/KX_CameraActuator.py @@ -6,6 +6,16 @@ class KX_CameraActuator(SCA_IActuator): """ Applies changes to a camera. + @ivar min: minimum distance to the target object maintained by the actuator + @type min: float + @ivar max: maximum distance to stay from the target object + @type max: float + @ivar height: height to stay above the target object + @type height: float + @ivar xy: axis this actuator is tracking, true=X, false=Y + @type xy: boolean + @ivar object: the object this actuator tracks. + @type object: KX_GameObject or None @author: snail """ def getObject(name_only = 1): diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index efeffab2eed..4f389a1ae4f 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -7,7 +7,7 @@ class KX_GameObject: Properties assigned to game objects are accessible as attributes of this class. - @ivar name: The object's name. + @ivar name: The object's name. (Read only) @type name: string. @ivar mass: The object's mass (provided the object has a physics controller). Read only. @type mass: float diff --git a/source/gameengine/PyDoc/KX_NearSensor.py b/source/gameengine/PyDoc/KX_NearSensor.py index fef2e4b2acc..a8c408827fe 100644 --- a/source/gameengine/PyDoc/KX_NearSensor.py +++ b/source/gameengine/PyDoc/KX_NearSensor.py @@ -5,5 +5,10 @@ from KX_TouchSensor import * class KX_NearSensor(KX_TouchSensor): """ A near sensor is a specialised form of touch sensor. + + @ivar distance: The near sensor activates when an object is within this distance. + @type distance: float + @ivar resetDistance: The near sensor deactivates when the object exceeds this distance. + @type resetDistance: float """ diff --git a/source/gameengine/PyDoc/KX_ParentActuator.py b/source/gameengine/PyDoc/KX_ParentActuator.py index 6d6e0937257..7b5625ec82d 100644 --- a/source/gameengine/PyDoc/KX_ParentActuator.py +++ b/source/gameengine/PyDoc/KX_ParentActuator.py @@ -5,6 +5,9 @@ from SCA_IActuator import * class KX_ParentActuator(SCA_IActuator): """ The parent actuator can set or remove an objects parent object. + + @ivar object: the object this actuator sets the parent too. + @type object: KX_GameObject or None """ def setObject(object): """ diff --git a/source/gameengine/PyDoc/KX_RadarSensor.py b/source/gameengine/PyDoc/KX_RadarSensor.py index 64be858371a..b68bf4ea0f3 100644 --- a/source/gameengine/PyDoc/KX_RadarSensor.py +++ b/source/gameengine/PyDoc/KX_RadarSensor.py @@ -5,8 +5,26 @@ from KX_NearSensor import * class KX_RadarSensor(KX_NearSensor): """ Radar sensor is a near sensor with a conical sensor object. + + @ivar coneOrigin: The origin of the cone with which to test. The origin + is in the middle of the cone. + (Read only) + @type coneOrigin: list of floats [x, y, z] + @ivar coneTarget: The center of the bottom face of the cone with which to test. + (Read only) + @type coneTarget: list of floats [x, y, z] + @ivar distance: The height of the cone with which to test. + @type distance: float + @ivar angle: The angle of the cone (in degrees) with which to test. + @type angle: float from 0 to 360 + @ivar axis: The axis on which the radar cone is cast + @type axis: int from 0 to 5 + KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, + KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z """ + + #--The following methods are deprecated, please use properties instead. def getConeOrigin(): """ Returns the origin of the cone with which to test. The origin diff --git a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py index c3b2e947ddb..56068fa641a 100644 --- a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py +++ b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py @@ -5,6 +5,10 @@ from SCA_IActuator import * class KX_SCA_AddObjectActuator(SCA_IActuator): """ Edit Object Actuator (in Add Object Mode) + @ivar object: the object this actuator adds. + @type object: KX_GameObject or None + @ivar objectLastCreated: the last added object from this actuator (read only). + @type objectLastCreated: KX_GameObject or None @warning: An Add Object actuator will be ignored if at game start, the linked object doesn't exist (or is empty) or the linked object is in an active layer. diff --git a/source/gameengine/PyDoc/KX_Scene.py b/source/gameengine/PyDoc/KX_Scene.py index 4a0a7a9556d..5e357e6eefc 100644 --- a/source/gameengine/PyDoc/KX_Scene.py +++ b/source/gameengine/PyDoc/KX_Scene.py @@ -39,6 +39,8 @@ class KX_Scene: @ivar name: The scene's name @type name: string + @type objects: A list of objects in the scene. + @type objects: list [L{KX_GameObject}] @ivar active_camera: The current active camera @type active_camera: L{KX_Camera} @ivar suspended: True if the scene is suspended. @@ -68,3 +70,16 @@ class KX_Scene: @rtype: string """ + def addObject(object, other, time=0) + """ + Adds an object to the scene like the Add Object Actuator would, and returns the created object. + + @param object: The object to add + @type object: L{KX_GameObject} or string + @param other: The object's center to use when adding the object + @type other: L{KX_GameObject} or string + @param time: The lifetime of the added object, in frames. A time of 0 means the object will last forever. + @type time: int + + @rtype: L{KX_GameObject} + """ diff --git a/source/gameengine/PyDoc/KX_TouchSensor.py b/source/gameengine/PyDoc/KX_TouchSensor.py index f2cc101af10..d7277be4c2a 100644 --- a/source/gameengine/PyDoc/KX_TouchSensor.py +++ b/source/gameengine/PyDoc/KX_TouchSensor.py @@ -1,36 +1,55 @@ # $Id$ # Documentation for KX_TouchSensor from SCA_ISensor import * +from KX_GameObject import * class KX_TouchSensor(SCA_ISensor): """ Touch sensor detects collisions between objects. + + @ivar property: The property or material to collide with. + @type property: string + @ivar useMaterial: Determines if the sensor is looking for a property or material. + KX_True = Find material; KX_False = Find property + @type useMaterial: boolean + @ivar pulseCollisions: The last collided object. + @type pulseCollisions: bool + @ivar objectHit: The last collided object. (Read Only) + @type objectHit: L{KX_GameObject} or None + @ivar objectHitList: A list of colliding objects. (Read Only) + @type objectHitList: list """ + + #--The following methods are deprecated, please use properties instead. def setProperty(name): """ + DEPRECATED: use the property property Set the property or material to collide with. Use setTouchMaterial() to switch between properties and materials. @type name: string """ + def getProperty(): """ + DEPRECATED: use the property property Returns the property or material to collide with. Use getTouchMaterial() to find out whether this sensor - looks for properties or materials. + looks for properties or materials. (B{deprecated}) @rtype: string """ - def getHitObject(): """ - Returns the last object hit by this touch sensor. + DEPRECATED: use the objectHit property + Returns the last object hit by this touch sensor. (B{deprecated}) @rtype: L{KX_GameObject} """ def getHitObjectList(): """ - Returns a list of all objects hit in the last frame. + DEPRECATED: use the objectHitList property + Returns a list of all objects hit in the last frame. (B{deprecated}) Only objects that have the requisite material/property are listed. @@ -38,13 +57,7 @@ class KX_TouchSensor(SCA_ISensor): """ def getTouchMaterial(): """ + DEPRECATED: use the useMaterial property Returns KX_TRUE if this sensor looks for a specific material, - KX_FALSE if it looks for a specific property. - """ - def setTouchMaterial(flag): - """ - Set flag to KX_TRUE to switch on positive pulse mode, - KX_FALSE to switch off positive pulse mode. - - @type flag: KX_TRUE or KX_FALSE. + KX_FALSE if it looks for a specific property. (B{deprecated}) """ diff --git a/source/gameengine/PyDoc/KX_TrackToActuator.py b/source/gameengine/PyDoc/KX_TrackToActuator.py index 948302991b7..730ab21166b 100644 --- a/source/gameengine/PyDoc/KX_TrackToActuator.py +++ b/source/gameengine/PyDoc/KX_TrackToActuator.py @@ -13,6 +13,8 @@ class KX_TrackToActuator(SCA_IActuator): C{ERROR: GameObject I{OBName} no object in EditObjectActuator I{ActuatorName}} + @ivar object: the object this actuator tracks. + @type object: KX_GameObject or None """ def setObject(object): """ diff --git a/source/gameengine/PyDoc/SCA_DelaySensor.py b/source/gameengine/PyDoc/SCA_DelaySensor.py index b99ed08bed5..6560df6573e 100644 --- a/source/gameengine/PyDoc/SCA_DelaySensor.py +++ b/source/gameengine/PyDoc/SCA_DelaySensor.py @@ -20,10 +20,9 @@ class SCA_DelaySensor(SCA_ISensor): @type delay: integer. @ivar duration: length of the ON period in number of frame after the initial OFF period. If duration is greater than 0, a negative trigger is sent at the end of the ON pulse. - @type duration: integer - @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. - @type repeat: integer - + @type duration: integer + @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once. + @type repeat: integer """ def setDelay(delay): """ diff --git a/source/gameengine/PyDoc/SCA_PythonController.py b/source/gameengine/PyDoc/SCA_PythonController.py index 06f2b7e9d1d..9684b41d481 100644 --- a/source/gameengine/PyDoc/SCA_PythonController.py +++ b/source/gameengine/PyDoc/SCA_PythonController.py @@ -15,7 +15,17 @@ class SCA_PythonController(SCA_IController): This can be used with the GameObject's state to test if the controller is active. @type state: integer """ - + def activate(actuator): + """ + Activates an actuator attached to this controller. + @type actuator: actuator or the actuator name as a string + """ + def deactivate(actuator): + """ + Deactivates an actuator attached to this controller. + @type actuator: actuator or the actuator name as a string + """ + def getSensors(): """ Gets a list of all sensors attached to this controller. diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index fb3607f89f4..cd88112007b 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -143,7 +143,7 @@ const STR_String& RAS_IPolyMaterial::GetTextureName() const return m_texturename; } -const unsigned int RAS_IPolyMaterial::GetFlag() const +unsigned int RAS_IPolyMaterial::GetFlag() const { return m_flag; } diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 218dd91cb30..e5b24070c4b 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -138,7 +138,7 @@ public: const STR_String& GetMaterialName() const; dword GetMaterialNameHash() const; const STR_String& GetTextureName() const; - const unsigned int GetFlag() const; + unsigned int GetFlag() const; virtual bool UsesLighting(RAS_IRasterizer *rasty) const; virtual bool UsesObjectColor() const; diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index b4b90c3608b..83adcfd8321 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -255,6 +255,8 @@ public: /** */ virtual const MT_Point3& GetCameraPosition()=0; + virtual bool GetCameraOrtho()=0; + /** */ virtual void SetFog(float start, @@ -359,6 +361,8 @@ public: virtual void SetPolygonOffset(float mult, float add) = 0; virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)=0; + virtual void FlushDebugLines()=0; + virtual void SetTexCoordNum(int num) = 0; diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index 57f331e64cb..a289ffed492 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -134,6 +134,7 @@ public: virtual void ProcessLighting( + RAS_IRasterizer *rasty, int layer, const MT_Transform& trans )=0; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index ad8d7ebd5b0..d8631c1edf6 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -517,9 +517,9 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I return false; if (m_material->UsesLighting(rasty)) - rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER, cameratrans); + rendertools->ProcessLighting(rasty, RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER, cameratrans); else - rendertools->ProcessLighting(-1, cameratrans); + rendertools->ProcessLighting(rasty, -1, cameratrans); return true; } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 3cad5fe74f2..d4d1b73c772 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -59,6 +59,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_2DCanvas(canvas), m_fogenabled(false), m_time(0.0), + m_campos(0.0f, 0.0f, 0.0f), + m_camortho(false), m_stereomode(RAS_STEREO_NOSTEREO), m_curreye(RAS_STEREO_LEFTEYE), m_eyeseparation(0.0), @@ -325,13 +327,12 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void) m_materialCachingInfo = 0; } - -void RAS_OpenGLRasterizer::EndFrame() +void RAS_OpenGLRasterizer::FlushDebugLines() { +//DrawDebugLines glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); - //DrawDebugLines glBegin(GL_LINES); for (unsigned int i=0;i<m_debugLines.size();i++) { @@ -346,8 +347,19 @@ void RAS_OpenGLRasterizer::EndFrame() } glEnd(); + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + m_debugLines.clear(); +} + +void RAS_OpenGLRasterizer::EndFrame() +{ + + + FlushDebugLines(); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); m_2DCanvas->EndFrame(); } @@ -756,8 +768,9 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) glMatrixMode(GL_PROJECTION); double* matrix = &mat(0,0); glLoadMatrixd(matrix); -} + m_camortho= (mat(3, 3) != 0.0f); +} void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) { @@ -767,6 +780,8 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) mat.getValue(matrix); /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */ glLoadMatrixd(matrix); + + m_camortho= (mat[3][3] != 0.0f); } MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( @@ -883,6 +898,10 @@ const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition() return m_campos; } +bool RAS_OpenGLRasterizer::GetCameraOrtho() +{ + return m_camortho; +} void RAS_OpenGLRasterizer::SetCullFace(bool enable) { diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index d39fd642f86..83a9f759a8b 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -80,6 +80,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer MT_Matrix4x4 m_viewmatrix; MT_Matrix4x4 m_viewinvmatrix; MT_Point3 m_campos; + bool m_camortho; StereoMode m_stereomode; StereoEye m_curreye; @@ -168,6 +169,7 @@ public: ); virtual const MT_Point3& GetCameraPosition(); + virtual bool GetCameraOrtho(); virtual void SetFog( float start, @@ -238,6 +240,8 @@ public: virtual void SetPolygonOffset(float mult, float add); + virtual void FlushDebugLines(); + virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) { OglDebugLine line; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript index b9358ffde6b..c0b73e7644f 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript @@ -6,4 +6,9 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines ' incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC'] -env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115] ) +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115], cxx_compileflags = cxxflags ) diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index b92965ed1cc..210addfb927 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -59,10 +59,10 @@ const MT_Point3& RAS_TexVert::xyz() void RAS_TexVert::SetRGBA(const MT_Vector4& rgba) { unsigned char *colp = (unsigned char*) &m_rgba; - colp[0] = (unsigned char) (rgba[0]*255.0); - colp[1] = (unsigned char) (rgba[1]*255.0); - colp[2] = (unsigned char) (rgba[2]*255.0); - colp[3] = (unsigned char) (rgba[3]*255.0); + colp[0] = (unsigned char) (rgba[0]*255.0f); + colp[1] = (unsigned char) (rgba[1]*255.0f); + colp[2] = (unsigned char) (rgba[2]*255.0f); + colp[3] = (unsigned char) (rgba[3]*255.0f); } @@ -71,7 +71,10 @@ void RAS_TexVert::SetXYZ(const MT_Point3& xyz) xyz.getValue(m_localxyz); } - +void RAS_TexVert::SetXYZ(const float *xyz) +{ + m_localxyz[0]= xyz[0]; m_localxyz[1]= xyz[1]; m_localxyz[2]= xyz[2]; +} void RAS_TexVert::SetUV(const MT_Point2& uv) { @@ -111,15 +114,18 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent) } // compare two vertices, and return TRUE if both are almost identical (they can be shared) +#define _VEC_EQUAL3(_v1, _v2) (_v1[0]==_v2[0] && _v1[1]==_v2[1] && _v1[2]==_v2[2]) +#define _VEC_EQUAL2(_v1, _v2) (_v1[0]==_v2[0] && _v1[1]==_v2[1]) bool RAS_TexVert::closeTo(const RAS_TexVert* other) { return (m_flag == other->m_flag && m_rgba == other->m_rgba && - MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) && - MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) && - MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) && - MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) && // p -- - MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))) ; + _VEC_EQUAL3(m_normal, other->m_normal) && + _VEC_EQUAL3(m_tangent, other->m_tangent) && + _VEC_EQUAL2(m_uv1, other->m_uv1) && + _VEC_EQUAL2(m_uv2, other->m_uv2) // p -- + /* we know the verts must be shared so dont need to check this */ + /*&& FAST_MT_fuzzyEqual3(m_localxyz, other->m_localxyz)*/) ; } short RAS_TexVert::getFlag() const diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 54da109cbf1..811867f3579 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -110,11 +110,12 @@ public: return (unsigned char *) &m_rgba; } - const unsigned int getOrigIndex() const { + unsigned int getOrigIndex() const { return m_origindex; } void SetXYZ(const MT_Point3& xyz); + void SetXYZ(const float *xyz); void SetUV(const MT_Point2& uv); void SetUV2(const MT_Point2& uv); diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index ebb2f28ec16..9f4cd61e7bb 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -7,9 +7,9 @@ sources = env.Glob('*.cpp') incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/blender/blenkernel #source/blender/makesdna' incs += ' ' + env['BF_PYTHON_INC'] +cxxflags = [] if env['OURPLATFORM']=='win32-vc': - cflags = [] - cflags.append('/Ox') - env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], compileflags = cflags ) -else: - env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115] ) + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], cxx_compileflags = cxxflags ) diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript index 39824cac1aa..864e4c3ebee 100644 --- a/source/gameengine/SConscript +++ b/source/gameengine/SConscript @@ -15,10 +15,12 @@ SConscript(['BlenderRoutines/SConscript', 'Rasterizer/RAS_OpenGLRasterizer/SConscript', 'SceneGraph/SConscript', 'Physics/Bullet/SConscript', - 'Physics/Sumo/SConscript', 'VideoTexture/SConscript' ]) +if env['WITH_BF_SOLID']: + SConscript(['Physics/Sumo/SConscript']) + if env['WITH_BF_PLAYER']: SConscript(['GamePlayer/SConscript']) diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index a0733b6c51c..0692b170a61 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/SConscript @@ -6,4 +6,9 @@ sources = env.Glob('*.cpp') incs = '. #intern/moto/include' -env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[280,125] ) +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + +env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,125], cxx_compileflags = cxxflags ) diff --git a/source/gameengine/SceneGraph/SG_BBox.cpp b/source/gameengine/SceneGraph/SG_BBox.cpp index 4bd2805978e..a44262d04f7 100644 --- a/source/gameengine/SceneGraph/SG_BBox.cpp +++ b/source/gameengine/SceneGraph/SG_BBox.cpp @@ -34,8 +34,8 @@ #include "SG_Node.h" SG_BBox::SG_BBox() : - m_min(MT_Point3(0., 0., 0.)), - m_max(MT_Point3(0., 0., 0.)) + m_min(0., 0., 0.), + m_max(0., 0., 0.) { } diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index 5ba116e59db..99aeb3e72ee 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -44,13 +44,13 @@ SG_Spatial( ): SG_IObject(clientobj,clientinfo,callbacks), - m_localPosition(MT_Point3(0.0,0.0,0.0)), - m_localRotation(MT_Matrix3x3(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0)), - m_localScaling(MT_Vector3(1.f,1.f,1.f)), + m_localPosition(0.0,0.0,0.0), + m_localRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0), + m_localScaling(1.f,1.f,1.f), - m_worldPosition(MT_Point3(0.0,0.0,0.0)), - m_worldRotation(MT_Matrix3x3(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0)), - m_worldScaling(MT_Vector3(1.f,1.f,1.f)), + m_worldPosition(0.0,0.0,0.0), + m_worldRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0), + m_worldScaling(1.f,1.f,1.f), m_parent_relation (NULL), @@ -297,6 +297,13 @@ GetWorldScaling( return m_worldScaling; } +void SG_Spatial::SetWorldFromLocalTransform() +{ + m_worldPosition= m_localPosition; + m_worldScaling= m_localScaling; + m_worldRotation= m_localRotation; +} + SG_BBox& SG_Spatial::BBox() { return m_bbox; diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index 28848b0f933..6ccec2aa9c1 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -176,6 +176,8 @@ public: GetWorldScaling( ) const ; + void SetWorldFromLocalTransform(); + MT_Transform GetWorldTransform() const; bool ComputeWorldTransforms( const SG_Spatial *parent); diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt index 12b6b83cabe..9d1bb89d2ca 100644 --- a/source/gameengine/VideoTexture/CMakeLists.txt +++ b/source/gameengine/VideoTexture/CMakeLists.txt @@ -53,7 +53,7 @@ SET(INC ) IF(WITH_FFMPEG) - SET(INC ${INC} ${FFMPEG_INC}) + SET(INC ${INC} ${FFMPEG_INC} ${PTHREADS_INC}) ADD_DEFINITIONS(-DWITH_FFMPEG) ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS) ENDIF(WITH_FFMPEG) diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp index b0112cd355b..b2abd4354fd 100644 --- a/source/gameengine/VideoTexture/FilterBase.cpp +++ b/source/gameengine/VideoTexture/FilterBase.cpp @@ -69,7 +69,7 @@ FilterBase * FilterBase::findFirst (void) { // find first filter in chain FilterBase * frst; - for (frst = this; frst->m_previous != NULL; frst = frst->m_previous->m_filter); + for (frst = this; frst->m_previous != NULL; frst = frst->m_previous->m_filter) {}; // set first filter return frst; } diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index 7e90747d252..6385ed5108f 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -189,9 +189,10 @@ protected: int d = m_buffU[offset] - 128; int e = m_buffV[offset] - 128; // if horizontal interpolation is needed - if ((x & 1) == 1) + if ((x & 1) == 1) { // if vertical interpolation is needed too if ((y & 1) == 1) + { // if this pixel is on the edge if (isEdge(x, y, size)) { @@ -206,7 +207,8 @@ protected: e = interpolVH(m_buffV + offset) - 128; } // otherwise use horizontal interpolation only - else + } + else { // if this pixel is on the edge if (isEdge(x, y, size)) { @@ -221,6 +223,8 @@ protected: e = interpolH(m_buffV + offset) - 128; } // otherwise if only vertical interpolation is needed + } + } else if ((y & 1) == 1) // if this pixel is on the edge if (isEdge(x, y, size)) diff --git a/source/gameengine/VideoTexture/Makefile b/source/gameengine/VideoTexture/Makefile index e4a70428c60..8677ed5c177 100644 --- a/source/gameengine/VideoTexture/Makefile +++ b/source/gameengine/VideoTexture/Makefile @@ -60,6 +60,9 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include ifeq ($(WITH_FFMPEG),true) CPPFLAGS += -DWITH_FFMPEG CPPFLAGS += $(NAN_FFMPEGCFLAGS) + ifdef NAN_PTHREADS + CPPFLAGS += -I$(NAN_PTHREADS)/include + endif endif diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index 36bb1ea6257..920da8ffb2e 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -15,18 +15,19 @@ incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/m incs += ' #intern/guardedalloc #intern/SoundSystem' incs += ' #extern/glew/include' -cflags = [] defs = '' -if env['OURPLATFORM'] == 'win32-vc': - cflags.append('/GR') - cflags.append('/Ox') +cxxflags = [] +if env['OURPLATFORM']=='win32-vc': + cxxflags.append ('/GR') + cxxflags.append ('/O2') + incs += ' ' + env['BF_PYTHON_INC'] #incs += ' ' + env['BF_OPENGL_INC'] if env['WITH_BF_FFMPEG']: defs += ' WITH_FFMPEG' - incs += ' ' + env['BF_FFMPEG_INC'] + incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC'] defs += ' __STDC_CONSTANT_MACROS' -env.BlenderLib ( 'bf_videotex', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[300, 72], compileflags = cflags ) +env.BlenderLib ( 'bf_videotex', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[300, 72], cxx_compileflags = cxxflags ) diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 02798c7e596..5265b0ecb93 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -55,7 +55,8 @@ m_codec(NULL), m_formatCtx(NULL), m_codecCtx(NULL), m_frame(NULL), m_frameDeinterlaced(NULL), m_frameRGB(NULL), m_imgConvertCtx(NULL), m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0), m_lastFrame(-1), m_eof(false), m_curPosition(-1), m_startTime(0), -m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false) +m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false), +m_isThreaded(false), m_stopThread(false), m_cacheStarted(false) { // set video format m_format = RGB24; @@ -63,6 +64,12 @@ m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false) setFlip(true); // construction is OK *hRslt = S_OK; + m_thread.first = m_thread.last = NULL; + pthread_mutex_init(&m_cacheMutex, NULL); + m_frameCacheFree.first = m_frameCacheFree.last = NULL; + m_frameCacheBase.first = m_frameCacheBase.last = NULL; + m_packetCacheFree.first = m_packetCacheFree.last = NULL; + m_packetCacheBase.first = m_packetCacheBase.last = NULL; } // destructor @@ -75,6 +82,7 @@ VideoFFmpeg::~VideoFFmpeg () bool VideoFFmpeg::release() { // release + stopCache(); if (m_codecCtx) { avcodec_close(m_codecCtx); @@ -112,6 +120,29 @@ bool VideoFFmpeg::release() return true; } +AVFrame *VideoFFmpeg::allocFrameRGB() +{ + AVFrame *frame; + frame = avcodec_alloc_frame(); + if (m_format == RGBA32) + { + avpicture_fill((AVPicture*)frame, + (uint8_t*)MEM_callocN(avpicture_get_size( + PIX_FMT_RGBA, + m_codecCtx->width, m_codecCtx->height), + "ffmpeg rgba"), + PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height); + } else + { + avpicture_fill((AVPicture*)frame, + (uint8_t*)MEM_callocN(avpicture_get_size( + PIX_FMT_RGB24, + m_codecCtx->width, m_codecCtx->height), + "ffmpeg rgb"), + PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height); + } + return frame; +} // set initial parameters void VideoFFmpeg::initParams (short width, short height, float rate, bool image) @@ -122,6 +153,7 @@ void VideoFFmpeg::initParams (short width, short height, float rate, bool image) m_isImage = image; } + int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams) { AVFormatContext *formatCtx; @@ -189,7 +221,6 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV m_videoStream = videoStream; m_frame = avcodec_alloc_frame(); m_frameDeinterlaced = avcodec_alloc_frame(); - m_frameRGB = avcodec_alloc_frame(); // allocate buffer if deinterlacing is required avpicture_fill((AVPicture*)m_frameDeinterlaced, @@ -207,12 +238,6 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV { // allocate buffer to store final decoded frame m_format = RGBA32; - avpicture_fill((AVPicture*)m_frameRGB, - (uint8_t*)MEM_callocN(avpicture_get_size( - PIX_FMT_RGBA, - m_codecCtx->width, m_codecCtx->height), - "ffmpeg rgba"), - PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height); // allocate sws context m_imgConvertCtx = sws_getContext( m_codecCtx->width, @@ -227,12 +252,6 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV { // allocate buffer to store final decoded frame m_format = RGB24; - avpicture_fill((AVPicture*)m_frameRGB, - (uint8_t*)MEM_callocN(avpicture_get_size( - PIX_FMT_RGB24, - m_codecCtx->width, m_codecCtx->height), - "ffmpeg rgb"), - PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height); // allocate sws context m_imgConvertCtx = sws_getContext( m_codecCtx->width, @@ -244,19 +263,247 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV SWS_FAST_BILINEAR, NULL, NULL, NULL); } + m_frameRGB = allocFrameRGB(); + if (!m_imgConvertCtx) { avcodec_close(m_codecCtx); + m_codecCtx = NULL; av_close_input_file(m_formatCtx); + m_formatCtx = NULL; av_free(m_frame); + m_frame = NULL; MEM_freeN(m_frameDeinterlaced->data[0]); av_free(m_frameDeinterlaced); + m_frameDeinterlaced = NULL; MEM_freeN(m_frameRGB->data[0]); av_free(m_frameRGB); + m_frameRGB = NULL; return -1; } return 0; } +/* + * This thread is used to load video frame asynchronously. + * It provides a frame caching service. + * The main thread is responsible for positionning the frame pointer in the + * file correctly before calling startCache() which starts this thread. + * The cache is organized in two layers: 1) a cache of 20-30 undecoded packets to keep + * memory and CPU low 2) a cache of 5 decoded frames. + * If the main thread does not find the frame in the cache (because the video has restarted + * or because the GE is lagging), it stops the cache with StopCache() (this is a synchronous + * function: it sends a signal to stop the cache thread and wait for confirmation), then + * change the position in the stream and restarts the cache thread. + */ +void *VideoFFmpeg::cacheThread(void *data) +{ + VideoFFmpeg* video = (VideoFFmpeg*)data; + // holds the frame that is being decoded + CacheFrame *currentFrame = NULL; + CachePacket *cachePacket; + bool endOfFile = false; + int frameFinished = 0; + + while (!video->m_stopThread) + { + // packet cache is used solely by this thread, no need to lock + // In case the stream/file contains other stream than the one we are looking for, + // allow a bit of cycling to get rid quickly of those frames + frameFinished = 0; + while ( !endOfFile + && (cachePacket = (CachePacket *)video->m_packetCacheFree.first) != NULL + && frameFinished < 25) + { + // free packet => packet cache is not full yet, just read more + if (av_read_frame(video->m_formatCtx, &cachePacket->packet)>=0) + { + if (cachePacket->packet.stream_index == video->m_videoStream) + { + // make sure fresh memory is allocated for the packet and move it to queue + av_dup_packet(&cachePacket->packet); + BLI_remlink(&video->m_packetCacheFree, cachePacket); + BLI_addtail(&video->m_packetCacheBase, cachePacket); + break; + } else { + // this is not a good packet for us, just leave it on free queue + // Note: here we could handle sound packet + av_free_packet(&cachePacket->packet); + frameFinished++; + } + + } else { + if (video->m_isFile) + // this mark the end of the file + endOfFile = true; + // if we cannot read a packet, no need to continue + break; + } + } + // frame cache is also used by main thread, lock + if (currentFrame == NULL) + { + // no current frame being decoded, take free one + pthread_mutex_lock(&video->m_cacheMutex); + if ((currentFrame = (CacheFrame *)video->m_frameCacheFree.first) != NULL) + BLI_remlink(&video->m_frameCacheFree, currentFrame); + pthread_mutex_unlock(&video->m_cacheMutex); + } + if (currentFrame != NULL) + { + // this frame is out of free and busy queue, we can manipulate it without locking + frameFinished = 0; + while (!frameFinished && (cachePacket = (CachePacket *)video->m_packetCacheBase.first) != NULL) + { + BLI_remlink(&video->m_packetCacheBase, cachePacket); + // use m_frame because when caching, it is not used in main thread + // we can't use currentFrame directly because we need to convert to RGB first + avcodec_decode_video(video->m_codecCtx, + video->m_frame, &frameFinished, + cachePacket->packet.data, cachePacket->packet.size); + if(frameFinished) + { + AVFrame * input = video->m_frame; + + /* This means the data wasnt read properly, this check stops crashing */ + if ( input->data[0]!=0 || input->data[1]!=0 + || input->data[2]!=0 || input->data[3]!=0) + { + if (video->m_deinterlace) + { + if (avpicture_deinterlace( + (AVPicture*) video->m_frameDeinterlaced, + (const AVPicture*) video->m_frame, + video->m_codecCtx->pix_fmt, + video->m_codecCtx->width, + video->m_codecCtx->height) >= 0) + { + input = video->m_frameDeinterlaced; + } + } + // convert to RGB24 + sws_scale(video->m_imgConvertCtx, + input->data, + input->linesize, + 0, + video->m_codecCtx->height, + currentFrame->frame->data, + currentFrame->frame->linesize); + // move frame to queue, this frame is necessarily the next one + currentFrame->framePosition = ++video->m_curPosition; + pthread_mutex_lock(&video->m_cacheMutex); + BLI_addtail(&video->m_frameCacheBase, currentFrame); + pthread_mutex_unlock(&video->m_cacheMutex); + currentFrame = NULL; + } + } + av_free_packet(&cachePacket->packet); + BLI_addtail(&video->m_packetCacheFree, cachePacket); + } + if (currentFrame && endOfFile) + { + // no more packet and end of file => put a special frame that indicates that + currentFrame->framePosition = -1; + pthread_mutex_lock(&video->m_cacheMutex); + BLI_addtail(&video->m_frameCacheBase, currentFrame); + pthread_mutex_unlock(&video->m_cacheMutex); + currentFrame = NULL; + // no need to stay any longer in this thread + break; + } + } + // small sleep to avoid unnecessary looping + PIL_sleep_ms(10); + } + // before quitting, put back the current frame to queue to allow freeing + if (currentFrame) + { + pthread_mutex_lock(&video->m_cacheMutex); + BLI_addtail(&video->m_frameCacheFree, currentFrame); + pthread_mutex_unlock(&video->m_cacheMutex); + } + return 0; +} + +// start thread to cache video frame from file/capture/stream +// this function should be called only when the position in the stream is set for the +// first frame to cache +bool VideoFFmpeg::startCache() +{ + if (!m_cacheStarted && m_isThreaded) + { + m_stopThread = false; + for (int i=0; i<CACHE_FRAME_SIZE; i++) + { + CacheFrame *frame = new CacheFrame(); + frame->frame = allocFrameRGB(); + BLI_addtail(&m_frameCacheFree, frame); + } + for (int i=0; i<CACHE_PACKET_SIZE; i++) + { + CachePacket *packet = new CachePacket(); + BLI_addtail(&m_packetCacheFree, packet); + } + BLI_init_threads(&m_thread, cacheThread, 1); + BLI_insert_thread(&m_thread, this); + m_cacheStarted = true; + } + return m_cacheStarted; +} + +void VideoFFmpeg::stopCache() +{ + if (m_cacheStarted) + { + m_stopThread = true; + BLI_end_threads(&m_thread); + // now delete the cache + CacheFrame *frame; + CachePacket *packet; + while ((frame = (CacheFrame *)m_frameCacheBase.first) != NULL) + { + BLI_remlink(&m_frameCacheBase, frame); + MEM_freeN(frame->frame->data[0]); + av_free(frame->frame); + delete frame; + } + while ((frame = (CacheFrame *)m_frameCacheFree.first) != NULL) + { + BLI_remlink(&m_frameCacheFree, frame); + MEM_freeN(frame->frame->data[0]); + av_free(frame->frame); + delete frame; + } + while((packet = (CachePacket *)m_packetCacheBase.first) != NULL) + { + BLI_remlink(&m_packetCacheBase, packet); + av_free_packet(&packet->packet); + delete packet; + } + while((packet = (CachePacket *)m_packetCacheFree.first) != NULL) + { + BLI_remlink(&m_packetCacheFree, packet); + delete packet; + } + m_cacheStarted = false; + } +} + +void VideoFFmpeg::releaseFrame(AVFrame* frame) +{ + if (frame == m_frameRGB) + { + // this is not a frame from the cache, ignore + return; + } + // this frame MUST be the first one of the queue + pthread_mutex_lock(&m_cacheMutex); + CacheFrame *cacheFrame = (CacheFrame *)m_frameCacheBase.first; + assert (cacheFrame != NULL && cacheFrame->frame == frame); + BLI_remlink(&m_frameCacheBase, cacheFrame); + BLI_addtail(&m_frameCacheFree, cacheFrame); + pthread_mutex_unlock(&m_cacheMutex); +} + // open video file void VideoFFmpeg::openFile (char * filename) { @@ -280,8 +527,12 @@ void VideoFFmpeg::openFile (char * filename) VideoBase::openFile(filename); if ( + // ffmpeg reports that http source are actually non stream + // but it is really not desirable to seek on http file, so force streaming. + // It would be good to find this information from the context but there are no simple indication + !strncmp(filename, "http://", 7) || #ifdef FFMPEG_PB_IS_POINTER - m_formatCtx->pb && m_formatCtx->pb->is_streamed + (m_formatCtx->pb && m_formatCtx->pb->is_streamed) #else m_formatCtx->pb.is_streamed #endif @@ -304,7 +555,13 @@ void VideoFFmpeg::openFile (char * filename) m_avail = false; play(); } - + // check if we should do multi-threading? + if (!m_isImage && BLI_system_thread_count() > 1) + { + // never thread image: there are no frame to read ahead + // no need to thread if the system has a single core + m_isThreaded = true; + } } @@ -385,6 +642,12 @@ void VideoFFmpeg::openCam (char * file, short camIdx) m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK; // open base class VideoBase::openCam(file, camIdx); + // check if we should do multi-threading? + if (BLI_system_thread_count() > 1) + { + // no need to thread if the system has a single core + m_isThreaded = true; + } } // play video @@ -427,9 +690,12 @@ void VideoFFmpeg::setRange (double start, double stop) try { // set range - VideoBase::setRange(start, stop); - // set range for video - setPositions(); + if (m_isFile) + { + VideoBase::setRange(start, stop); + // set range for video + setPositions(); + } } CATCH_EXCP; } @@ -451,43 +717,61 @@ void VideoFFmpeg::calcImage (unsigned int texId) // load frame from video void VideoFFmpeg::loadFrame (void) { - // get actual time - double actTime = PIL_check_seconds_timer() - m_startTime; - // if video has ended - if (m_isFile && actTime * m_frameRate >= m_range[1]) - { - // if repeats are set, decrease them - if (m_repeat > 0) - --m_repeat; - // if video has to be replayed - if (m_repeat != 0) - { - // reset its position - actTime -= (m_range[1] - m_range[0]) / m_frameRate; - m_startTime += (m_range[1] - m_range[0]) / m_frameRate; - } - // if video has to be stopped, stop it - else - m_status = SourceStopped; - } - // if video is playing if (m_status == SourcePlaying) { + // get actual time + double startTime = PIL_check_seconds_timer(); + double actTime = startTime - m_startTime; + // if video has ended + if (m_isFile && actTime * m_frameRate >= m_range[1]) + { + // in any case, this resets the cache + stopCache(); + // if repeats are set, decrease them + if (m_repeat > 0) + --m_repeat; + // if video has to be replayed + if (m_repeat != 0) + { + // reset its position + actTime -= (m_range[1] - m_range[0]) / m_frameRate; + m_startTime += (m_range[1] - m_range[0]) / m_frameRate; + } + // if video has to be stopped, stop it + else + { + m_status = SourceStopped; + return; + } + } // actual frame - long actFrame = m_isFile ? long(actTime * actFrameRate()) : m_lastFrame + 1; + long actFrame = (m_isImage) ? m_lastFrame+1 : long(actTime * actFrameRate()); // if actual frame differs from last frame if (actFrame != m_lastFrame) { + AVFrame* frame; // get image - if(grabFrame(actFrame)) + if((frame = grabFrame(actFrame)) != NULL) { - AVFrame* frame = getFrame(); + if (!m_isFile && !m_cacheStarted) + { + // streaming without cache: detect synchronization problem + double execTime = PIL_check_seconds_timer() - startTime; + if (execTime > 0.005) + { + // exec time is too long, it means that the function was blocking + // resynchronize the stream from this time + m_startTime += execTime; + } + } // save actual frame m_lastFrame = actFrame; // init image, if needed init(short(m_codecCtx->width), short(m_codecCtx->height)); // process image process((BYTE*)(frame->data[0])); + // finished with the frame, release it so that cache can reuse it + releaseFrame(frame); // in case it is an image, automatically stop reading it if (m_isImage) { @@ -495,6 +779,12 @@ void VideoFFmpeg::loadFrame (void) // close the file as we don't need it anymore release(); } + } else if (!m_isFile) + { + // we didn't get a frame and we are streaming, this may be due to + // a delay in the network or because we are getting the frame too fast. + // In the later case, shift time by a small amount to compensate for a drift + m_startTime += 0.01; } } } @@ -507,77 +797,135 @@ void VideoFFmpeg::setPositions (void) // set video start time m_startTime = PIL_check_seconds_timer(); // if file is played and actual position is before end position - if (m_isFile && !m_eof && m_lastFrame >= 0 && m_lastFrame < m_range[1] * actFrameRate()) + if (!m_eof && m_lastFrame >= 0 && (!m_isFile || m_lastFrame < m_range[1] * actFrameRate())) // continue from actual position m_startTime -= double(m_lastFrame) / actFrameRate(); - else + else { m_startTime -= m_range[0]; + // start from begining, stop cache just in case + stopCache(); + } } // position pointer in file, position in second -bool VideoFFmpeg::grabFrame(long position) +AVFrame *VideoFFmpeg::grabFrame(long position) { AVPacket packet; int frameFinished; int posFound = 1; bool frameLoaded = false; long long targetTs = 0; + CacheFrame *frame; - // first check if the position that we are looking for is in the preseek range - // if so, just read the frame until we get there - if (position > m_curPosition + 1 - && m_preseek - && position - (m_curPosition + 1) < m_preseek) + if (m_cacheStarted) { - while(av_read_frame(m_formatCtx, &packet)>=0) + // when cache is active, we must not read the file directly + do { + pthread_mutex_lock(&m_cacheMutex); + frame = (CacheFrame *)m_frameCacheBase.first; + pthread_mutex_unlock(&m_cacheMutex); + // no need to remove the frame from the queue: the cache thread does not touch the head, only the tail + if (frame == NULL) + { + // no frame in cache, in case of file it is an abnormal situation + if (m_isFile) + { + // go back to no threaded reading + stopCache(); + break; + } + return NULL; + } + if (frame->framePosition == -1) + { + // this frame mark the end of the file (only used for file) + // leave in cache to make sure we don't miss it + m_eof = true; + return NULL; + } + // for streaming, always return the next frame, + // that's what grabFrame does in non cache mode anyway. + if (!m_isFile || frame->framePosition == position) + { + return frame->frame; + } + // this frame is not useful, release it + pthread_mutex_lock(&m_cacheMutex); + BLI_remlink(&m_frameCacheBase, frame); + BLI_addtail(&m_frameCacheFree, frame); + pthread_mutex_unlock(&m_cacheMutex); + } while (true); + } + // come here when there is no cache or cache has been stopped + // locate the frame, by seeking if necessary (seeking is only possible for files) + if (m_isFile) + { + // first check if the position that we are looking for is in the preseek range + // if so, just read the frame until we get there + if (position > m_curPosition + 1 + && m_preseek + && position - (m_curPosition + 1) < m_preseek) { - if (packet.stream_index == m_videoStream) + while(av_read_frame(m_formatCtx, &packet)>=0) { - avcodec_decode_video( - m_codecCtx, - m_frame, &frameFinished, - packet.data, packet.size); - if (frameFinished) - m_curPosition++; + if (packet.stream_index == m_videoStream) + { + avcodec_decode_video( + m_codecCtx, + m_frame, &frameFinished, + packet.data, packet.size); + if (frameFinished) + m_curPosition++; + } + av_free_packet(&packet); + if (position == m_curPosition+1) + break; } - av_free_packet(&packet); - if (position == m_curPosition+1) - break; } - } - // if the position is not in preseek, do a direct jump - if (position != m_curPosition + 1) - { - double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base); - long long pos = (long long) - ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate); - long long startTs = m_formatCtx->streams[m_videoStream]->start_time; + // if the position is not in preseek, do a direct jump + if (position != m_curPosition + 1) + { + double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base); + long long pos = (long long) + ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate); + long long startTs = m_formatCtx->streams[m_videoStream]->start_time; - if (pos < 0) - pos = 0; + if (pos < 0) + pos = 0; - if (startTs != AV_NOPTS_VALUE) - pos += (long long)(startTs * AV_TIME_BASE * timeBase); + if (startTs != AV_NOPTS_VALUE) + pos += (long long)(startTs * AV_TIME_BASE * timeBase); - if (position <= m_curPosition || !m_eof) - { - // no need to seek past the end of the file - if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0) + if (position <= m_curPosition || !m_eof) { - // current position is now lost, guess a value. - // It's not important because it will be set at this end of this function - m_curPosition = position - m_preseek - 1; + // no need to seek past the end of the file + if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0) + { + // current position is now lost, guess a value. + // It's not important because it will be set at this end of this function + m_curPosition = position - m_preseek - 1; + } } - } - // this is the timestamp of the frame we're looking for - targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase); - if (startTs != AV_NOPTS_VALUE) - targetTs += startTs; + // this is the timestamp of the frame we're looking for + targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase); + if (startTs != AV_NOPTS_VALUE) + targetTs += startTs; - posFound = 0; - avcodec_flush_buffers(m_codecCtx); + posFound = 0; + avcodec_flush_buffers(m_codecCtx); + } + } else if (m_isThreaded) + { + // cache is not started but threading is possible + // better not read the stream => make take some time, better start caching + if (startCache()) + return NULL; + // Abnormal!!! could not start cache, fall back on direct read + m_isThreaded = false; } + // find the correct frame, in case of streaming and no cache, it means just + // return the next frame. This is not quite correct, may need more work while(av_read_frame(m_formatCtx, &packet)>=0) { if(packet.stream_index == m_videoStream) @@ -632,10 +980,22 @@ bool VideoFFmpeg::grabFrame(long position) } av_free_packet(&packet); } - m_eof = !frameLoaded; + m_eof = m_isFile && !frameLoaded; if (frameLoaded) + { m_curPosition = position; - return frameLoaded; + if (m_isThreaded) + { + // normal case for file: first locate, then start cache + if (!startCache()) + { + // Abnormal!! could not start cache, return to non-cache mode + m_isThreaded = false; + } + } + return m_frameRGB; + } + return NULL; } diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index e60f1727aab..51ce2c4eebe 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -24,12 +24,17 @@ http://www.gnu.org/copyleft/lesser.txt. #ifdef WITH_FFMPEG extern "C" { +#include <pthread.h> #include <ffmpeg/avformat.h> #include <ffmpeg/avcodec.h> #include <ffmpeg/rational.h> #include <ffmpeg/swscale.h> +#include "DNA_listBase.h" +#include "BLI_threads.h" +#include "BLI_blenlib.h" } + #if LIBAVFORMAT_VERSION_INT < (49 << 16) #define FFMPEG_OLD_FRAME_RATE 1 #else @@ -54,6 +59,8 @@ static inline AVCodecContext* get_codec_from_stream(AVStream* stream) #include "VideoBase.h" +#define CACHE_FRAME_SIZE 5 +#define CACHE_PACKET_SIZE 30 // type VideoFFmpeg declaration class VideoFFmpeg : public VideoBase @@ -91,7 +98,6 @@ public: char *getImageName(void) { return (m_isImage) ? m_imageName.Ptr() : NULL; } protected: - // format and codec information AVCodec *m_codec; AVFormatContext *m_formatCtx; @@ -138,6 +144,9 @@ protected: /// is file an image? bool m_isImage; + /// is image loading done in a separate thread? + bool m_isThreaded; + /// keep last image name STR_String m_imageName; @@ -157,10 +166,37 @@ protected: int openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams); /// check if a frame is available and load it in pFrame, return true if a frame could be retrieved - bool grabFrame(long frame); - - /// return the frame in RGB24 format, the image data is found in AVFrame.data[0] - AVFrame* getFrame(void) { return m_frameRGB; } + AVFrame* grabFrame(long frame); + + /// in case of caching, put the frame back in free queue + void releaseFrame(AVFrame* frame); + + /// start thread to load the video file/capture/stream + bool startCache(); + void stopCache(); + +private: + typedef struct { + Link link; + long framePosition; + AVFrame *frame; + } CacheFrame; + typedef struct { + Link link; + AVPacket packet; + } CachePacket; + + bool m_stopThread; + bool m_cacheStarted; + ListBase m_thread; + ListBase m_frameCacheBase; // list of frames that are ready + ListBase m_frameCacheFree; // list of frames that are unused + ListBase m_packetCacheBase; // list of packets that are ready for decoding + ListBase m_packetCacheFree; // list of packets that are unused + pthread_mutex_t m_cacheMutex; + + AVFrame *allocFrameRGB(); + static void *cacheThread(void *); }; inline VideoFFmpeg * getFFmpeg (PyImage * self) |