diff options
Diffstat (limited to 'source/gameengine')
46 files changed, 761 insertions, 250 deletions
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index e11bc84a0da..8d73e591113 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -101,7 +101,7 @@ static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) out->chanhash = NULL; out->agroups.first= out->agroups.last= NULL; out->ikdata = NULL; - out->ikparam = MEM_dupallocN(out->ikparam); + out->ikparam = MEM_dupallocN(src->ikparam); out->flag |= POSE_GAME_ENGINE; BLI_duplicatelist(&out->chanbase, &src->chanbase); @@ -231,6 +231,8 @@ BL_ArmatureObject::BL_ArmatureObject( m_objArma = BKE_object_copy(armature); m_objArma->data = BKE_armature_copy((bArmature *)armature->data); m_pose = m_objArma->pose; + // need this to get iTaSC working ok in the BGE + m_pose->flag |= POSE_GAME_ENGINE; memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat)); } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index e511f01e9c6..87b64582e11 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -876,7 +876,7 @@ static bool ConvertMaterial( material->alphablend = GEMAT_ALPHA; // always zsort alpha + add - if ((ELEM3(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD) || texalpha) && (material->alphablend != GEMAT_CLIP )) { + if ((ELEM(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD) || texalpha) && (material->alphablend != GEMAT_CLIP )) { material->ras_mode |= ALPHA; material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0; } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index f72275b79cf..e96d0e0ebb4 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -59,7 +59,7 @@ public: virtual void ProcessReplica(); void SetBlendTime (float newtime); - void BlendShape(struct Key* key, float weigth); + void BlendShape(struct Key* key, float weight); bAction* GetAction() { return m_action; } void SetAction(bAction* act) { m_action= act; } diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 45fc11b97d2..f6ed3366625 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -538,8 +538,8 @@ void BL_ConvertActuators(const char* maggiename, originalval, editobact->time, editobact->flag, - blenderobject->trackflag, - blenderobject->upflag); + editobact->trackflag, + editobact->upflag); baseact = tmptrackact; break; } diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 93a5ee11366..0d706fcd924 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -329,12 +329,19 @@ void BL_ConvertSensors(struct Object* blenderobject, gameobj); } else { /* give us a focus-aware sensor */ + bool bFindMaterial = (bmouse->mode & SENS_COLLISION_MATERIAL); + bool bXRay = (bmouse->flag & SENS_RAY_XRAY); + STR_String checkname = (bFindMaterial? bmouse->matname : bmouse->propname); + gamesensor = new KX_MouseFocusSensor(eventmgr, startx, starty, keytype, trackfocus, (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false, + checkname, + bFindMaterial, + bXRay, kxscene, kxengine, gameobj); diff --git a/source/gameengine/Expressions/Expression.cpp b/source/gameengine/Expressions/Expression.cpp index c1146aaa65c..2428df977d3 100644 --- a/source/gameengine/Expressions/Expression.cpp +++ b/source/gameengine/Expressions/Expression.cpp @@ -21,13 +21,13 @@ ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// -#ifdef _DEBUG +#ifdef DEBUG //int gRefCountExpr; #endif CExpression::CExpression()// : m_cached_calculate(NULL) { m_refcount = 1; -#ifdef _DEBUG +#ifdef DEBUG //gRefCountExpr++; #endif } diff --git a/source/gameengine/Expressions/Expression.h b/source/gameengine/Expressions/Expression.h index d1b7eda43f0..9a4f1f93284 100644 --- a/source/gameengine/Expressions/Expression.h +++ b/source/gameengine/Expressions/Expression.h @@ -116,7 +116,7 @@ public: virtual CExpression * AddRef() { // please leave multiline, for debugger !!! -#ifdef _DEBUG +#ifdef DEBUG //gRefCountExpr++; assertd(m_refcount < 255); #endif @@ -124,7 +124,7 @@ public: return this; }; virtual CExpression* Release(CExpression* complicatedtrick=NULL) { -#ifdef _DEBUG +#ifdef DEBUG //gRefCountExpr--; #endif if (--m_refcount < 1) diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index a2d055974c3..82d2e94dbb0 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -35,7 +35,7 @@ effect: constructs a new CIntValue */ { -#ifdef _DEBUG_ +#ifdef DEBUG_ m_textval = "Int illegal constructor"; #endif m_pstrRep=NULL; diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 1ced71e66a4..bdef2dbd5b0 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -86,7 +86,7 @@ struct SmartCValueRef std::vector<SmartCValueRef> gRefList; #endif -#ifdef _DEBUG +#ifdef DEBUG //int gRefCountValue; #endif @@ -101,7 +101,7 @@ effect: constucts a CValue */ { //debug(gRefCountValue++) // debugging -#ifdef _DEBUG +#ifdef DEBUG //gRefCountValue++; #ifdef CVALUE_DEBUG gRefList.push_back(SmartCValueRef(this)); @@ -460,7 +460,7 @@ void CValue::DisableRefCount() m_refcount--; //debug(gRefCountValue--); -#ifdef _DEBUG +#ifdef DEBUG //gRefCountValue--; #endif m_ValFlags.RefCountDisabled=true; @@ -472,7 +472,7 @@ void CValue::ProcessReplica() /* was AddDataToReplica in 2.48 */ { m_refcount = 1; -#ifdef _DEBUG +#ifdef DEBUG //gRefCountValue++; #endif PyObjectPlus::ProcessReplica(); diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 7f6ce9aa703..c7e9a40a059 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -90,7 +90,7 @@ enum VALUE_DATA_TYPE { -#ifdef _DEBUG +#ifdef DEBUG //extern int gRefCountValue; // debugonly variable to check if all CValue Refences are Dereferenced at programexit #endif @@ -251,7 +251,7 @@ public: // Increase global reference count, used to see at the end of the program // if all CValue-derived classes have been dereferenced to 0 //debug(gRefCountValue++); -#ifdef _DEBUG +#ifdef DEBUG //gRefCountValue++; #endif m_refcount++; @@ -264,7 +264,7 @@ public: // Decrease global reference count, used to see at the end of the program // if all CValue-derived classes have been dereferenced to 0 //debug(gRefCountValue--); -#ifdef _DEBUG +#ifdef DEBUG //gRefCountValue--; #endif // Decrease local reference count, if it reaches 0 the object should be freed diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h index 37c867ef7d6..566e5567507 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h @@ -36,7 +36,7 @@ #undef main #endif -#ifndef _DEBUG +#ifndef DEBUG # define JOYSTICK_ECHO(x) #else # include <iostream> diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp index c98c86639d3..3ca4b6607b3 100644 --- a/source/gameengine/GameLogic/SCA_IScene.cpp +++ b/source/gameengine/GameLogic/SCA_IScene.cpp @@ -70,6 +70,32 @@ std::vector<SCA_DebugProp*>& SCA_IScene::GetDebugProperties() } +bool SCA_IScene::PropertyInDebugList( class CValue *gameobj, const STR_String &name ) +{ + for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin(); + !(it==m_debugList.end());++it) { + STR_String debugname = (*it)->m_name; + CValue *debugobj = (*it)->m_obj; + + if (debugobj == gameobj && debugname == name) + return true; + } + return false; +} + + +bool SCA_IScene::ObjectInDebugList( class CValue *gameobj ) +{ + for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin(); + !(it==m_debugList.end());++it) { + CValue* debugobj = (*it)->m_obj; + + if (debugobj == gameobj) + return true; + } + return false; +} + void SCA_IScene::AddDebugProperty(class CValue* debugprop, const STR_String &name) @@ -84,6 +110,24 @@ void SCA_IScene::AddDebugProperty(class CValue* debugprop, } +void SCA_IScene::RemoveDebugProperty(class CValue *gameobj, + const STR_String &name) +{ + vector<SCA_DebugProp*>::iterator it = m_debugList.begin(); + while(it != m_debugList.end()) { + STR_String debugname = (*it)->m_name; + CValue *debugobj = (*it)->m_obj; + + if (debugobj == gameobj && debugname == name) { + delete (*it); + m_debugList.erase(it); + break; + } + ++it; + } +} + + void SCA_IScene::RemoveObjectDebugProperties(class CValue* gameobj) { vector<SCA_DebugProp*>::iterator it = m_debugList.begin(); diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h index e2e1edd4354..b76b5636b13 100644 --- a/source/gameengine/GameLogic/SCA_IScene.h +++ b/source/gameengine/GameLogic/SCA_IScene.h @@ -67,9 +67,11 @@ public: virtual void ReplaceMesh(class CValue* gameobj, void* meshobj, bool use_gfx, bool use_phys)=0; std::vector<SCA_DebugProp*>& GetDebugProperties(); + bool PropertyInDebugList(class CValue *gameobj, const STR_String &name); + bool ObjectInDebugList(class CValue *gameobj); void RemoveAllDebugProperties(); - void AddDebugProperty(class CValue* debugprop, - const STR_String &name); + void AddDebugProperty(class CValue* debugprop, const STR_String &name); + void RemoveDebugProperty(class CValue *gameobj, const STR_String &name); void RemoveObjectDebugProperties(class CValue* gameobj); virtual void Update2DFilter(std::vector<STR_String>& propNames, void* gameObj, diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp index 0eab6187d07..ea1b2a2bce3 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp @@ -69,13 +69,24 @@ bool SCA_PropertyActuator::Update() bool bNegativeEvent = IsNegativeEvent(); RemoveAllEvents(); - + CValue* propowner = GetParent(); if (bNegativeEvent) - return false; // do nothing on negative events + { + if (m_type==KX_ACT_PROP_LEVEL) + { + CValue* newval = new CBoolValue(false); + CValue* oldprop = propowner->GetProperty(m_propname); + if (oldprop) + { + oldprop->SetValue(newval); + } + newval->Release(); + } + return false; + } - CValue* propowner = GetParent(); CParser parser; parser.SetContext( propowner->AddRef()); @@ -97,6 +108,19 @@ bool SCA_PropertyActuator::Update() } newval->Release(); } + else if (m_type==KX_ACT_PROP_LEVEL) + { + CValue* newval = new CBoolValue(true); + CValue* oldprop = propowner->GetProperty(m_propname); + if (oldprop) + { + oldprop->SetValue(newval); + } else + { + propowner->SetProperty(m_propname,newval); + } + newval->Release(); + } else if ((userexpr = parser.ProcessText(m_exprtxt))) { switch (m_type) { diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index 83a6d05df1b..228ecf94bc4 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -44,6 +44,7 @@ class SCA_PropertyActuator : public SCA_IActuator KX_ACT_PROP_ADD, KX_ACT_PROP_COPY, KX_ACT_PROP_TOGGLE, + KX_ACT_PROP_LEVEL, KX_ACT_PROP_MAX }; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 0d0b99edee1..9f0b582045f 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -616,7 +616,7 @@ void KX_BlenderMaterial::ActivateMeshSlot(const RAS_MeshSlot & ms, RAS_IRasteriz /* we do blend modes here, because they can change per object * with the same material due to obcolor/obalpha */ alphablend = mBlenderShader->GetAlphaBlend(); - if (ELEM3(alphablend, GEMAT_SOLID, GEMAT_ALPHA, GEMAT_ALPHA_SORT) && mMaterial->alphablend != GEMAT_SOLID) + if (ELEM(alphablend, GEMAT_SOLID, GEMAT_ALPHA, GEMAT_ALPHA_SORT) && mMaterial->alphablend != GEMAT_SOLID) alphablend = mMaterial->alphablend; rasty->SetAlphaBlend(alphablend); diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp index 793324fab75..29d92762285 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -114,6 +114,7 @@ PyMethodDef KX_ConstraintWrapper::Methods[] = { PyAttributeDef KX_ConstraintWrapper::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("constraint_id", KX_ConstraintWrapper, pyattr_get_constraintId), + KX_PYATTRIBUTE_RO_FUNCTION("constraint_type", KX_ConstraintWrapper, pyattr_get_constraintType), { NULL } //Sentinel }; @@ -123,4 +124,10 @@ PyObject *KX_ConstraintWrapper::pyattr_get_constraintId(void *self_v, const KX_P return self->PyGetConstraintId(); } +PyObject *KX_ConstraintWrapper::pyattr_get_constraintType(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_ConstraintWrapper* self = static_cast<KX_ConstraintWrapper*>(self_v); + return PyLong_FromLong(self->m_constraintType); +} + #endif // WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index eafc45b5a70..b7124c76439 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -49,6 +49,7 @@ public: KX_PYMETHOD(KX_ConstraintWrapper,GetParam); static PyObject *pyattr_get_constraintId(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_constraintType(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); #endif private: diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index f58fee88d48..a77269c116d 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -2044,6 +2044,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i) cam->NodeUpdateGS(0.f); scene->CalculateVisibleMeshes(m_rasterizer,cam); + scene->UpdateAnimations(m_engine->GetFrameTime()); scene->RenderBuckets(camtrans, m_rasterizer); } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index de528aeac63..c681e0842c4 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -51,6 +51,7 @@ typedef unsigned long uint_ptr; #include "KX_Light.h" // only for their ::Type #include "KX_FontObject.h" // only for their ::Type #include "RAS_MeshObject.h" +#include "KX_NavMeshObject.h" #include "KX_MeshProxy.h" #include "KX_PolyProxy.h" #include <stdio.h> // printf @@ -68,6 +69,7 @@ typedef unsigned long uint_ptr; #include "SCA_IController.h" #include "NG_NetworkScene.h" //Needed for sendMessage() #include "KX_ObstacleSimulation.h" +#include "KX_Scene.h" #include "BKE_object.h" @@ -928,6 +930,27 @@ KX_GameObject::SetVisible( } } +bool KX_GameObject::GetCulled() +{ + // If we're set to not cull, double-check with + // the mesh slots first. This is kind of nasty, but + // it allows us to get proper culling information. + if (!m_bCulled) + { + SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots); + for (mit.begin(); !mit.end(); ++mit) + { + if ((*mit)->m_bCulled) + { + m_bCulled = true; + break; + } + } + } + + return m_bCulled; +} + static void setOccluder_recursive(SG_Node* node, bool v) { NodeList& children = node->GetSGChildren(); @@ -958,6 +981,44 @@ KX_GameObject::SetOccluder( } } +static void setDebug_recursive(SG_Node *node, bool debug) +{ + NodeList& children = node->GetSGChildren(); + KX_Scene *scene = KX_GetActiveScene(); + + for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) { + SG_Node *childnode = (*childit); + KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); + if (clientgameobj != NULL) { + if (debug) { + if (!scene->ObjectInDebugList(clientgameobj)) + scene->AddObjectDebugProperties(clientgameobj); + } + else + scene->RemoveObjectDebugProperties(clientgameobj); + } + + /* if the childobj is NULL then this may be an inverse parent link + * so a non recursive search should still look down this node. */ + setDebug_recursive(childnode, debug); + } +} + +void KX_GameObject::SetUseDebugProperties( bool debug, bool recursive ) +{ + KX_Scene *scene = KX_GetActiveScene(); + + if (debug) { + if (!scene->ObjectInDebugList(this)) + scene->AddObjectDebugProperties(this); + } + else + scene->RemoveObjectDebugProperties(this); + + if (recursive) + setDebug_recursive(GetSGNode(), debug); +} + void KX_GameObject::SetLayer( int l @@ -1807,6 +1868,7 @@ PyMethodDef KX_GameObject::Methods[] = { KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo), KX_PYMETHODTABLE_O(KX_GameObject, getVectTo), KX_PYMETHODTABLE(KX_GameObject, sendMessage), + KX_PYMETHODTABLE(KX_GameObject, addDebugProperty), KX_PYMETHODTABLE_KEYWORDS(KX_GameObject, playAction), KX_PYMETHODTABLE(KX_GameObject, stopAction), @@ -1859,6 +1921,8 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("childrenRecursive", KX_GameObject, pyattr_get_children_recursive), KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict), KX_PYATTRIBUTE_RW_FUNCTION("color", KX_GameObject, pyattr_get_obcolor, pyattr_set_obcolor), + KX_PYATTRIBUTE_RW_FUNCTION("debug", KX_GameObject, pyattr_get_debug, pyattr_set_debug), + KX_PYATTRIBUTE_RW_FUNCTION("debugRecursive", KX_GameObject, pyattr_get_debugRecursive, pyattr_set_debugRecursive), /* experimental, don't rely on these yet */ KX_PYATTRIBUTE_RO_FUNCTION("sensors", KX_GameObject, pyattr_get_sensors), @@ -2775,6 +2839,52 @@ PyObject *KX_GameObject::pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_ return self->m_attr_dict; } +PyObject *KX_GameObject::pyattr_get_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene *scene = KX_GetActiveScene(); + KX_GameObject *self = static_cast<KX_GameObject*>(self_v); + + return PyBool_FromLong(scene->ObjectInDebugList(self)); +} + +int KX_GameObject::pyattr_set_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject *self = static_cast<KX_GameObject*>(self_v); + int param = PyObject_IsTrue(value); + + if (param == -1) { + PyErr_SetString(PyExc_AttributeError, "gameOb.debug = bool: KX_GameObject, expected True or False"); + return PY_SET_ATTR_FAIL; + } + + self->SetUseDebugProperties(param, false); + + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_GameObject::pyattr_get_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_Scene *scene = KX_GetActiveScene(); + KX_GameObject *self = static_cast<KX_GameObject*>(self_v); + + return PyBool_FromLong(scene->ObjectInDebugList(self)); +} + +int KX_GameObject::pyattr_set_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject *self = static_cast<KX_GameObject*>(self_v); + int param = PyObject_IsTrue(value); + + if (param == -1) { + PyErr_SetString(PyExc_AttributeError, "gameOb.debugRecursive = bool: KX_GameObject, expected True or False"); + return PY_SET_ATTR_FAIL; + } + + self->SetUseDebugProperties(param, true); + + return PY_SET_ATTR_SUCCESS; +} + PyObject *KX_GameObject::PyApplyForce(PyObject *args) { int local = 0; @@ -3596,6 +3706,29 @@ KX_PYMETHODDEF_DOC(KX_GameObject, isPlayingAction, } +KX_PYMETHODDEF_DOC(KX_GameObject, addDebugProperty, +"addDebugProperty(name, visible=1)\n" +"Added or remove a debug property to the debug list.\n") +{ + KX_Scene *scene = KX_GetActiveScene(); + char *name; + int visible = 1; + + if (!PyArg_ParseTuple(args,"s|i:debugProperty", &name , &visible)) + return NULL; + + if (visible) { + if (!scene->PropertyInDebugList(this, name)) + scene->AddDebugProperty(this, name); + } + else { + scene->RemoveDebugProperty(this, name); + } + + Py_RETURN_NONE; +} + + /* dict style access */ @@ -3663,7 +3796,8 @@ bool ConvertPythonToGameObject(PyObject *value, KX_GameObject **object, bool py_ if ( PyObject_TypeCheck(value, &KX_GameObject::Type) || PyObject_TypeCheck(value, &KX_LightObject::Type) || PyObject_TypeCheck(value, &KX_Camera::Type) || - PyObject_TypeCheck(value, &KX_FontObject::Type)) + PyObject_TypeCheck(value, &KX_FontObject::Type) || + PyObject_TypeCheck(value, &KX_NavMeshObject::Type)) { *object = static_cast<KX_GameObject*>BGE_PROXY_REF(value); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 7450be4fdef..d4fa4851696 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -852,10 +852,10 @@ public: /** * Was this object culled? */ - inline bool + bool GetCulled( void - ) { return m_bCulled; } + ); /** * Set culled flag of this object @@ -934,6 +934,11 @@ public: m_pObstacleSimulation = NULL; } + /** + * add debug object to the debuglist. + */ + void SetUseDebugProperties(bool debug, bool recursive); + KX_ClientObjectInfo* getClientInfo() { return m_pClient_info; } CListValue* GetChildren(); @@ -993,6 +998,7 @@ public: KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo); KX_PYMETHOD_DOC_VARARGS(KX_GameObject, sendMessage); KX_PYMETHOD_VARARGS(KX_GameObject, ReinstancePhysicsMesh); + KX_PYMETHOD_DOC(KX_GameObject, addDebugProperty); KX_PYMETHOD_DOC(KX_GameObject, playAction); KX_PYMETHOD_DOC(KX_GameObject, stopAction); @@ -1060,7 +1066,11 @@ public: static int pyattr_set_obcolor(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_collisionCallbacks(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_collisionCallbacks(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); - + static PyObject* pyattr_get_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + /* Experimental! */ static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_controllers(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 7d7e15a5141..14772cda113 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -140,7 +140,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system) m_frameTime(0.f), m_clockTime(0.f), m_previousClockTime(0.f), - m_previousAnimTime(0.f), m_exitcode(KX_EXIT_REQUEST_NO_REQUEST), @@ -164,6 +163,7 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system) m_showProperties(false), m_showBackground(false), m_show_debug_properties(false), + m_autoAddDebugProperties(true), m_animation_record(false), @@ -686,16 +686,6 @@ bool KX_KetsjiEngine::NextFrame() SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE); scene->UpdateParents(m_frameTime); - // update levels of detail - scene->UpdateObjectLods(); - - if (!GetRestrictAnimationFPS()) - { - m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); - SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); - scene->UpdateAnimations(m_frameTime); - } - m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); SG_SetActiveStage(SG_STAGE_PHYSICS2); scene->GetPhysicsEnvironment()->BeginFrame(); @@ -797,27 +787,6 @@ bool KX_KetsjiEngine::NextFrame() m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true); } } - - - // Handle the animations independently of the logic time step - if (GetRestrictAnimationFPS()) - { - double clocktime = m_kxsystem->GetTimeInSeconds(); - m_logger->StartLog(tc_animations, clocktime, true); - SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); - - double anim_timestep = 1.0/KX_GetActiveScene()->GetAnimationFPS(); - if (clocktime - m_previousAnimTime > anim_timestep) - { - // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep) - // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime)); - m_previousAnimTime = clocktime; - for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit) - { - (*sceneit)->UpdateAnimations(clocktime); - } - } - } // Start logging time spend outside main loop m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true); @@ -1186,8 +1155,15 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) raslight->BindShadowBuffer(m_canvas, cam, camtrans); /* update scene */ + m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); scene->CalculateVisibleMeshes(m_rasterizer, cam, raslight->GetShadowLayer()); + m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); + scene->UpdateAnimations(GetFrameTime()); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + /* render */ m_rasterizer->ClearDepthBuffer(); m_rasterizer->ClearColorBuffer(); @@ -1319,6 +1295,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->CalculateVisibleMeshes(m_rasterizer,cam); + m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true); + SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); + + scene->UpdateAnimations(GetFrameTime()); + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); SG_SetActiveStage(SG_STAGE_RENDER); @@ -1751,9 +1732,20 @@ void KX_KetsjiEngine::AddScheduledScenes() -void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene) +bool KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene) { - m_replace_scenes.push_back(std::make_pair(oldscene,newscene)); + // Don't allow replacement if the new scene doesn't exists. + // Allows smarter game design (used to have no check here). + // Note that it creates a small backward compatbility issue + // for a game that did a replace followed by a lib load with the + // new scene in the lib => it won't work anymore, the lib + // must be loaded before doing the replace. + if (m_sceneconverter->GetBlenderSceneForName(newscene) != NULL) + { + m_replace_scenes.push_back(std::make_pair(oldscene,newscene)); + return true; + } + return false; } // replace scene is not the same as removing and adding because the @@ -1777,13 +1769,19 @@ void KX_KetsjiEngine::ReplaceScheduledScenes() KX_SceneList::iterator sceneit; for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) { - KX_Scene* scene = *sceneit; + KX_Scene* scene = *sceneit; if (scene->GetName() == oldscenename) { - m_sceneconverter->RemoveScene(scene); - KX_Scene* tmpscene = CreateScene(newscenename); - m_scenes[i]=tmpscene; - PostProcessScene(tmpscene); + // avoid crash if the new scene doesn't exist, just do nothing + Scene *blScene = m_sceneconverter->GetBlenderSceneForName(newscenename); + if (blScene) { + m_sceneconverter->RemoveScene(scene); + KX_Scene* tmpscene = CreateScene(blScene); + m_scenes[i]=tmpscene; + PostProcessScene(tmpscene); + } else { + printf("warning: scene %s could not be found, not replaced!\n",newscenename.ReadPtr()); + } } i++; } @@ -1917,6 +1915,46 @@ short KX_KetsjiEngine::GetExitKey() return m_exitkey; } +void KX_KetsjiEngine::SetShowFramerate(bool frameRate) +{ + m_show_framerate = frameRate; +} + +bool KX_KetsjiEngine::GetShowFramerate() +{ + return m_show_framerate; +} + +void KX_KetsjiEngine::SetShowProfile(bool profile) +{ + m_show_profile = profile; +} + +bool KX_KetsjiEngine::GetShowProfile() +{ + return m_show_profile; +} + +void KX_KetsjiEngine::SetShowProperties(bool properties) +{ + m_show_debug_properties = properties; +} + +bool KX_KetsjiEngine::GetShowProperties() +{ + return m_show_debug_properties; +} + +void KX_KetsjiEngine::SetAutoAddDebugProperties(bool add) +{ + m_autoAddDebugProperties = add; +} + +bool KX_KetsjiEngine::GetAutoAddDebugProperties() +{ + return m_autoAddDebugProperties; +} + void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties) { m_show_framerate = frameRate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 9e5d1893320..2b80e3bd69a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -111,7 +111,6 @@ private: double m_frameTime;//discrete timestamp of the 'game logic frame' double m_clockTime;//current time double m_previousClockTime;//previous clock time - double m_previousAnimTime; //the last time animations were updated double m_remainingTime; static int m_maxLogicFrame; /* maximum number of consecutive logic frame */ @@ -175,8 +174,10 @@ private: bool m_showProperties; /** Show background behind text for readability? */ bool m_showBackground; - + /** Show debug properties on the game display*/ bool m_show_debug_properties; + /** Automatic add debug properties to the debug list*/ + bool m_autoAddDebugProperties; /** record physics into keyframes */ bool m_animation_record; @@ -222,6 +223,7 @@ public: PyObject* GetPyProfileDict(); #endif void SetSceneConverter(KX_ISceneConverter* sceneconverter); + KX_ISceneConverter* GetSceneConverter() { return m_sceneconverter; } void SetAnimRecordMode(bool animation_record, int startFrame); RAS_IRasterizer* GetRasterizer() { return m_rasterizer; } @@ -256,7 +258,7 @@ public: void ConvertAndAddScene(const STR_String& scenename,bool overlay); void RemoveScene(const STR_String& scenename); - void ReplaceScene(const STR_String& oldscene,const STR_String& newscene); + bool ReplaceScene(const STR_String& oldscene,const STR_String& newscene); void SuspendScene(const STR_String& scenename); void ResumeScene(const STR_String& scenename); @@ -354,6 +356,46 @@ public: static short GetExitKey(); /** + * \Sets the display for frame rate on or off. + */ + void SetShowFramerate(bool frameRate); + + /** + * \Gets the display for frame rate on or off. + */ + bool GetShowFramerate(); + + /** + * \Sets the display for individual components on or off. + */ + void SetShowProfile(bool profile); + + /** + * \Gets the display for individual components on or off. + */ + bool GetShowProfile(); + + /** + * \Sets the display of scene object debug properties on or off. + */ + void SetShowProperties(bool properties); + + /** + * \Gets the display of scene object debug properties on or off. + */ + bool GetShowProperties(); + + /** + * \Sets if the auto adding of scene object debug properties on or off. + */ + bool GetAutoAddDebugProperties(); + + /** + * \Sets the auto adding of scene object debug properties on or off. + */ + void SetAutoAddDebugProperties(bool add); + + /** * Activates or deactivates timing information display. * \param frameRate Display for frame rate on or off. * \param profile Display for individual components on or off. diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 37c36da0db3..33cfec57fc0 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -231,7 +231,7 @@ int KX_LightObject::pyattr_set_distance(void *self_v, const KX_PYATTRIBUTE_DEF * else if (val > 5000.f) val = 5000.f; - self->m_lightobj->m_energy = val; + self->m_lightobj->m_distance = val; return PY_SET_ATTR_SUCCESS; } @@ -242,7 +242,7 @@ int KX_LightObject::pyattr_set_distance(void *self_v, const KX_PYATTRIBUTE_DEF * PyObject *KX_LightObject::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_LightObject* self = static_cast<KX_LightObject*>(self_v); - return Py_BuildValue("[fff]", self->m_lightobj->m_color[0], self->m_lightobj->m_color[1], self->m_lightobj->m_color[1]); + return Py_BuildValue("[fff]", self->m_lightobj->m_color[0], self->m_lightobj->m_color[1], self->m_lightobj->m_color[2]); } int KX_LightObject::pyattr_set_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) diff --git a/source/gameengine/Ketsji/KX_MouseActuator.cpp b/source/gameengine/Ketsji/KX_MouseActuator.cpp index 3d74bd7c98a..aae5d18189a 100644 --- a/source/gameengine/Ketsji/KX_MouseActuator.cpp +++ b/source/gameengine/Ketsji/KX_MouseActuator.cpp @@ -208,6 +208,9 @@ bool KX_MouseActuator::Update() parent->ApplyRotation(rotation, m_local_x); } } + else { + setposition[0] = 0.5; + } //Calculating Y axis. if (m_use_axis_y) { @@ -266,6 +269,9 @@ bool KX_MouseActuator::Update() parent->ApplyRotation(rotation, m_local_y); } } + else { + setposition[1] = 0.5; + } setMousePosition(setposition[0], setposition[1]); diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 2dbafdad3d9..a9f6bb0d2ff 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -60,15 +60,21 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, int startx, int starty, - short int mousemode, - int focusmode, - bool bTouchPulse, - KX_Scene* kxscene, - KX_KetsjiEngine *kxengine, - SCA_IObject* gameobj) + short int mousemode, + int focusmode, + bool bTouchPulse, + const STR_String& propname, + bool bFindMaterial, + bool bXRay, + KX_Scene* kxscene, + KX_KetsjiEngine *kxengine, + SCA_IObject* gameobj) : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj), m_focusmode(focusmode), m_bTouchPulse(bTouchPulse), + m_bXRay(bXRay), + m_bFindMaterial(bFindMaterial), + m_propertyname(propname), m_kxscene(kxscene), m_kxengine(kxengine) { @@ -146,20 +152,73 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo *client_info, KX_RayCast *r * self-hits are excluded by setting the correct ignore-object.) * Hitspots now become valid. */ KX_GameObject* thisObj = (KX_GameObject*) GetParent(); + + bool bFound = false; + if ((m_focusmode == 2) || hitKXObj == thisObj) { - m_hitObject = hitKXObj; - m_hitPosition = result->m_hitPoint; - m_hitNormal = result->m_hitNormal; - m_hitUV = result->m_hitUV; - return true; + if (m_propertyname.Length() == 0) + { + bFound = true; + } + else + { + if (m_bFindMaterial) + { + if (client_info->m_auxilary_info) + { + bFound = (m_propertyname== ((char*)client_info->m_auxilary_info)); + } + } + else + { + bFound = hitKXObj->GetProperty(m_propertyname) != NULL; + } + } + + if (bFound) + { + m_hitObject = hitKXObj; + m_hitPosition = result->m_hitPoint; + m_hitNormal = result->m_hitNormal; + m_hitUV = result->m_hitUV; + return true; + } } return true; // object must be visible to trigger //return false; // occluded objects can trigger } - +/* this function is used to pre-filter the object before casting the ray on them. + * This is useful for "X-Ray" option when we want to see "through" unwanted object. + */ +bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo* client) +{ + if (client->m_type > KX_ClientObjectInfo::ACTOR) + { + // Unknown type of object, skip it. + // Should not occur as the sensor objects are filtered in RayTest() + printf("Invalid client type %d found ray casting\n", client->m_type); + return false; + } + if (m_bXRay && m_propertyname.Length() != 0) + { + if (m_bFindMaterial) + { + // not quite correct: an object may have multiple material + // should check all the material and not only the first one + if (!client->m_auxilary_info || (m_propertyname != ((char*)client->m_auxilary_info))) + return false; + } + else + { + if (client->m_gameobject->GetProperty(m_propertyname) == NULL) + return false; + } + } + return true; +} bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam) { @@ -384,7 +443,10 @@ PyAttributeDef KX_MouseFocusSensor::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("hitPosition", KX_MouseFocusSensor, pyattr_get_hit_position), KX_PYATTRIBUTE_RO_FUNCTION("hitNormal", KX_MouseFocusSensor, pyattr_get_hit_normal), KX_PYATTRIBUTE_RO_FUNCTION("hitUV", KX_MouseFocusSensor, pyattr_get_hit_uv), - KX_PYATTRIBUTE_BOOL_RW("usePulseFocus", KX_MouseFocusSensor,m_bTouchPulse), + KX_PYATTRIBUTE_BOOL_RW("usePulseFocus", KX_MouseFocusSensor, m_bTouchPulse), + KX_PYATTRIBUTE_BOOL_RW("useXRay", KX_MouseFocusSensor, m_bXRay), + KX_PYATTRIBUTE_BOOL_RW("useMaterial", KX_MouseFocusSensor, m_bFindMaterial), + KX_PYATTRIBUTE_STRING_RW("propName", 0, MAX_PROP_NAME, false, KX_MouseFocusSensor, m_propertyname), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 1f7809831e7..0c7c8ab676a 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -57,6 +57,9 @@ class KX_MouseFocusSensor : public SCA_MouseSensor short int mousemode, int focusmode, bool bTouchPulse, + const STR_String& propname, + bool bFindMaterial, + bool bXRay, KX_Scene* kxscene, KX_KetsjiEngine* kxengine, SCA_IObject* gameobj); @@ -88,7 +91,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor }; bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data); - bool NeedRayCast(KX_ClientObjectInfo* client) { return true; } + bool NeedRayCast(KX_ClientObjectInfo* client); const MT_Point3& RaySource() const; const MT_Point3& RayTarget() const; @@ -134,6 +137,21 @@ class KX_MouseFocusSensor : public SCA_MouseSensor bool m_bTouchPulse; /** + * Flags get through other objects + */ + bool m_bXRay; + + /** + * Flags material + */ + bool m_bFindMaterial; + + /** + * Property or material name + */ + STR_String m_propertyname; + + /** * Flags whether the previous test evaluated positive. */ bool m_positive_event; diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp index 998b856497e..8360681759a 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -111,7 +111,7 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, float *&dvertices, int &ndvertsuniq, unsigned short *&dtris, int& ndtris, int &vertsPerPoly) { - DerivedMesh* dm = mesh_create_derived_no_virtual(KX_GetActiveScene()->GetBlenderScene(), GetBlenderObject(), + DerivedMesh* dm = mesh_create_derived_no_virtual(GetScene()->GetBlenderScene(), GetBlenderObject(), NULL, CD_MASK_MESH); CustomData *pdata = dm->getPolyDataLayout(dm); int* recastData = (int*) CustomData_get_layer(pdata, CD_RECAST); diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index e9843b0af5b..ebf1b9ec577 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -740,6 +740,7 @@ PyObject *initPythonConstraintBinding() KX_MACRO_addTypesToDict(d, ANGULAR_CONSTRAINT, PHY_ANGULAR_CONSTRAINT); KX_MACRO_addTypesToDict(d, CONETWIST_CONSTRAINT, PHY_CONE_TWIST_CONSTRAINT); KX_MACRO_addTypesToDict(d, VEHICLE_CONSTRAINT, PHY_VEHICLE_CONSTRAINT); + KX_MACRO_addTypesToDict(d, GENERIC_6DOF_CONSTRAINT, PHY_GENERIC_6DOF_CONSTRAINT); // Check for errors if (PyErr_Occurred()) { diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index ca6658773e9..fefc64b4bad 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -88,6 +88,7 @@ extern "C" { #include "KX_SteeringActuator.h" #include "KX_NavMeshObject.h" #include "KX_MouseActuator.h" +#include "KX_TrackToActuator.h" #include "SCA_IInputDevice.h" #include "SCA_PropertySensor.h" @@ -200,7 +201,16 @@ static PyObject *gp_OrigPythonSysModules= NULL; //#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromLong(SCA_IInputDevice::KX_##name)) //#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item) /* For the defines for types from logic bricks, we do stuff explicitly... */ -#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name2)); Py_DECREF(item) +#define KX_MACRO_addTypesToDict(dict, name, value) KX_MACRO_addTypesToDict_fn(dict, #name, value) +static void KX_MACRO_addTypesToDict_fn(PyObject *dict, const char *name, long value) +{ + PyObject *item; + + item = PyLong_FromLong(value); + PyDict_SetItemString(dict, name, item); + Py_DECREF(item); +} + // temporarily python stuff, will be put in another place later ! @@ -247,7 +257,7 @@ static PyObject *gPyExpandPath(PyObject *, PyObject *args) BLI_strncpy(expanded, filename, FILE_MAX); BLI_path_abs(expanded, gp_GamePythonPath); - return PyUnicode_DecodeFSDefault(expanded); + return PyC_UnicodeFromByte(expanded); } static char gPyStartGame_doc[] = @@ -536,7 +546,7 @@ static PyObject *gPyGetBlendFileList(PyObject *, PyObject *args) while ((dirp = readdir(dp)) != NULL) { if (BLI_testextensie(dirp->d_name, ".blend")) { - value= PyUnicode_DecodeFSDefault(dirp->d_name); + value = PyC_UnicodeFromByte(dirp->d_name); PyList_Append(list, value); Py_DECREF(value); } @@ -1391,6 +1401,71 @@ static PyObject *gPyGetVsync(PyObject *) return PyLong_FromLong(interval); } +static PyObject *gPyShowFramerate(PyObject *, PyObject *args) +{ + int visible; + if (!PyArg_ParseTuple(args,"i:showFramerate",&visible)) + return NULL; + + if (visible && gp_KetsjiEngine) + gp_KetsjiEngine->SetShowFramerate(true); + else + gp_KetsjiEngine->SetShowFramerate(false); + + Py_RETURN_NONE; +} + +static PyObject *gPyShowProfile(PyObject *, PyObject *args) +{ + int visible; + if (!PyArg_ParseTuple(args,"i:showProfile",&visible)) + return NULL; + + if (visible && gp_KetsjiEngine) + gp_KetsjiEngine->SetShowProfile(true); + else + gp_KetsjiEngine->SetShowProfile(false); + + Py_RETURN_NONE; +} + +static PyObject *gPyShowProperties(PyObject *, PyObject *args) +{ + int visible; + if (!PyArg_ParseTuple(args,"i:showProperties",&visible)) + return NULL; + + if (visible && gp_KetsjiEngine) + gp_KetsjiEngine->SetShowProperties(true); + else + gp_KetsjiEngine->SetShowProperties(false); + + Py_RETURN_NONE; +} + +static PyObject *gPyAutoDebugList(PyObject *, PyObject *args) +{ + int add; + if (!PyArg_ParseTuple(args,"i:autoAddProperties",&add)) + return NULL; + + if (add && gp_KetsjiEngine) + gp_KetsjiEngine->SetAutoAddDebugProperties(true); + else + gp_KetsjiEngine->SetAutoAddDebugProperties(false); + + Py_RETURN_NONE; +} + +static PyObject *gPyClearDebugList(PyObject *) +{ + if (gp_KetsjiScene) + gp_KetsjiScene->RemoveAllDebugProperties(); + + Py_RETURN_NONE; +} + + static struct PyMethodDef rasterizer_methods[] = { {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, METH_VARARGS, "getWindowWidth doc"}, @@ -1438,6 +1513,11 @@ static struct PyMethodDef rasterizer_methods[] = { {"getMipmapping", (PyCFunction) gPyGetMipmapping, METH_NOARGS, ""}, {"setVsync", (PyCFunction) gPySetVsync, METH_VARARGS, ""}, {"getVsync", (PyCFunction) gPyGetVsync, METH_NOARGS, ""}, + {"showFramerate",(PyCFunction) gPyShowFramerate, METH_VARARGS, "show or hide the framerate"}, + {"showProfile",(PyCFunction) gPyShowProfile, METH_VARARGS, "show or hide the profile"}, + {"showProperties",(PyCFunction) gPyShowProperties, METH_VARARGS, "show or hide the debug properties"}, + {"autoDebugList",(PyCFunction) gPyAutoDebugList, METH_VARARGS, "enable or disable auto adding debug properties to the debug list"}, + {"clearDebugList",(PyCFunction) gPyClearDebugList, METH_NOARGS, "clears the debug property list"}, { NULL, (PyCFunction) NULL, 0, NULL } }; @@ -1686,6 +1766,17 @@ PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Y, KX_RaySensor::KX_RAY_AXIS_NEG_Y); KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Z, KX_RaySensor::KX_RAY_AXIS_NEG_Z); + /* TrackTo Actuator */ + KX_MACRO_addTypesToDict(d, KX_TRACK_UPAXIS_POS_X, KX_TrackToActuator::KX_TRACK_UPAXIS_POS_X); + KX_MACRO_addTypesToDict(d, KX_TRACK_UPAXIS_POS_Y, KX_TrackToActuator::KX_TRACK_UPAXIS_POS_Y); + KX_MACRO_addTypesToDict(d, KX_TRACK_UPAXIS_POS_Z, KX_TrackToActuator::KX_TRACK_UPAXIS_POS_Z); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_POS_X, KX_TrackToActuator::KX_TRACK_TRAXIS_POS_X); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_POS_Y, KX_TrackToActuator::KX_TRACK_TRAXIS_POS_Y); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_POS_Z, KX_TrackToActuator::KX_TRACK_TRAXIS_POS_Z); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_NEG_X, KX_TrackToActuator::KX_TRACK_TRAXIS_NEG_X); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_NEG_Y, KX_TrackToActuator::KX_TRACK_TRAXIS_NEG_Y); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_NEG_Z, KX_TrackToActuator::KX_TRACK_TRAXIS_NEG_Z); + /* Dynamic actuator */ KX_MACRO_addTypesToDict(d, KX_DYN_RESTORE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_RESTORE_DYNAMICS); KX_MACRO_addTypesToDict(d, KX_DYN_DISABLE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_DISABLE_DYNAMICS); @@ -1885,7 +1976,7 @@ static void initPySysObjects__append(PyObject *sys_path, const char *filename) BLI_split_dir_part(filename, expanded, sizeof(expanded)); /* get the dir part of filename only */ BLI_path_abs(expanded, gp_GamePythonPath); /* filename from lib->filename is (always?) absolute, so this may not be needed but it wont hurt */ BLI_cleanup_file(gp_GamePythonPath, expanded); /* Don't use BLI_cleanup_dir because it adds a slash - BREAKS WIN32 ONLY */ - item= PyUnicode_DecodeFSDefault(expanded); + item = PyC_UnicodeFromByte(expanded); // printf("SysPath - '%s', '%s', '%s'\n", expanded, filename, gp_GamePythonPath); @@ -2190,7 +2281,6 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) PyObject *m; PyObject *d; - PyObject *item; /* Use existing module where possible * be careful not to init any runtime vars after this */ @@ -2320,7 +2410,6 @@ PyObject *initGameKeys() { PyObject *m; PyObject *d; - PyObject *item; /* Use existing module where possible */ m = PyImport_ImportModule( "GameKeys" ); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 3d71327828e..625bbee2c8e 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -595,7 +595,9 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal void KX_Scene::ReplicateLogic(KX_GameObject* newobj) { /* add properties to debug list, for added objects and DupliGroups */ - AddObjectDebugProperties(newobj); + if (KX_GetActiveEngine()->GetAutoAddDebugProperties()) { + AddObjectDebugProperties(newobj); + } // also relink the controller to sensors/actuators SCA_ControllerList& controllers = newobj->GetControllers(); //SCA_SensorList& sensors = newobj->GetSensors(); @@ -1005,7 +1007,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) int ret; KX_GameObject* newobj = (KX_GameObject*) gameobj; - /* remove property to debug list */ + /* remove property from debug list */ RemoveObjectDebugProperties(newobj); /* Invalidate the python reference, since the object may exist in script lists @@ -1529,6 +1531,9 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer); } } + + // Now that we know visible meshes, update LoDs + UpdateObjectLods(); } // logic stuff @@ -1634,6 +1639,20 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t void KX_Scene::UpdateAnimations(double curtime) { + KX_KetsjiEngine *engine = KX_GetActiveEngine(); + + if (engine->GetRestrictAnimationFPS()) + { + // Handle the animations independently of the logic time step + double anim_timestep = 1.0 / GetAnimationFPS(); + if (curtime - m_previousAnimTime < anim_timestep) + return; + + // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep) + // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime)); + m_previousAnimTime = curtime; + } + TaskPool *pool = BLI_task_pool_create(KX_GetActiveEngine()->GetTaskScheduler(), &curtime); for (int i=0; i<m_animatedlist->GetCount(); ++i) { @@ -2005,7 +2024,11 @@ bool KX_Scene::MergeScene(KX_Scene *other) { KX_GameObject* gameobj = (KX_GameObject*)other->GetObjectList()->GetValue(i); MergeScene_GameObject(gameobj, this, other); - AddObjectDebugProperties(gameobj); // add properties to debug list for LibLoad objects + + /* add properties to debug list for LibLoad objects */ + if (KX_GetActiveEngine()->GetAutoAddDebugProperties()) { + AddObjectDebugProperties(gameobj); + } gameobj->UpdateBuckets(false); /* only for active objects */ } @@ -2478,16 +2501,18 @@ KX_PYMETHODDEF_DOC(KX_Scene, restart, KX_PYMETHODDEF_DOC(KX_Scene, replace, "replace(newScene)\n" - "Replaces this scene with another one.\n") + "Replaces this scene with another one.\n" + "Return True if the new scene exists and scheduled for replacement, False otherwise.\n") { char* name; if (!PyArg_ParseTuple(args, "s:replace", &name)) return NULL; - KX_GetActiveEngine()->ReplaceScene(m_sceneName, name); + if (KX_GetActiveEngine()->ReplaceScene(m_sceneName, name)) + Py_RETURN_TRUE; - Py_RETURN_NONE; + Py_RETURN_FALSE; } KX_PYMETHODDEF_DOC(KX_Scene, suspend, diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 2e1ee9f101d..c5840c28041 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -289,6 +289,8 @@ protected: double m_suspendedtime; double m_suspendeddelta; + double m_previousAnimTime; //the last time animations were updated + struct Scene* m_blenderScene; RAS_2DFilterManager m_filtermanager; diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp index 2fa72c04a20..ff192299702 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp +++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp @@ -602,7 +602,7 @@ int KX_SteeringActuator::pyattr_set_navmesh(void *self, const struct KX_PYATTRIB if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SteeringActuator")) return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error - if (!PyObject_TypeCheck(value, &KX_NavMeshObject::Type)) + if (dynamic_cast<KX_NavMeshObject *>(gameobj) == NULL) { PyErr_Format(PyExc_TypeError, "KX_NavMeshObject is expected"); return PY_SET_ATTR_FAIL; diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 90b7850946b..75baf5fac1d 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -31,8 +31,7 @@ * Replace the mesh for this actuator's parent */ -/* todo: not all trackflags / upflags are implemented/tested ! - * m_trackflag is used to determine the forward tracking direction +/* m_trackflag is used to determine the forward tracking direction * m_upflag for the up direction * normal situation is +y for forward, +z for up */ @@ -177,7 +176,77 @@ static MT_Matrix3x3 matrix3x3_interpol(MT_Matrix3x3 oldmat, MT_Matrix3x3 mat, in return EulToMat3(eul); } +static float basis_cross(int n, int m) +{ + switch (n - m) { + case 1: + case -2: + return 1.0f; + + case -1: + case 2: + return -1.0f; + + default: + return 0.0f; + } +} +/* vectomat function obtained from constrain.c and modified to work with MOTO library */ +static MT_Matrix3x3 vectomat(MT_Vector3 vec, short axis, short upflag, short threedimup) +{ + MT_Matrix3x3 mat; + MT_Vector3 y(MT_Scalar(0.0), MT_Scalar(1.0), MT_Scalar(0.0)); + MT_Vector3 z(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(1.0)); /* world Z axis is the global up axis */ + MT_Vector3 proj; + MT_Vector3 right; + MT_Scalar mul; + int right_index; + + /* Normalized Vec vector*/ + vec = vec.safe_normalized_vec(z); + + /* if 2D doesn't move the up vector */ + if (!threedimup){ + vec.setValue(MT_Scalar(vec[0]), MT_Scalar(vec[1]), MT_Scalar(0.0)); + vec = (vec - z.dot(vec)*z).safe_normalized_vec(z); + } + + if (axis > 2) + axis -= 3; + else + vec = -vec; + + /* project the up vector onto the plane specified by vec */ + /* first z onto vec... */ + mul = z.dot(vec) / vec.dot(vec); + proj = vec * mul; + /* then onto the plane */ + proj = z - proj; + /* proj specifies the transformation of the up axis */ + proj = proj.safe_normalized_vec(y); + + /* Normalized cross product of vec and proj specifies transformation of the right axis */ + right = proj.cross(vec); + right.normalize(); + + if (axis != upflag) { + right_index = 3 - axis - upflag; + + /* account for up direction, track direction */ + right = right * basis_cross(axis, upflag); + mat.setRow(right_index, right); + mat.setRow(upflag, proj); + mat.setRow(axis, vec); + mat = mat.inverse(); + } + /* identity matrix - don't do anything if the two axes are the same */ + else { + mat.setIdentity(); + } + + return mat; +} KX_TrackToActuator::~KX_TrackToActuator() { @@ -247,153 +316,24 @@ bool KX_TrackToActuator::Update(double curtime, bool frame) else if (m_object) { KX_GameObject* curobj = (KX_GameObject*) GetParent(); - MT_Vector3 dir = ((KX_GameObject*)m_object)->NodeGetWorldPosition() - curobj->NodeGetWorldPosition(); - if (dir.length2()) - dir.normalize(); - MT_Vector3 up(0,0,1); - - -#ifdef DSADSA - switch (m_upflag) - { - case 0: - { - up.setValue(1.0,0,0); - break; - } - case 1: - { - up.setValue(0,1.0,0); - break; - } - case 2: - default: - { - up.setValue(0,0,1.0); - } - } -#endif - if (m_allow3D) - { - up = (up - up.dot(dir) * dir).safe_normalized(); - - } - else - { - dir = (dir - up.dot(dir)*up).safe_normalized(); - } - - MT_Vector3 left; + MT_Vector3 dir = curobj->NodeGetWorldPosition() - ((KX_GameObject*)m_object)->NodeGetWorldPosition(); MT_Matrix3x3 mat; - - switch (m_trackflag) - { - case 0: // TRACK X - { - // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = dir.safe_normalized(); - dir = up.cross(left).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - }; - case 1: // TRACK Y - { - // (0.0 , 1.0 , 0.0 ) y direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = (dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - } - - case 2: // track Z - { - left = up.safe_normalized(); - up = dir.safe_normalized(); - dir = left; - left = (dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - break; - } - - case 3: // TRACK -X - { - // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = -dir.safe_normalized(); - dir = up.cross(left).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - }; - case 4: // TRACK -Y - { - // (0.0 , -1.0 , 0.0 ) -y direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = (-dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], -dir[0],up[0], - left[1], -dir[1],up[1], - left[2], -dir[2],up[2] - ); - break; - } - case 5: // track -Z - { - left = up.safe_normalized(); - up = -dir.safe_normalized(); - dir = left; - left = (dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - } - - default: - { - // (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = -dir.safe_normalized(); - dir = up.cross(left).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - } - } - MT_Matrix3x3 oldmat; - oldmat= curobj->NodeGetWorldOrientation(); + + mat = vectomat(dir, m_trackflag, m_upflag, m_allow3D); + oldmat = curobj->NodeGetWorldOrientation(); /* erwin should rewrite this! */ - mat= matrix3x3_interpol(oldmat, mat, m_time); + mat = matrix3x3_interpol(oldmat, mat, m_time); - - if (m_parentobj) { // check if the model is parented and calculate the child transform + /* check if the model is parented and calculate the child transform */ + if (m_parentobj) { MT_Point3 localpos; localpos = curobj->GetSGNode()->GetLocalPosition(); // Get the inverse of the parent matrix MT_Matrix3x3 parentmatinv; - parentmatinv = m_parentobj->NodeGetWorldOrientation ().inverse (); + parentmatinv = m_parentobj->NodeGetWorldOrientation().inverse(); // transform the local coordinate system into the parents system mat = parentmatinv * mat; // append the initial parent local rotation matrix @@ -404,8 +344,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame) curobj->NodeSetLocalPosition(localpos); //curobj->UpdateTransform(); } - else - { + else { curobj->NodeSetLocalOrientation(mat); } @@ -451,6 +390,8 @@ PyMethodDef KX_TrackToActuator::Methods[] = { PyAttributeDef KX_TrackToActuator::Attributes[] = { KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_TrackToActuator,m_time), KX_PYATTRIBUTE_BOOL_RW("use3D",KX_TrackToActuator,m_allow3D), + KX_PYATTRIBUTE_INT_RW("upAxis", 0, 2, true, KX_TrackToActuator,m_upflag), + KX_PYATTRIBUTE_INT_RW("trackAxis", 0, 5, true, KX_TrackToActuator,m_trackflag), KX_PYATTRIBUTE_RW_FUNCTION("object", KX_TrackToActuator, pyattr_get_object, pyattr_set_object), { NULL } //Sentinel diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 4df240a0063..124014eede2 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -68,6 +68,21 @@ class KX_TrackToActuator : public SCA_IActuator virtual void Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map); virtual bool Update(double curtime, bool frame); + //Python Interface + enum UpAxis { + KX_TRACK_UPAXIS_POS_X = 0, + KX_TRACK_UPAXIS_POS_Y, + KX_TRACK_UPAXIS_POS_Z + }; + enum TrackAxis { + KX_TRACK_TRAXIS_POS_X = 0, + KX_TRACK_TRAXIS_POS_Y, + KX_TRACK_TRAXIS_POS_Z, + KX_TRACK_TRAXIS_NEG_X, + KX_TRACK_TRAXIS_NEG_Y, + KX_TRACK_TRAXIS_NEG_Z + }; + #ifdef WITH_PYTHON /* Python part */ diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt index e295b701b36..e52dc1ba052 100644 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ b/source/gameengine/Physics/Bullet/CMakeLists.txt @@ -29,6 +29,7 @@ remove_strict_flags() set(INC . ../common + ../../Converter ../../Expressions ../../GameLogic ../../Ketsji diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 69e190c79db..e17d4402556 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -42,6 +42,7 @@ subject to the following restrictions: #include "PHY_Pro.h" #include "KX_GameObject.h" #include "KX_PythonInit.h" // for KX_RasterizerDrawDebugLine +#include "KX_BlenderSceneConverter.h" #include "RAS_MeshObject.h" #include "RAS_Polygon.h" #include "RAS_TexVert.h" @@ -83,7 +84,7 @@ void DrawRasterizerLine(const float* from,const float* to,int color); // This was copied from the old KX_ConvertPhysicsObjects #ifdef WIN32 -#if defined(_MSC_VER) && (_MSC_VER >= 1310) +#ifdef _MSC_VER //only use SIMD Hull code under Win32 //#define TEST_HULL 1 #ifdef TEST_HULL @@ -877,6 +878,14 @@ void CcdPhysicsEnvironment::ProcessFhSprings(double curTime,float interval) } } +int CcdPhysicsEnvironment::GetDebugMode() const +{ + if (m_debugDrawer) { + return m_debugDrawer->getDebugMode(); + } + return 0; +} + void CcdPhysicsEnvironment::SetDebugMode(int debugMode) { if (m_debugDrawer) { @@ -2085,7 +2094,7 @@ void CcdPhysicsEnvironment::SetConstraintParam(int constraintId,int param,float case 12: case 13: case 14: case 15: case 16: case 17: { - //param 13-17 are for motorized springs on each of the degrees of freedom + //param 12-17 are for motorized springs on each of the degrees of freedom btGeneric6DofSpringConstraint* genCons = (btGeneric6DofSpringConstraint*)typedConstraint; int springIndex = param-12; if (value0!=0.f) @@ -3036,9 +3045,17 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject CcdConstructionInfo ci; class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo(); - KX_GameObject *parent = gameobj->GetParent(); - if (parent) + // get Root Parent of blenderobject + Object *blenderparent = blenderobject->parent; + while (blenderparent && blenderparent->parent) { + blenderparent = blenderparent->parent; + } + + KX_GameObject *parent = NULL; + if (blenderparent) { + KX_BlenderSceneConverter *converter = (KX_BlenderSceneConverter*)KX_GetActiveEngine()->GetSceneConverter(); + parent = converter->FindGameObject(blenderparent); isbulletdyna = false; isbulletsoftbody = false; shapeprops->m_mass = 0.f; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index a94e205b160..ff8a3f4f9f9 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -139,6 +139,7 @@ protected: virtual float GetFixedTimeStep() { return 0.f; } virtual void SetDebugMode(int debugMode); + virtual int GetDebugMode()const; virtual void SetGravity(float x,float y,float z); virtual void GetGravity(MT_Vector3& grav); diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index 2700997ccd4..2a8249b9558 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -39,6 +39,7 @@ incs = [ '#source/blender/blenkernel', '#source/blender/blenlib', '#source/blender/makesdna', + '#source/gameengine/Converter', '#source/gameengine/Expressions', '#source/gameengine/GameLogic', '#source/gameengine/Ketsji', diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp index 1bb5431c749..979128370ee 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp @@ -78,8 +78,10 @@ float DummyPhysicsEnvironment::GetFixedTimeStep() return 0.f; } - - +int DummyPhysicsEnvironment::GetDebugMode() const +{ + return 0; +} void DummyPhysicsEnvironment::SetGravity(float x,float y,float z) { diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index a645af1e471..cfc8841cac2 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -56,6 +56,8 @@ public: virtual void SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); virtual float GetFixedTimeStep(); + virtual int GetDebugMode() const; + virtual void SetGravity(float x,float y,float z); virtual void GetGravity(class MT_Vector3& grav); diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 81a45f93993..dd762b02b4e 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -126,6 +126,8 @@ class PHY_IPhysicsEnvironment //returns 0.f if no fixed timestep is used virtual float GetFixedTimeStep()=0; + ///getDebugMode return the actual debug visualization state + virtual int GetDebugMode()const=0; ///setDebugMode is used to support several ways of debug lines, contact point visualization virtual void SetDebugMode(int debugMode) {} ///setNumIterations set the number of iterations for iterative solvers diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp index 61c658b22fd..e0613350b77 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp @@ -247,7 +247,7 @@ void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); current_blmat_nr = current_polymat->GetMaterialIndex(); current_image = current_polymat->GetBlenderImage(); - ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); + ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL, DM_DRAW_USE_ACTIVE_UV); } return; } diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index 6cc8d287e66..705d9136cbe 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -163,7 +163,7 @@ void ImageBuff::plot(unsigned char *img, short width, short height, short x, sho // assign temporarily our buffer to the ImBuf buffer, we use the same format tmpbuf->rect = (unsigned int*)img; m_imbuf->rect = m_image; - IMB_rectblend(m_imbuf, m_imbuf, tmpbuf, NULL, NULL, 0, x, y, x, y, 0, 0, width, height, (IMB_BlendMode)mode); + IMB_rectblend(m_imbuf, m_imbuf, tmpbuf, NULL, NULL, NULL, 0, x, y, x, y, 0, 0, width, height, (IMB_BlendMode)mode, false); // remove so that MB_freeImBuf will free our buffer m_imbuf->rect = NULL; tmpbuf->rect = NULL; @@ -186,7 +186,7 @@ void ImageBuff::plot(ImageBuff *img, short x, short y, short mode) // assign temporarily our buffer to the ImBuf buffer, we use the same format img->m_imbuf->rect = img->m_image; m_imbuf->rect = m_image; - IMB_rectblend(m_imbuf, m_imbuf, img->m_imbuf, NULL, NULL, 0, x, y, x, y, 0, 0, img->m_imbuf->x, img->m_imbuf->y, (IMB_BlendMode)mode); + IMB_rectblend(m_imbuf, m_imbuf, img->m_imbuf, NULL, NULL, NULL, 0, x, y, x, y, 0, 0, img->m_imbuf->x, img->m_imbuf->y, (IMB_BlendMode)mode, false); // remove so that MB_freeImBuf will free our buffer m_imbuf->rect = NULL; img->m_imbuf->rect = NULL; diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 57b2e85845c..617e7fd1d8e 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -274,6 +274,8 @@ void ImageRender::Render() m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + m_scene->UpdateAnimations(m_engine->GetFrameTime()); + m_scene->RenderBuckets(camtrans, m_rasterizer); m_scene->RenderFonts(); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 179f1ced03b..edf3c58bcbe 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -545,6 +545,7 @@ void VideoFFmpeg::openFile (char *filename) // 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) || + !strncmp(filename, "rtsp://", 7) || (m_formatCtx->pb && !m_formatCtx->pb->seekable) ) { @@ -680,6 +681,12 @@ bool VideoFFmpeg::play (void) { // set video position setPositions(); + + if (m_isStreaming) + { + av_read_play(m_formatCtx); + } + // return success return true; } @@ -696,6 +703,10 @@ bool VideoFFmpeg::pause (void) { if (VideoBase::pause()) { + if (m_isStreaming) + { + av_read_pause(m_formatCtx); + } return true; } } |