diff options
author | Maxime Curioni <maxime.curioni@gmail.com> | 2008-07-12 09:02:47 +0400 |
---|---|---|
committer | Maxime Curioni <maxime.curioni@gmail.com> | 2008-07-12 09:02:47 +0400 |
commit | 8398730043faeb9af860ca7a408a5a4ba49b46f1 (patch) | |
tree | bc38242ec4333e81f5aea3205fffa21f669abffe /source/gameengine | |
parent | d124d3c5cdfdc9d470a4734281396b97c4d3afb5 (diff) |
soc-2008-mxcurioni: merge with trunk - rev 15540
Diffstat (limited to 'source/gameengine')
56 files changed, 1081 insertions, 938 deletions
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 230d6b262c6..ed6ea7c5f6a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -26,6 +26,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "GL/glew.h" #include "KX_BlenderGL.h" #ifdef HAVE_CONFIG_H @@ -44,7 +45,6 @@ #include "BMF_Api.h" -#include "GL/glew.h" #include "BIF_gl.h" #include "BL_Material.h" // MAXTEX diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 44f6ec1af90..5d6dd694765 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -184,6 +184,11 @@ bool BL_ActionActuator::Update(double curtime, bool frame) if (bNegativeEvent) { + // dont continue where we left off when restarting + if (m_end_reset) { + m_flag &= ~ACT_FLAG_LOCKINPUT; + } + if (!(m_flag & ACT_FLAG_ACTIVE)) return false; m_flag &= ~ACT_FLAG_ACTIVE; @@ -472,8 +477,10 @@ PyMethodDef BL_ActionActuator::Methods[] = { {"getFrameProperty", (PyCFunction) BL_ActionActuator::sPyGetFrameProperty, METH_VARARGS, GetFrameProperty_doc}, {"setChannel", (PyCFunction) BL_ActionActuator::sPySetChannel, METH_VARARGS, SetChannel_doc}, // {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS}, - {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, GetType_doc}, + {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, GetType_doc}, {"setType", (PyCFunction) BL_ActionActuator::sPySetType, METH_VARARGS, SetType_doc}, + {"getContinue", (PyCFunction) BL_ActionActuator::sPyGetContinue, METH_NOARGS, 0}, + {"setContinue", (PyCFunction) BL_ActionActuator::sPySetContinue, METH_O, 0}, {NULL,NULL} //Sentinel }; @@ -978,7 +985,26 @@ PyObject* BL_ActionActuator::PySetType(PyObject* self, default: printf("Invalid type for action actuator: %d\n", typeArg); /* error */ } + Py_RETURN_NONE; +} + +PyObject* BL_ActionActuator::PyGetContinue(PyObject* self) { + return PyInt_FromLong((long)(m_end_reset==0)); +} + +PyObject* BL_ActionActuator::PySetContinue(PyObject* self, PyObject* value) { + int param = PyObject_IsTrue( value ); - Py_Return; + if( param == -1 ) { + PyErr_SetString( PyExc_TypeError, "expected True/False or 0/1" ); + return NULL; + } + + if (param) { + m_end_reset = 0; + } else { + m_end_reset = 1; + } + Py_RETURN_NONE; } diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 190f727c9c3..a67b6d29b74 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -47,6 +47,7 @@ public: short playtype, short blendin, short priority, + short end_reset, float stride, PyTypeObject* T=&Type) : SCA_IActuator(gameobj,T), @@ -64,6 +65,7 @@ public: m_stridelength(stride), m_playtype(playtype), m_priority(priority), + m_end_reset(end_reset), m_pose(NULL), m_blendpose(NULL), m_userpose(NULL), @@ -101,6 +103,8 @@ public: // KX_PYMETHOD(BL_ActionActuator,GetChannel); KX_PYMETHOD_DOC(BL_ActionActuator,GetType); KX_PYMETHOD_DOC(BL_ActionActuator,SetType); + KX_PYMETHOD_NOARGS(BL_ActionActuator,GetContinue); + KX_PYMETHOD_O(BL_ActionActuator,SetContinue); virtual PyObject* _getattr(const STR_String& attr); @@ -137,6 +141,7 @@ protected: float m_stridelength; short m_playtype; short m_priority; + short m_end_reset; struct bPose* m_pose; struct bPose* m_blendpose; struct bPose* m_userpose; diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 665783a1ba5..f3e22cd297a 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -312,11 +312,13 @@ BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, MTFace* tface, + const char *tfaceName, MFace* mface, MCol* mmcol, int lightlayer, Object* blenderobj, - MTF_localLayer *layers) + MTF_localLayer *layers, + bool glslmat) { //this needs some type of manager BL_Material *material = new BL_Material(); @@ -335,7 +337,7 @@ BL_Material* ConvertMaterial( if(validmat) { // use vertex colors by explicitly setting - if(mat->mode &MA_VERTEXCOLP) + if(mat->mode &MA_VERTEXCOLP || glslmat) type = 0; // use lighting? @@ -558,6 +560,7 @@ BL_Material* ConvertMaterial( } else { int valid = 0; + // check for tface tex to fallback on if( validface ){ @@ -590,6 +593,7 @@ BL_Material* ConvertMaterial( } MT_Point2 uv[4]; 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); @@ -616,6 +620,8 @@ BL_Material* ConvertMaterial( if (mface->v4) uv[3] = MT_Point2(tface->uv[3]); + + uvName = tfaceName; } else { // nothing at all @@ -641,39 +647,38 @@ BL_Material* ConvertMaterial( isFirstSet = false; else { - MT_Point2 uvSet[4]; for (int lay=0; lay<MAX_MTFACE; lay++) { MTF_localLayer& layer = layers[lay]; if (layer.face == 0) break; - - bool processed = false; if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) { + 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]); if (mface->v4) uvSet[3] = MT_Point2(layer.face->uv[3]); + else + uvSet[3] = MT_Point2(0.0f, 0.0f); - processed = true; - } - - if (!processed) continue; - - if (isFirstSet) - { - uv[0] = uvSet[0]; uv[1] = uvSet[1]; - uv[2] = uvSet[2]; uv[3] = uvSet[3]; - isFirstSet = false; - } - else - { - uv2[0] = uvSet[0]; uv2[1] = uvSet[1]; - uv2[2] = uvSet[2]; uv2[3] = uvSet[3]; - map.mapping |= USECUSTOMUV; + if (isFirstSet) + { + uv[0] = uvSet[0]; uv[1] = uvSet[1]; + uv[2] = uvSet[2]; uv[3] = uvSet[3]; + isFirstSet = false; + uvName = layer.name; + } + else + { + uv2[0] = uvSet[0]; uv2[1] = uvSet[1]; + uv2[2] = uvSet[2]; uv2[3] = uvSet[3]; + map.mapping |= USECUSTOMUV; + uv2Name = layer.name; + } } } } @@ -693,9 +698,8 @@ BL_Material* ConvertMaterial( } material->SetConversionRGB(rgb); - material->SetConversionUV(uv); - material->SetConversionUV2(uv2); - + material->SetConversionUV(uvName, uv); + material->SetConversionUV2(uv2Name, uv2); material->ras_mode |= (mface->v4==0)?TRIANGLE:0; if(validmat) @@ -797,6 +801,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* MFace* mface = static_cast<MFace*>(mesh->mface); MTFace* tface = static_cast<MTFace*>(mesh->mtface); + const char *tfaceName = ""; MCol* mmcol = mesh->mcol; MT_assert(mface || mesh->totface == 0); @@ -832,14 +837,14 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;; layers[validLayers].name = mesh->fdata.layers[i].name; + if(tface == layers[validLayers].face) + tfaceName = layers[validLayers].name; validLayers++; } } meshobj->SetName(mesh->id.name); meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert); - if(skinMesh) - ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.resize(mesh->totvert); for (int f=0;f<mesh->totface;f++,mface++) { @@ -898,8 +903,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* else ma = give_current_material(blenderobj, 1); - bl_mat = ConvertMaterial(mesh, ma, tface, mface, mmcol, lightlayer, blenderobj, layers); - bl_mat->glslmat = converter->GetGLSLMaterials(); + bl_mat = ConvertMaterial(mesh, ma, tface, tfaceName, mface, mmcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); // set the index were dealing with bl_mat->material_index = (int)mface->mat_nr; @@ -1059,35 +1063,25 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* int nverts = mface->v4?4:3; int vtxarray = meshobj->FindVertexArray(nverts,polymat); RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray); - if (skinMesh) { - int d1, d2, d3, d4=0; - bool flat; + bool flat; + + if (skinMesh) { /* If the face is set to solid, all fnors are the same */ if (mface->flag & ME_SMOOTH) flat = false; else flat = true; - - d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat); - d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat); - d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat); - if (nverts==4) - d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat); - poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,d1,flat,polymat,mface->v1)); - poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,d2,flat,polymat,mface->v2)); - poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,d3,flat,polymat,mface->v3)); - if (nverts==4) - poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,d4,flat,polymat,mface->v4)); } else - { - poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,false,polymat,mface->v1)); - poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,false,polymat,mface->v2)); - poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,false,polymat,mface->v3)); - if (nverts==4) - poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,false,polymat,mface->v4)); - } + flat = false; + + poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1)); + poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2)); + poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3)); + if (nverts==4) + poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4)); + meshobj->AddPolygon(poly); if (poly->IsCollider()) { @@ -1125,8 +1119,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* } } meshobj->m_xyz_index_to_vertex_index_mapping.clear(); - if(skinMesh) - ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.clear(); meshobj->UpdateMaterialList(); // pre calculate texture generation @@ -1545,7 +1537,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, -static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) { +static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) { RAS_LightObject lightobj; KX_LightObject *gamelight; @@ -1577,8 +1569,15 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX } else { lightobj.m_type = RAS_LightObject::LIGHT_NORMAL; } + +#ifdef BLENDER_GLSL + if(converter->GetGLSLMaterials()) + GPU_lamp_from_blender(ob, la); - gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj); + gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, ob->gpulamp); +#else + gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, NULL); +#endif BL_ConvertLampIpos(la, gamelight, converter); return gamelight; @@ -1610,7 +1609,7 @@ static KX_GameObject *gameobject_from_blenderobject( { case OB_LAMP: { - KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); + KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); gameobj = gamelight; gamelight->AddRef(); @@ -1660,7 +1659,7 @@ static KX_GameObject *gameobject_from_blenderobject( // two options exists for deform: shape keys and armature // only support relative shape key bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE; - bool bHasDvert = mesh->dvert != NULL; + bool bHasDvert = mesh->dvert != NULL && ob->defbase.first; bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert); if (bHasShapeKey) { @@ -1671,13 +1670,15 @@ static KX_GameObject *gameobject_from_blenderobject( if (bHasArmature) dcont->LoadShapeDrivers(ob->parent); } else if (bHasArmature) { - BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj ); + BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj, + ob, (BL_SkinMeshObject*)meshobj); ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; } else if (bHasDvert) { // this case correspond to a mesh that can potentially deform but not with the // object to which it is attached for the moment. A skin mesh was created in // BL_ConvertMesh() so must create a deformer too! - BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj ); + BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj, + ob, (BL_SkinMeshObject*)meshobj); ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont; } @@ -2075,7 +2076,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (blenderscene->camera) { KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera); - kxscene->SetActiveCamera(gamecamera); + if(gamecamera) + kxscene->SetActiveCamera(gamecamera); } // Set up armatures @@ -2331,7 +2333,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); struct Object* blenderobj = converter->FindBlenderObject(gameobj); - gameobj->SetState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); + gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); + gameobj->ResetState(); } #endif //CONVERT_LOGIC diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index 212827a660f..39d66a90e92 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -39,6 +39,7 @@ #endif #include "RAS_IPolygonMaterial.h" +#include "BL_DeformableGameObject.h" #include "BL_MeshDeformer.h" #include "BL_SkinMeshObject.h" #include "DNA_mesh_types.h" @@ -47,33 +48,40 @@ #include "GEN_Map.h" #include "STR_HashedString.h" -bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat) +bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*) { - size_t i, j, index; - vecVertexArray array; - vecIndexArrays mvarray; - vecIndexArrays diarray; - - RAS_TexVert *tv; - MVert *mvert; - - // For each material - array = m_pMeshObject->GetVertexCache(mat); - mvarray = m_pMeshObject->GetMVertCache(mat); - diarray = m_pMeshObject->GetDIndexCache(mat); - - // For each array - for (i=0; i<array.size(); i++){ - // For each vertex - for (j=0; j<array[i]->size(); j++){ - tv = &((*array[i])[j]); - index = ((*diarray[i])[j]); - - mvert = &(m_bmesh->mvert[((*mvarray[i])[index])]); - tv->SetXYZ(MT_Point3(mvert->co)); + size_t i, j; + float *co; + + // only apply once per frame if the mesh is actually modified + if(m_pMeshObject->MeshModified() && + m_lastDeformUpdate != m_gameobj->GetLastFrame()) { + // For each material + for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); + mit != m_pMeshObject->GetLastMaterial(); ++ mit) { + RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); + + // For each array + for (i=0; i<vertexarrays.size(); i++){ + KX_VertexArray& vertexarray = (*vertexarrays[i]); + + // For each vertex + for (j=0; j<vertexarray.size(); j++){ + RAS_TexVert& v = vertexarray[j]; + co = m_bmesh->mvert[v.getOrigIndex()].co; + v.SetXYZ(MT_Point3(co)); + } + } } + + m_lastDeformUpdate = m_gameobj->GetLastFrame(); + + return true; } - return true; + + return false; } BL_MeshDeformer::~BL_MeshDeformer() @@ -92,83 +100,86 @@ void BL_MeshDeformer::RecalcNormals() /* We don't normalize for performance, not doing it for faces normals * gives area-weight normals which often look better anyway, and use * GL_NORMALIZE so we don't have to do per vertex normalization either - * since the GPU can do it faster - * - * There's a lot of indirection here to get to the data, can this work - * with less arrays/indirection? */ - - vecIndexArrays indexarrays; - vecIndexArrays mvarrays; - vecIndexArrays diarrays; - vecVertexArray vertexarrays; + * since the GPU can do it faster */ size_t i, j; /* set vertex normals to zero */ - for (i=0; i<(size_t)m_bmesh->totvert; i++) - m_transnors[i] = MT_Vector3(0.0f, 0.0f, 0.0f); + memset(m_transnors, 0, sizeof(float)*3*m_bmesh->totvert); /* add face normals to vertices. */ for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); mit != m_pMeshObject->GetLastMaterial(); ++ mit) { RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); - indexarrays = m_pMeshObject->GetIndexCache(mat); - vertexarrays = m_pMeshObject->GetVertexCache(mat); - diarrays = m_pMeshObject->GetDIndexCache(mat); - mvarrays = m_pMeshObject->GetMVertCache(mat); + const vecIndexArrays& indexarrays = m_pMeshObject->GetIndexCache(mat); + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); for (i=0; i<indexarrays.size(); i++) { KX_VertexArray& vertexarray = (*vertexarrays[i]); - const KX_IndexArray& mvarray = (*mvarrays[i]); - const KX_IndexArray& diarray = (*diarrays[i]); const KX_IndexArray& indexarray = (*indexarrays[i]); int nvert = mat->UsesTriangles()? 3: 4; for(j=0; j<indexarray.size(); j+=nvert) { - MT_Point3 mv1, mv2, mv3, mv4, fnor; - int i1 = indexarray[j]; - int i2 = indexarray[j+1]; - int i3 = indexarray[j+2]; - RAS_TexVert& v1 = vertexarray[i1]; - RAS_TexVert& v2 = vertexarray[i2]; - RAS_TexVert& v3 = vertexarray[i3]; - + RAS_TexVert& v1 = vertexarray[indexarray[j]]; + RAS_TexVert& v2 = vertexarray[indexarray[j+1]]; + RAS_TexVert& v3 = vertexarray[indexarray[j+2]]; + RAS_TexVert *v4 = NULL; + + const float *co1 = v1.getLocalXYZ(); + const float *co2 = v2.getLocalXYZ(); + const float *co3 = v3.getLocalXYZ(); + const float *co4 = NULL; + /* compute face normal */ - mv1 = MT_Point3(v1.getLocalXYZ()); - mv2 = MT_Point3(v2.getLocalXYZ()); - mv3 = MT_Point3(v3.getLocalXYZ()); + float fnor[3], n1[3], n2[3]; if(nvert == 4) { - int i4 = indexarray[j+3]; - RAS_TexVert& v4 = vertexarray[i4]; - mv4 = MT_Point3(v4.getLocalXYZ()); + v4 = &vertexarray[indexarray[j+3]]; + co4 = v4->getLocalXYZ(); + + n1[0]= co1[0]-co3[0]; + n1[1]= co1[1]-co3[1]; + n1[2]= co1[2]-co3[2]; - fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))); //.safe_normalized(); + n2[0]= co2[0]-co4[0]; + n2[1]= co2[1]-co4[1]; + n2[2]= co2[2]-co4[2]; } - else - fnor = ((mv2-mv1).cross(mv3-mv2)); //.safe_normalized(); + else { + n1[0]= co1[0]-co2[0]; + n2[0]= co2[0]-co3[0]; + n1[1]= co1[1]-co2[1]; + + n2[1]= co2[1]-co3[1]; + n1[2]= co1[2]-co2[2]; + n2[2]= co2[2]-co3[2]; + } + + fnor[0]= n1[1]*n2[2] - n1[2]*n2[1]; + fnor[1]= n1[2]*n2[0] - n1[0]*n2[2]; + fnor[2]= n1[0]*n2[1] - n1[1]*n2[0]; /* add to vertices for smooth normals */ - m_transnors[mvarray[diarray[i1]]] += fnor; - m_transnors[mvarray[diarray[i2]]] += fnor; - m_transnors[mvarray[diarray[i3]]] += fnor; + float *vn1 = m_transnors[v1.getOrigIndex()]; + float *vn2 = m_transnors[v2.getOrigIndex()]; + float *vn3 = m_transnors[v3.getOrigIndex()]; + + vn1[0] += fnor[0]; vn1[1] += fnor[1]; vn1[2] += fnor[2]; + vn2[0] += fnor[0]; vn2[1] += fnor[1]; vn2[2] += fnor[2]; + vn3[0] += fnor[0]; vn3[1] += fnor[1]; vn3[2] += fnor[2]; + + if(v4) { + float *vn4 = m_transnors[v4->getOrigIndex()]; + vn4[0] += fnor[0]; vn4[1] += fnor[1]; vn4[2] += fnor[2]; + } /* in case of flat - just assign, the vertices are split */ if(v1.getFlag() & TV_CALCFACENORMAL) { v1.SetNormal(fnor); v2.SetNormal(fnor); v3.SetNormal(fnor); - } - - if(nvert == 4) { - int i4 = indexarray[j+3]; - RAS_TexVert& v4 = vertexarray[i4]; - - /* same as above */ - m_transnors[mvarray[diarray[i4]]] += fnor; - - if(v4.getFlag() & TV_CALCFACENORMAL) - v4.SetNormal(fnor); + if(v4) + v4->SetNormal(fnor); } } } @@ -179,18 +190,17 @@ void BL_MeshDeformer::RecalcNormals() mit != m_pMeshObject->GetLastMaterial(); ++ mit) { RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); - vertexarrays = m_pMeshObject->GetVertexCache(mat); - diarrays = m_pMeshObject->GetDIndexCache(mat); - mvarrays = m_pMeshObject->GetMVertCache(mat); + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); for (i=0; i<vertexarrays.size(); i++) { KX_VertexArray& vertexarray = (*vertexarrays[i]); - const KX_IndexArray& mvarray = (*mvarrays[i]); - const KX_IndexArray& diarray = (*diarrays[i]); - for(j=0; j<vertexarray.size(); j++) - if(!(vertexarray[j].getFlag() & TV_CALCFACENORMAL)) - vertexarray[j].SetNormal(m_transnors[mvarray[diarray[j]]]); //.safe_normalized() + for(j=0; j<vertexarray.size(); j++) { + RAS_TexVert& v = vertexarray[j]; + + if(!(v.getFlag() & TV_CALCFACENORMAL)) + v.SetNormal(m_transnors[v.getOrigIndex()]); //.safe_normalized() + } } } } @@ -204,8 +214,8 @@ void BL_MeshDeformer::VerifyStorage() if (m_transnors) delete [] m_transnors; - m_transverts=new float[(sizeof(*m_transverts)*m_bmesh->totvert)][3]; - m_transnors=new MT_Vector3[m_bmesh->totvert]; + m_transverts=new float[m_bmesh->totvert][3]; + m_transnors=new float[m_bmesh->totvert][3]; m_tvtot = m_bmesh->totvert; } } diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 8d8b56b1eed..e9f7f0b192f 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -40,19 +40,25 @@ #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning #endif //WIN32 +class BL_DeformableGameObject; + class BL_MeshDeformer : public RAS_Deformer { public: void VerifyStorage(); void RecalcNormals(); virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){}; - BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj ): + BL_MeshDeformer(BL_DeformableGameObject *gameobj, + struct Object* obj, + class BL_SkinMeshObject *meshobj ): m_pMeshObject(meshobj), m_bmesh((struct Mesh*)(obj->data)), m_transverts(0), m_transnors(0), m_objMesh(obj), - m_tvtot(0) + m_tvtot(0), + m_gameobj(gameobj), + m_lastDeformUpdate(-1) {}; virtual ~BL_MeshDeformer(); virtual void SetSimulatedTime(double time){}; @@ -68,10 +74,12 @@ protected: // this is so m_transverts doesn't need to be converted // before deformation float (*m_transverts)[3]; - MT_Vector3* m_transnors; + float (*m_transnors)[3]; struct Object* m_objMesh; // -- int m_tvtot; + BL_DeformableGameObject* m_gameobj; + double m_lastDeformUpdate; }; #endif diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index 9f8361dbaca..5f0188e3a42 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -58,9 +58,8 @@ public: Object *bmeshobj, BL_SkinMeshObject *mesh) : - BL_SkinDeformer(bmeshobj, mesh), - m_lastShapeUpdate(-1), - m_gameobj(gameobj) + BL_SkinDeformer(gameobj,bmeshobj, mesh), + m_lastShapeUpdate(-1) { }; @@ -72,9 +71,8 @@ public: bool release_object, BL_ArmatureObject* arma = NULL) : - BL_SkinDeformer(bmeshobj_old, bmeshobj_new, mesh, release_object, arma), - m_lastShapeUpdate(-1), - m_gameobj(gameobj) + BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, arma), + m_lastShapeUpdate(-1) { }; @@ -94,7 +92,6 @@ public: protected: vector<IpoCurve*> m_shapeDrivers; double m_lastShapeUpdate; - BL_DeformableGameObject* m_gameobj; }; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index dd7119b1031..d3442fe5298 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -57,11 +57,12 @@ extern "C"{ #define __NLA_DEFNORMALS //#undef __NLA_DEFNORMALS -BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj, +BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj, class BL_SkinMeshObject *mesh, BL_ArmatureObject* arma) : // - BL_MeshDeformer(bmeshobj, mesh), + BL_MeshDeformer(gameobj, bmeshobj, mesh), m_armobj(arma), m_lastArmaUpdate(-1), m_defbase(&bmeshobj->defbase), @@ -71,12 +72,13 @@ BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj, }; BL_SkinDeformer::BL_SkinDeformer( + BL_DeformableGameObject *gameobj, struct Object *bmeshobj_old, // Blender object that owns the new mesh struct Object *bmeshobj_new, // Blender object that owns the original mesh class BL_SkinMeshObject *mesh, bool release_object, BL_ArmatureObject* arma) : - BL_MeshDeformer(bmeshobj_old, mesh), + BL_MeshDeformer(gameobj, bmeshobj_old, mesh), m_armobj(arma), m_lastArmaUpdate(-1), m_defbase(&bmeshobj_old->defbase), @@ -96,35 +98,32 @@ BL_SkinDeformer::~BL_SkinDeformer() m_armobj->Release(); } -bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) +bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *) { - size_t i, j, index; - vecVertexArray array; - vecIndexArrays mvarray; - vecMDVertArray dvarray; - vecIndexArrays diarray; - - RAS_TexVert *tv; - MT_Point3 pt; -// float co[3]; - - Update(); - - array = m_pMeshObject->GetVertexCache(mat); - mvarray = m_pMeshObject->GetMVertCache(mat); - diarray = m_pMeshObject->GetDIndexCache(mat); - // For each array - for (i=0; i<array.size(); i++) { - // For each vertex - for (j=0; j<array[i]->size(); j++) { - - tv = &((*array[i])[j]); - - index = ((*diarray[i])[j]); - - // Copy the untransformed data from the original mvert - // Set the data - tv->SetXYZ(m_transverts[((*mvarray[i])[index])]); + size_t i, j; + + if (!Update()) + // no need to update the cache + return false; + + // Update all materials at once, so we can do the above update test + // without ending up with some materials not updated + for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); + mit != m_pMeshObject->GetLastMaterial(); ++ mit) { + RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); + + // For each array + for (i=0; i<vertexarrays.size(); i++) { + KX_VertexArray& vertexarray = (*vertexarrays[i]); + + // For each vertex + // copy the untransformed data from the original mvert + for (j=0; j<vertexarray.size(); j++) { + RAS_TexVert& v = vertexarray[j]; + v.SetXYZ(m_transverts[v.getOrigIndex()]); + } } } diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index c5568c049cb..f35db8273c4 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -63,12 +63,14 @@ public: } void SetArmature (class BL_ArmatureObject *armobj); - BL_SkinDeformer(struct Object *bmeshobj, + BL_SkinDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj, class BL_SkinMeshObject *mesh, BL_ArmatureObject* arma = NULL); /* this second constructor is needed for making a mesh deformable on the fly. */ - BL_SkinDeformer(struct Object *bmeshobj_old, + BL_SkinDeformer(BL_DeformableGameObject *gameobj, + struct Object *bmeshobj_old, struct Object *bmeshobj_new, class BL_SkinMeshObject *mesh, bool release_object, diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp index 49492923c7c..fa215df1e1c 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.cpp +++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp @@ -43,90 +43,6 @@ #include "KX_GameObject.h" #include "RAS_BucketManager.h" -void BL_SkinMeshObject::AddPolygon(RAS_Polygon* poly) -{ - /* We're overriding this so that we can eventually associate faces with verts somehow */ - - // For vertIndex in poly: - // find the appropriate normal - - RAS_MeshObject::AddPolygon(poly); -} - -int BL_SkinMeshObject::FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat) -{ - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - int numvert = ao->m_MvertArrayCache1[vtxarray]->size(); - - /* Check to see if this has already been pushed */ - for (vector<BL_MDVertMap>::iterator it = m_mvert_to_dvert_mapping[mv].begin(); - it != m_mvert_to_dvert_mapping[mv].end(); - it++) - { - if(it->mat == mat) - return it->index; - } - - ao->m_MvertArrayCache1[vtxarray]->push_back(mv); - ao->m_DvertArrayCache1[vtxarray]->push_back(dv); - - BL_MDVertMap mdmap; - mdmap.mat = mat; - mdmap.index = numvert; - m_mvert_to_dvert_mapping[mv].push_back(mdmap); - - return numvert; -}; - -int BL_SkinMeshObject::FindVertexArray(int numverts,RAS_IPolyMaterial* polymat) -{ - int array=-1; - - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(polymat); - - - for (size_t i=0;i<ao->m_VertexArrayCache1.size();i++) - { - if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES) - { - if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES)) - { - array = i; - ao->m_TriangleArrayCount[array]+=numverts-2; - break; - } - } - } - - - if (array == -1) - { - array = ao->m_VertexArrayCache1.size(); - - vector<RAS_TexVert>* va = new vector<RAS_TexVert>; - ao->m_VertexArrayCache1.push_back(va); - - KX_IndexArray *ia = new KX_IndexArray(); - ao->m_IndexArrayCache1.push_back(ia); - - KX_IndexArray *bva = new KX_IndexArray(); - ao->m_MvertArrayCache1.push_back(bva); - - BL_DeformVertArray *dva = new BL_DeformVertArray(); - ao->m_DvertArrayCache1.push_back(dva); - - KX_IndexArray *da = new KX_IndexArray(); - ao->m_DIndexArrayCache1.push_back(da); - - ao->m_TriangleArrayCount.push_back(numverts-2); - - } - - - return array; -} - - //void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,RAS_BucketManager* bucketmgr) void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec) { diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h index cc2b8de600e..c21fb64204b 100644 --- a/source/gameengine/Converter/BL_SkinMeshObject.h +++ b/source/gameengine/Converter/BL_SkinMeshObject.h @@ -44,78 +44,19 @@ #include "DNA_key_types.h" #include "DNA_meshdata_types.h" -typedef vector<struct MVert*> BL_MVertArray; -typedef vector<struct MDeformVert*> BL_DeformVertArray; -typedef vector<class BL_TexVert> BL_VertexArray; - - -typedef vector<vector<struct MDeformVert*>*> vecMDVertArray; -typedef vector<vector<class BL_TexVert>*> vecBVertexArray; - -class BL_SkinArrayOptimizer : public KX_ArrayOptimizer -{ -public: - BL_SkinArrayOptimizer(int index) - :KX_ArrayOptimizer (index) {}; - virtual ~BL_SkinArrayOptimizer(){ - - for (vector<KX_IndexArray*>::iterator itv = m_MvertArrayCache1.begin(); - !(itv == m_MvertArrayCache1.end());itv++) - { - delete (*itv); - } - for (vector<BL_DeformVertArray*>::iterator itd = m_DvertArrayCache1.begin(); - !(itd == m_DvertArrayCache1.end());itd++) - { - delete (*itd); - } - for (vector<KX_IndexArray*>::iterator iti = m_DIndexArrayCache1.begin(); - !(iti == m_DIndexArrayCache1.end());iti++) - { - delete (*iti); - } - - m_MvertArrayCache1.clear(); - m_DvertArrayCache1.clear(); - m_DIndexArrayCache1.clear(); - }; - - vector<KX_IndexArray*> m_MvertArrayCache1; - vector<BL_DeformVertArray*> m_DvertArrayCache1; - vector<KX_IndexArray*> m_DIndexArrayCache1; - -}; - class BL_SkinMeshObject : public RAS_MeshObject { // enum { BUCKET_MAX_INDICES = 16384};//2048};//8192}; // enum { BUCKET_MAX_TRIANGLES = 4096}; - KX_ArrayOptimizer* GetArrayOptimizer(RAS_IPolyMaterial* polymat) - { - KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]); - if (aop) - return *aop; - int numelements = m_matVertexArrayS.size(); - m_sortedMaterials.push_back(polymat); - - BL_SkinArrayOptimizer* ao = new BL_SkinArrayOptimizer(numelements); - m_matVertexArrayS.insert(*polymat,ao); - return ao; - } - protected: vector<int> m_cacheWeightIndex; public: - struct BL_MDVertMap { RAS_IPolyMaterial *mat; int index; }; - vector<vector<BL_MDVertMap> > m_mvert_to_dvert_mapping; - void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec); // void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr); - int FindVertexArray(int numverts,RAS_IPolyMaterial* polymat); BL_SkinMeshObject(Mesh* mesh, int lightlayer) : RAS_MeshObject (mesh, lightlayer) { m_class = 1; @@ -144,42 +85,7 @@ public: } } }; - - const vecIndexArrays& GetDIndexCache (RAS_IPolyMaterial* mat) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - return ao->m_DIndexArrayCache1; - } - const vecMDVertArray& GetDVertCache (RAS_IPolyMaterial* mat) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - return ao->m_DvertArrayCache1; - } - const vecIndexArrays& GetMVertCache (RAS_IPolyMaterial* mat) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); - return ao->m_MvertArrayCache1; - } - void AddPolygon(RAS_Polygon* poly); - int FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat); - int FindOrAddVertex(int vtxarray,const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, - const MT_Vector4& tangent, - const unsigned int rgbacolor, - const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat, int origindex) - { - BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat); - int numverts = ao->m_VertexArrayCache1[vtxarray]->size(); - int index = RAS_MeshObject::FindOrAddVertex(vtxarray, xyz, uv, uv2, tangent, rgbacolor, normal, flat, mat, origindex); - - /* this means a new vertex was added, so we add the defnr too */ - if(index == numverts) - ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr); - - return index; - } // for shape keys, void CheckWeightCache(struct Object* obj); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 6e05ea31fe8..1f87e9d9ac7 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -193,6 +193,7 @@ void BL_ConvertActuators(char* maggiename, actact->type, // + 1, because Blender starts to count at zero, actact->blendin, actact->priority, + actact->end_reset, actact->stridelength // Ketsji at 1, because zero is reserved for "NoDef" ); @@ -233,7 +234,8 @@ void BL_ConvertActuators(char* maggiename, STR_String propname = ( ipoact->name ? ipoact->name : ""); // first bit? bool ipo_as_force = (ipoact->flag & ACT_IPOFORCE); - bool force_local = (ipoact->flag & ACT_IPOFORCE_LOCAL); + bool local = (ipoact->flag & ACT_IPOLOCAL); + bool ipo_add = (ipoact->flag & ACT_IPOADD); KX_IpoActuator* tmpbaseact = new KX_IpoActuator( gameobj, @@ -244,8 +246,8 @@ void BL_ConvertActuators(char* maggiename, ipoact->type + 1, // + 1, because Blender starts to count at zero, // Ketsji at 1, because zero is reserved for "NoDef" ipo_as_force, - force_local - ); + ipo_add, + local); baseact = tmpbaseact; break; } diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 04cc119efee..2bcb604dd23 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -76,18 +76,36 @@ static inline void Py_Fatal(char *M) { virtual PyTypeObject *GetType(void) {return &Type;}; \ 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 = Py_FindMethod(Methods, this, const_cast<char*>(attr.ReadPtr())); \ - if (rvalue == NULL) \ - { \ + 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); \ + } \ + } \ + } else { \ + rvalue = Py_FindMethod(Methods, this, const_cast<char*>(attr.ReadPtr())); \ + if (rvalue == NULL) { \ PyErr_Clear(); \ - return Parent::_getattr(attr); \ + rvalue = Parent::_getattr(attr); \ } \ - else \ - return rvalue + } \ + return rvalue; \ + /** * These macros are helpfull when embedding Python routines. The second diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp index 9645bfbed4a..e1c8ef87dd1 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp @@ -111,7 +111,7 @@ void SCA_ActuatorSensor::Update() { if (m_actuator) { - m_midresult = m_actuator->IsActive(); + m_midresult = m_actuator->IsActive() && !m_actuator->IsNegativeEvent(); } } diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 774b27c5ad4..7ffb21b5490 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -87,6 +87,7 @@ public: bool IsNegativeEvent() const; virtual ~SCA_IActuator(); + void ClrLink() { m_links=0; } void IncLink() { m_links++; } void DecLink(); bool IsNoLink() const { return !m_links; } diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index 27e7d5faada..c5bb4a41552 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_state(0), CValue(T) +SCA_IObject::SCA_IObject(PyTypeObject* T): m_initState(0), m_state(0), CValue(T) { m_suspended = false; } @@ -164,7 +164,9 @@ void SCA_IObject::ReParentLogic() { SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica(); newactuator->ReParent(this); + // actuators are initially not connected to any controller newactuator->SetActive(false); + newactuator->ClrLink(); oldactuators[act++] = newactuator; } @@ -175,6 +177,7 @@ void SCA_IObject::ReParentLogic() { SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica(); newcontroller->ReParent(this); + newcontroller->SetActive(false); oldcontrollers[con++]=newcontroller; } @@ -186,6 +189,9 @@ void SCA_IObject::ReParentLogic() { SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica(); newsensor->ReParent(this); + newsensor->SetActive(false); + // sensors are initially not connected to any controller + newsensor->ClrLink(); oldsensors[sen++] = newsensor; } diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 07b4310a91e..38a7ed29dca 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -69,6 +69,11 @@ protected: bool m_suspended; /** + * init state of object (used when object is created) + */ + unsigned int m_initState; + + /** * current state = bit mask of state that are active */ unsigned int m_state; @@ -118,6 +123,16 @@ public: void Resume(void); /** + * Set init state + */ + void SetInitState(unsigned int initState) { m_initState = initState; } + + /** + * initialize the state when object is created + */ + void ResetState(void) { SetState(m_initState); } + + /** * Set the object state */ void SetState(unsigned int state); diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index f2ed6a803c2..4ce49e71507 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -126,6 +126,8 @@ public: /** Resume sensing. */ void Resume(); + void ClrLink() + { m_links = 0; } void IncLink() { m_links++; } void DecLink(); diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 06e012123b1..dd45d522b9f 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -1,9 +1,11 @@ #include "DNA_customdata_types.h" +#include "DNA_material_types.h" #include "BL_BlenderShader.h" +#include "BL_Material.h" -#if 0 +#ifdef BLENDER_GLSL #include "GPU_extensions.h" #include "GPU_material.h" #endif @@ -13,29 +15,32 @@ const bool BL_BlenderShader::Ok()const { -#if 0 +#ifdef BLENDER_GLSL return (mGPUMat != 0); +#else + return 0; #endif - - return false; } -BL_BlenderShader::BL_BlenderShader(struct Material *ma) +BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer) : -#if 0 +#ifdef BLENDER_GLSL mGPUMat(0), #endif - mBound(false) + mBound(false), + mLightLayer(lightlayer) { -#if 0 - if(ma) - mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_DERIVEDMESH); +#ifdef BLENDER_GLSL + if(ma) { + GPU_material_from_blender(ma); + mGPUMat = ma->gpumaterial; + } #endif } BL_BlenderShader::~BL_BlenderShader() { -#if 0 +#ifdef BLENDER_GLSL if(mGPUMat) { GPU_material_unbind(mGPUMat); mGPUMat = 0; @@ -43,16 +48,12 @@ BL_BlenderShader::~BL_BlenderShader() #endif } -void BL_BlenderShader::ApplyShader() -{ -} - void BL_BlenderShader::SetProg(bool enable) { -#if 0 +#ifdef BLENDER_GLSL if(mGPUMat) { if(enable) { - GPU_material_bind(mGPUMat); + GPU_material_bind(mGPUMat, mLightLayer); mBound = true; } else { @@ -65,7 +66,7 @@ void BL_BlenderShader::SetProg(bool enable) int BL_BlenderShader::GetAttribNum() { -#if 0 +#ifdef BLENDER_GLSL GPUVertexAttribs attribs; int i, enabled = 0; @@ -82,17 +83,19 @@ int BL_BlenderShader::GetAttribNum() enabled = BL_MAX_ATTRIB; return enabled; -#endif - +#else return 0; +#endif } -void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) +void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat) { -#if 0 +#ifdef BLENDER_GLSL GPUVertexAttribs attribs; int i, attrib_num; + ras->SetAttribNum(0); + if(!mGPUMat) return; @@ -109,14 +112,24 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) if(attribs.layer[i].glindex > attrib_num) continue; - if(attribs.layer[i].type == CD_MTFACE) - ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + if(attribs.layer[i].type == CD_MTFACE) { + if(!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + else if(!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex); + else + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); + } else if(attribs.layer[i].type == CD_TANGENT) ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_ORCO) ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex); else if(attribs.layer[i].type == CD_NORMAL) ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex); + else if(attribs.layer[i].type == CD_MCOL) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex); + else + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex); } ras->EnableTextures(true); @@ -128,8 +141,8 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras) void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) { -#if 0 - float obmat[4][4], viewmat[4][4]; +#ifdef BLENDER_GLSL + float obmat[4][4], viewmat[4][4], viewinvmat[4][4]; if(!mGPUMat || !mBound) return; @@ -142,7 +155,20 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty ) model.getValue((float*)obmat); view.getValue((float*)viewmat); - GPU_material_bind_uniforms(mGPUMat, obmat, viewmat); + view.invert(); + view.getValue((float*)viewinvmat); + + GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat); +#endif +} + +bool BL_BlenderShader::Equals(BL_BlenderShader *blshader) +{ +#ifdef BLENDER_GLSL + /* to avoid unneeded state switches */ + return (blshader && mGPUMat == blshader->mGPUMat && mLightLayer == blshader->mLightLayer); +#else + return true; #endif } diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index 4cab0e644c3..b758d1a9cba 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -2,7 +2,7 @@ #ifndef __BL_GPUSHADER_H__ #define __BL_GPUSHADER_H__ -#if 0 +#ifdef BLENDER_GLSL #include "GPU_material.h" #endif @@ -12,7 +12,10 @@ #include "MT_Tuple3.h" #include "MT_Tuple4.h" +#include "RAS_IPolygonMaterial.h" + struct Material; +class BL_Material; #define BL_MAX_ATTRIB 16 @@ -23,22 +26,24 @@ struct Material; class BL_BlenderShader { private: -#if 0 +#ifdef BLENDER_GLSL GPUMaterial *mGPUMat; #endif bool mBound; + int mLightLayer; public: - BL_BlenderShader(struct Material *ma); + BL_BlenderShader(struct Material *ma, int lightlayer); virtual ~BL_BlenderShader(); const bool Ok()const; void SetProg(bool enable); - void ApplyShader(); - void SetTexCoords(class RAS_IRasterizer* ras); int GetAttribNum(); + void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat); void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty); + + bool Equals(BL_BlenderShader *blshader); }; #endif//__BL_GPUSHADER_H__ diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index f5312ccd023..7e3d6984f19 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -105,7 +105,8 @@ void BL_Material::GetConversionRGB(unsigned int *nrgb) { *nrgb = rgb[3]; } -void BL_Material::SetConversionUV(MT_Point2 *nuv) { +void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) { + uvName = name; uv[0] = *nuv++; uv[1] = *nuv++; uv[2] = *nuv++; @@ -118,7 +119,8 @@ void BL_Material::GetConversionUV(MT_Point2 *nuv){ *nuv++ = uv[2]; *nuv = uv[3]; } -void BL_Material::SetConversionUV2(MT_Point2 *nuv) { +void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) { + uv2Name = name; uv2[0] = *nuv++; uv2[1] = *nuv++; uv2[2] = *nuv++; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index ddb6662830a..568f7e171de 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -83,13 +83,16 @@ public: MT_Point2 uv[4]; MT_Point2 uv2[4]; + STR_String uvName; + STR_String uv2Name; + void SetConversionRGB(unsigned int *rgb); void GetConversionRGB(unsigned int *rgb); - void SetConversionUV(MT_Point2 *uv); + void SetConversionUV(const STR_String& name, MT_Point2 *uv); void GetConversionUV(MT_Point2 *uv); - void SetConversionUV2(MT_Point2 *uv); + void SetConversionUV2(const STR_String& name, MT_Point2 *uv); void GetConversionUV2(MT_Point2 *uv); void SetSharedMaterial(bool v); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 02b1ffd432a..0f445a9f32e 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -38,6 +38,8 @@ extern "C" { // ------------------------------------ #define spit(x) std::cout << x << std::endl; +BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL; + //static PyObject *gTextureDict = 0; KX_BlenderMaterial::KX_BlenderMaterial( @@ -126,32 +128,31 @@ void KX_BlenderMaterial::OnConstruction() // when material are reused between objects return; - if(mMaterial->glslmat) { + if(mMaterial->glslmat) SetBlenderGLSLShader(); - } - else { - // for each unique material... - int i; - for(i=0; i<mMaterial->num_enabled; i++) { - if( mMaterial->mapping[i].mapping & USEENV ) { - if(!GLEW_ARB_texture_cube_map) { - spit("CubeMap textures not supported"); - continue; - } - if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) + + // for each unique material... + int i; + for(i=0; i<mMaterial->num_enabled; i++) { + if( mMaterial->mapping[i].mapping & USEENV ) { + if(!GLEW_ARB_texture_cube_map) { + spit("CubeMap textures not supported"); + continue; + } + if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) + spit("unable to initialize image("<<i<<") in "<< + mMaterial->matname<< ", image will not be available"); + } + + else { + if( mMaterial->img[i] ) { + if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) spit("unable to initialize image("<<i<<") in "<< - mMaterial->matname<< ", image will not be available"); - } - - else { - if( mMaterial->img[i] ) { - if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) - spit("unable to initialize image("<<i<<") in "<< - mMaterial->matname<< ", image will not be available"); - } + mMaterial->matname<< ", image will not be available"); } } } + mBlendFunc[0] =0; mBlendFunc[1] =0; mConstructed = true; @@ -168,7 +169,11 @@ void KX_BlenderMaterial::OnExit() } if( mBlenderShader ) { - mBlenderShader->SetProg(false); + if(mBlenderShader == mLastBlenderShader) { + mBlenderShader->SetProg(false); + mLastBlenderShader = NULL; + } + delete mBlenderShader; mBlenderShader = 0; } @@ -225,14 +230,23 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras { if( !enable || !mBlenderShader->Ok() ) { // frame cleanup. - mBlenderShader->SetProg(false); + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader= NULL; + } BL_Texture::DisableAllTextures(); return; } - BL_Texture::DisableAllTextures(); - mBlenderShader->SetProg(true); - mBlenderShader->ApplyShader(); + if(!mBlenderShader->Equals(mLastBlenderShader)) { + BL_Texture::DisableAllTextures(); + + if(mLastBlenderShader) + mLastBlenderShader->SetProg(false); + + mBlenderShader->SetProg(true); + mLastBlenderShader= mBlenderShader; + } } void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) @@ -298,7 +312,12 @@ KX_BlenderMaterial::ActivatShaders( // reset... if(tmp->mMaterial->IsShared()) cachingInfo =0; - + + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader= NULL; + } + if (GetCachingInfo() != cachingInfo) { if (!cachingInfo) @@ -372,7 +391,7 @@ KX_BlenderMaterial::ActivateBlenderShaders( } ActivatGLMaterials(rasty); - mBlenderShader->SetTexCoords(rasty); + mBlenderShader->SetAttribs(rasty, mMaterial); } void @@ -382,6 +401,12 @@ KX_BlenderMaterial::ActivateMat( )const { KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this); + + if(mLastBlenderShader) { + mLastBlenderShader->SetProg(false); + mLastBlenderShader= NULL; + } + if (GetCachingInfo() != cachingInfo) { if (!cachingInfo) tmp->setTexData( false,rasty ); @@ -460,17 +485,29 @@ KX_BlenderMaterial::Activate( return dopass; } +bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const +{ + if(!RAS_IPolyMaterial::UsesLighting(rasty)) + return false; + + if(mShader && mShader->Ok()); + else if(mBlenderShader && mBlenderShader->Ok()) + return false; + + return true; +} + void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const { if(mShader && GLEW_ARB_shader_objects) mShader->Update(ms, rasty); - if(mBlenderShader && GLEW_ARB_shader_objects) + else if(mBlenderShader && GLEW_ARB_shader_objects) mBlenderShader->Update(ms, rasty); } void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const { - if(!mBlenderShader) { + if(mShader || !mBlenderShader) { rasty->SetSpecularity( mMaterial->speccolor[0]*mMaterial->spec_f, mMaterial->speccolor[1]*mMaterial->spec_f, @@ -506,6 +543,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const ras->SetAttribNum(0); if(mShader && GLEW_ARB_shader_objects) { if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) { + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, 0); ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1); ras->SetAttribNum(2); } @@ -793,7 +831,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") void KX_BlenderMaterial::SetBlenderGLSLShader(void) { if(!mBlenderShader) - mBlenderShader = new BL_BlenderShader(mMaterial->material); + mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer); if(!mBlenderShader->Ok()) { delete mBlenderShader; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 62e96b71937..bf6d2095e7c 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -94,6 +94,7 @@ private: BL_Material* mMaterial; BL_Shader* mShader; BL_BlenderShader* mBlenderShader; + static BL_BlenderShader *mLastBlenderShader; KX_Scene* mScene; BL_Texture mTextures[MAXTEX]; // texture array bool mUserDefBlend; @@ -106,6 +107,7 @@ private: void ActivatGLMaterials( RAS_IRasterizer* rasty )const; void ActivateTexGen( RAS_IRasterizer *ras ) const; + bool UsesLighting(RAS_IRasterizer *rasty) const; // message centers void setTexData( bool enable,RAS_IRasterizer *ras); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index bde5e2cd0a2..2ac4f909077 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -405,34 +405,25 @@ void KX_GameObject::ResetDebugColor() SetDebugColor(0xff000000); } +void KX_GameObject::InitIPO(bool ipo_as_force, + bool ipo_add, + bool ipo_local) +{ + SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin(); + while (it != GetSGNode()->GetSGControllerList().end()) { + (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true); + (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force); + (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, ipo_add); + (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, ipo_local); + it++; + } +} void KX_GameObject::UpdateIPO(float curframetime, - bool recurse, - bool ipo_as_force, - bool force_local) + bool recurse) { - - // The ipo-actuator needs a sumo reference... this is retrieved (unfortunately) - // by the iposgcontr itself... -// ipocontr->SetSumoReference(gameobj->GetSumoScene(), -// gameobj->GetSumoObject()); - - - // The ipo has to be treated as a force, and not a displacement! - // For this case, we send some settings to the controller. This - // may need some caching... - if (ipo_as_force) { - SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin(); - - while (it != GetSGNode()->GetSGControllerList().end()) { - (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force); - (*it)->SetOption(SG_Controller::SG_CONTR_IPO_FORCES_ACT_LOCAL, force_local); - it++; - } - } - - // The rest is the 'normal' update procedure. + // just the 'normal' update procedure. GetSGNode()->SetSimulatedTime(curframetime,recurse); GetSGNode()->UpdateWorldData(curframetime); UpdateTransform(); @@ -581,7 +572,7 @@ void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec) m_objectColor = rgbavec; } -void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) +void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) { MT_Matrix3x3 orimat; MT_Vector3 vect,ori,z,x,y; @@ -594,6 +585,11 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) cout << "alignAxisToVect() Error: Null vector!\n"; return; } + + if (fac<=0.0) { + return; + } + // normalize vect /= len; orimat = GetSGNode()->GetWorldOrientation(); @@ -603,7 +599,14 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) ori = MT_Vector3(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! - x = vect; + if (fac == 1.0) { + x = vect; + } else { + x = (vect * fac) + ((orimat * MT_Vector3(1.0, 0.0, 0.0)) * (1-fac)); + len = x.length(); + if (MT_fuzzyZero(len)) x = vect; + else x /= len; + } y = ori.cross(x); z = x.cross(y); break; @@ -611,7 +614,14 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) ori = MT_Vector3(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]); - y = vect; + if (fac == 1.0) { + y = vect; + } else { + y = (vect * fac) + ((orimat * MT_Vector3(0.0, 1.0, 0.0)) * (1-fac)); + len = y.length(); + if (MT_fuzzyZero(len)) y = vect; + else y /= len; + } z = ori.cross(y); x = y.cross(z); break; @@ -619,7 +629,14 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis) ori = MT_Vector3(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]); - z = vect; + if (fac == 1.0) { + z = vect; + } else { + z = (vect * fac) + ((orimat * MT_Vector3(0.0, 0.0, 1.0)) * (1-fac)); + len = z.length(); + if (MT_fuzzyZero(len)) z = vect; + else z /= len; + } x = ori.cross(z); y = z.cross(x); break; @@ -1289,7 +1306,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, return meshproxy; } } - return NULL; + Py_RETURN_NONE; } @@ -1395,13 +1412,14 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, { PyObject* pyvect; int axis = 2; //z axis is the default + float fac = 1.0; - if (PyArg_ParseTuple(args,"O|i",&pyvect,&axis)) + if (PyArg_ParseTuple(args,"O|if",&pyvect,&axis, &fac)) { MT_Vector3 vect; if (PyVecTo(pyvect, vect)) { - AlignAxisToVect(vect,axis); + AlignAxisToVect(vect,axis,fac); Py_RETURN_NONE; } } @@ -1590,14 +1608,18 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, other = static_cast<KX_GameObject*>(pyfrom); fromPoint = other->NodeGetWorldPosition(); } - - if (dist != 0.0f) - { + + if (dist != 0.0f) { MT_Vector3 toDir = toPoint-fromPoint; + if (MT_fuzzyZero(toDir.length2())) { + return Py_BuildValue("OOO", Py_None, Py_None, Py_None); + } toDir.normalize(); toPoint = fromPoint + (dist) * toDir; + } else if (MT_fuzzyZero((toPoint-fromPoint).length2())) { + return Py_BuildValue("OOO", Py_None, Py_None, Py_None); } - + MT_Point3 resultPoint; MT_Vector3 resultNormal; PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment(); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 5e44a36515d..ddbf863aa1a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -278,7 +278,8 @@ public: void AlignAxisToVect( const MT_Vector3& vect, - int axis = 2 + int axis = 2, + float fac = 1.0 ); /** @@ -490,14 +491,22 @@ public: ); /** + * Function to set IPO option at start of IPO + */ + void + InitIPO( + bool ipo_as_force, + bool ipo_add, + bool ipo_local + ); + + /** * Odd function to update an ipo. ??? */ void UpdateIPO( float curframetime, - bool recurse, - bool ipo_as_force, - bool force_ipo_local + bool recurse ); /** * Updates Material Ipo data diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 5303e9a9e85..d3aa924665e 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -55,7 +55,8 @@ typedef unsigned long uint_ptr; // start on another frame, the 1.0 should change. KX_IpoSGController::KX_IpoSGController() : m_ipo_as_force(false), - m_force_ipo_acts_local(false), + m_ipo_add(false), + m_ipo_local(false), m_modified(true), m_ipo_start_initialized(false), m_ipotime(1.0) @@ -75,8 +76,23 @@ void KX_IpoSGController::SetOption( m_ipo_as_force = (value != 0); m_modified = true; break; - case SG_CONTR_IPO_FORCES_ACT_LOCAL: - m_force_ipo_acts_local = (value != 0); + case SG_CONTR_IPO_IPO_ADD: + m_ipo_add = (value != 0); + m_modified = true; + break; + case SG_CONTR_IPO_RESET: + if (m_ipo_start_initialized && value) { + m_ipo_start_initialized = false; + m_modified = true; + } + break; + case SG_CONTR_IPO_LOCAL: + if (value/* && ((SG_Node*)m_pObject)->GetSGParent() == NULL*/) { + // only accept local Ipo if the object has no parent + m_ipo_local = true; + } else { + m_ipo_local = false; + } m_modified = true; break; default: @@ -129,15 +145,19 @@ bool KX_IpoSGController::Update(double currentTime) { if (m_game_object && ob) { - m_game_object->GetPhysicsController()->ApplyForce(m_force_ipo_acts_local ? + m_game_object->GetPhysicsController()->ApplyForce(m_ipo_local ? ob->GetWorldOrientation() * m_ipo_xform.GetPosition() : m_ipo_xform.GetPosition(), false); } } else { - //by default, leave object as it stands - MT_Point3 newPosition = ob->GetLocalPosition(); + // Local ipo should be defined with the object position at (0,0,0) + // Local transform is applied to the object based on initial position + MT_Point3 newPosition(0.0,0.0,0.0); + + if (!m_ipo_add) + newPosition = ob->GetLocalPosition(); //apply separate IPO channels if there is any data in them //Loc and dLoc act by themselves or are additive //LocX and dLocX @@ -145,23 +165,28 @@ bool KX_IpoSGController::Update(double currentTime) newPosition[0] = (m_ipo_channels_active[OB_DLOC_X] ? m_ipo_xform.GetPosition()[0] + m_ipo_xform.GetDeltaPosition()[0] : m_ipo_xform.GetPosition()[0]); } else if (m_ipo_channels_active[OB_DLOC_X] && m_ipo_start_initialized) { - newPosition[0] = (m_ipo_start_point[0] + m_ipo_xform.GetDeltaPosition()[0]); + newPosition[0] = (((!m_ipo_add)?m_ipo_start_point[0]:0.0) + m_ipo_xform.GetDeltaPosition()[0]); } //LocY and dLocY if (m_ipo_channels_active[OB_LOC_Y]) { newPosition[1] = (m_ipo_channels_active[OB_DLOC_Y] ? m_ipo_xform.GetPosition()[1] + m_ipo_xform.GetDeltaPosition()[1] : m_ipo_xform.GetPosition()[1]); } else if (m_ipo_channels_active[OB_DLOC_Y] && m_ipo_start_initialized) { - newPosition[1] = (m_ipo_start_point[1] + m_ipo_xform.GetDeltaPosition()[1]); + newPosition[1] = (((!m_ipo_add)?m_ipo_start_point[1]:0.0) + m_ipo_xform.GetDeltaPosition()[1]); } //LocZ and dLocZ if (m_ipo_channels_active[OB_LOC_Z]) { newPosition[2] = (m_ipo_channels_active[OB_DLOC_Z] ? m_ipo_xform.GetPosition()[2] + m_ipo_xform.GetDeltaPosition()[2] : m_ipo_xform.GetPosition()[2]); } else if (m_ipo_channels_active[OB_DLOC_Z] && m_ipo_start_initialized) { - newPosition[2] = (m_ipo_start_point[2] + m_ipo_xform.GetDeltaPosition()[2]); + newPosition[2] = (((!m_ipo_add)?m_ipo_start_point[2]:0.0) + m_ipo_xform.GetDeltaPosition()[2]); + } + if (m_ipo_add) { + if (m_ipo_local) + newPosition = m_ipo_start_point + m_ipo_start_scale*(m_ipo_start_orient*newPosition); + else + newPosition = m_ipo_start_point + newPosition; } - ob->SetLocalPosition(newPosition); } } @@ -170,21 +195,23 @@ bool KX_IpoSGController::Update(double currentTime) if (m_ipo_as_force) { if (m_game_object && ob) { - m_game_object->ApplyTorque(m_force_ipo_acts_local ? + m_game_object->ApplyTorque(m_ipo_local ? ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() : m_ipo_xform.GetEulerAngles(), false); } } else { - double yaw, pitch, roll; //final Euler angles + double yaw=0, pitch=0, roll=0; //final Euler angles double tempYaw=0, tempPitch=0, tempRoll=0; //temp holders - ob->GetLocalOrientation().getEuler(yaw, pitch, roll); + if (!m_ipo_add) + ob->GetLocalOrientation().getEuler(yaw, pitch, roll); //RotX and dRotX if (m_ipo_channels_active[OB_ROT_X]) { yaw = (m_ipo_channels_active[OB_DROT_X] ? (m_ipo_xform.GetEulerAngles()[0] + m_ipo_xform.GetDeltaEulerAngles()[0]) : m_ipo_xform.GetEulerAngles()[0] ); } else if (m_ipo_channels_active[OB_DROT_X] && m_ipo_start_initialized) { - m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll); + if (!m_ipo_add) + m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll); yaw = tempYaw + m_ipo_xform.GetDeltaEulerAngles()[0]; } @@ -193,7 +220,8 @@ bool KX_IpoSGController::Update(double currentTime) pitch = (m_ipo_channels_active[OB_DROT_Y] ? (m_ipo_xform.GetEulerAngles()[1] + m_ipo_xform.GetDeltaEulerAngles()[1]) : m_ipo_xform.GetEulerAngles()[1] ); } else if (m_ipo_channels_active[OB_DROT_Y] && m_ipo_start_initialized) { - m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll); + if (!m_ipo_add) + m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll); pitch = tempPitch + m_ipo_xform.GetDeltaEulerAngles()[1]; } @@ -202,23 +230,34 @@ bool KX_IpoSGController::Update(double currentTime) roll = (m_ipo_channels_active[OB_DROT_Z] ? (m_ipo_xform.GetEulerAngles()[2] + m_ipo_xform.GetDeltaEulerAngles()[2]) : m_ipo_xform.GetEulerAngles()[2] ); } else if (m_ipo_channels_active[OB_DROT_Z] && m_ipo_start_initialized) { - m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll); + if (!m_ipo_add) + m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll); roll = tempRoll + m_ipo_xform.GetDeltaEulerAngles()[2]; } - - ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll)); + if (m_ipo_add) { + MT_Matrix3x3 rotation(MT_Vector3(yaw, pitch, roll)); + if (m_ipo_local) + rotation = m_ipo_start_orient * rotation; + else + rotation = rotation * m_ipo_start_orient; + ob->SetLocalOrientation(rotation); + } else { + ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll)); + } } } //modifies scale? if (m_ipo_channels_active[OB_SIZE_X] || m_ipo_channels_active[OB_SIZE_Y] || m_ipo_channels_active[OB_SIZE_Z] || m_ipo_channels_active[OB_DSIZE_X] || m_ipo_channels_active[OB_DSIZE_Y] || m_ipo_channels_active[OB_DSIZE_Z]) { //default is no scale change - MT_Vector3 newScale = ob->GetLocalScale(); + MT_Vector3 newScale(1.0,1.0,1.0); + if (!m_ipo_add) + newScale = ob->GetLocalScale(); if (m_ipo_channels_active[OB_SIZE_X]) { newScale[0] = (m_ipo_channels_active[OB_DSIZE_X] ? (m_ipo_xform.GetScaling()[0] + m_ipo_xform.GetDeltaScaling()[0]) : m_ipo_xform.GetScaling()[0]); } else if (m_ipo_channels_active[OB_DSIZE_X] && m_ipo_start_initialized) { - newScale[0] = (m_ipo_xform.GetDeltaScaling()[0] + m_ipo_start_scale[0]); + newScale[0] = (m_ipo_xform.GetDeltaScaling()[0] + ((!m_ipo_add)?m_ipo_start_scale[0]:0.0)); } //RotY dRotY @@ -226,7 +265,7 @@ bool KX_IpoSGController::Update(double currentTime) newScale[1] = (m_ipo_channels_active[OB_DSIZE_Y] ? (m_ipo_xform.GetScaling()[1] + m_ipo_xform.GetDeltaScaling()[1]): m_ipo_xform.GetScaling()[1]); } else if (m_ipo_channels_active[OB_DSIZE_Y] && m_ipo_start_initialized) { - newScale[1] = (m_ipo_xform.GetDeltaScaling()[1] + m_ipo_start_scale[1]); + newScale[1] = (m_ipo_xform.GetDeltaScaling()[1] + ((!m_ipo_add)?m_ipo_start_scale[1]:0.0)); } //RotZ and dRotZ @@ -234,7 +273,11 @@ bool KX_IpoSGController::Update(double currentTime) newScale[2] = (m_ipo_channels_active[OB_DSIZE_Z] ? (m_ipo_xform.GetScaling()[2] + m_ipo_xform.GetDeltaScaling()[2]) : m_ipo_xform.GetScaling()[2]); } else if (m_ipo_channels_active[OB_DSIZE_Z] && m_ipo_start_initialized) { - newScale[2] = (m_ipo_xform.GetDeltaScaling()[2] + m_ipo_start_scale[2]); + newScale[2] = (m_ipo_xform.GetDeltaScaling()[2] + ((!m_ipo_add)?m_ipo_start_scale[2]:1.0)); + } + + if (m_ipo_add) { + newScale = m_ipo_start_scale * newScale; } ob->SetLocalScale(newScale); diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h index 7b5a151b41c..0bd8980f11c 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.h +++ b/source/gameengine/Ketsji/KX_IPO_SGController.h @@ -48,8 +48,11 @@ class KX_IpoSGController : public SG_Controller /** Interpret the ipo as a force rather than a displacement? */ bool m_ipo_as_force; - /** Ipo-as-force acts in local rather than in global coordinates? */ - bool m_force_ipo_acts_local; + /** Add Ipo curve to current loc/rot/scale */ + bool m_ipo_add; + + /** Ipo must be applied in local coordinate rather than in global coordinates (used for force and Add mode)*/ + bool m_ipo_local; /** Were settings altered since the last update? */ bool m_modified; diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp index cf246342cf9..b7103f49aee 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.cpp +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -59,40 +59,6 @@ STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp"; /* ------------------------------------------------------------------------- */ /* Native functions */ /* ------------------------------------------------------------------------- */ -/** Another poltergeist? This seems to be a very transient class... */ -class CIpoAction : public CAction -{ - float m_curtime; - bool m_recurse; - KX_GameObject* m_gameobj; - bool m_ipo_as_force; - bool m_force_ipo_local; - -public: - CIpoAction(KX_GameObject* gameobj, - float curtime, - bool recurse, - bool ipo_as_force, - bool force_ipo_local) : - m_curtime(curtime) , - m_recurse(recurse), - m_gameobj(gameobj), - m_ipo_as_force(ipo_as_force), - m_force_ipo_local(force_ipo_local) - { - /* intentionally empty */ - }; - - virtual void Execute() const - { - m_gameobj->UpdateIPO( - m_curtime, - m_recurse, - m_ipo_as_force, - m_force_ipo_local); - }; - -}; KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, const STR_String& propname, @@ -101,7 +67,8 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, bool recurse, int acttype, bool ipo_as_force, - bool force_ipo_local, + bool ipo_add, + bool ipo_local, PyTypeObject* T) : SCA_IActuator(gameobj,T), m_bNegativeEvent(false), @@ -112,7 +79,8 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, m_direction(1), m_propname(propname), m_ipo_as_force(ipo_as_force), - m_force_ipo_local(force_ipo_local), + m_ipo_add(ipo_add), + m_ipo_local(ipo_local), m_type((IpoActType)acttype) { m_starttime = -2.0*fabs(m_endframe - m_startframe) - 1.0; @@ -160,7 +128,7 @@ bool KX_IpoActuator::ClampLocalTime() void KX_IpoActuator::SetStartTime(float curtime) { - float direction = m_startframe < m_endframe ? 1.0 : -1.0; + float direction = m_startframe < m_endframe ? 1.0f : -1.0f; curtime = curtime - KX_KetsjiEngine::GetSuspendedDelta(); if (m_direction > 0) @@ -195,31 +163,26 @@ bool KX_IpoActuator::Update(double curtime, bool frame) // maybe there are events for us in the queue ! bool bNegativeEvent = false; int numevents = 0; + bool bIpoStart = false; if (frame) { numevents = m_events.size(); - for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());) - { - --i; - if ((*i)->GetNumber() == 0.0f) - bNegativeEvent = true; - - (*i)->Release(); - } - m_events.clear(); + bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); } - double start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0); + float start_smaller_then_end = ( m_startframe < m_endframe ? 1.0f : -1.0f); bool result=true; if (!bNegativeEvent) { - if (m_starttime < -2.0*start_smaller_then_end*(m_endframe - m_startframe)) + if (m_starttime < -2.0f*start_smaller_then_end*(m_endframe - m_startframe)) { // start for all Ipo, initial start for LOOP_STOP m_starttime = curtime - KX_KetsjiEngine::GetSuspendedDelta(); m_bIpoPlaying = true; + bIpoStart = true; } } @@ -230,7 +193,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame) { // Check if playing forwards. result = ! finished - if (start_smaller_then_end > 0.0) + if (start_smaller_then_end > 0.f) result = (m_localtime < m_endframe && m_bIpoPlaying); else result = (m_localtime > m_endframe && m_bIpoPlaying); @@ -241,14 +204,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame) /* Perform clamping */ ClampLocalTime(); - - CIpoAction ipoaction( - (KX_GameObject*)GetParent(), - m_localtime, - m_recurse, - m_ipo_as_force, - m_force_ipo_local); - GetParent()->Execute(ipoaction); + + if (bIpoStart) + ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local); + ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse); } else { m_localtime=m_startframe; @@ -270,13 +229,9 @@ bool KX_IpoActuator::Update(double curtime, bool frame) m_direction = -m_direction; } - CIpoAction ipoaction( - (KX_GameObject*) GetParent(), - m_localtime, - m_recurse, - m_ipo_as_force, - m_force_ipo_local); - GetParent()->Execute(ipoaction); + if (bIpoStart && m_direction > 0) + ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local); + ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse); break; } case KX_ACT_IPO_FLIPPER: @@ -299,14 +254,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame) if (ClampLocalTime() && m_localtime == m_startframe) result = false; - - CIpoAction ipoaction( - (KX_GameObject*) GetParent(), - m_localtime, - m_recurse, - m_ipo_as_force, - m_force_ipo_local); - GetParent()->Execute(ipoaction); + + if (bIpoStart) + ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local); + ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse); break; } @@ -352,8 +303,12 @@ bool KX_IpoActuator::Update(double curtime, bool frame) if (!m_bNegativeEvent){ /* Perform wraparound */ SetLocalTime(curtime); - m_localtime = m_startframe + fmod(m_localtime, m_startframe - m_endframe); + if (start_smaller_then_end > 0.f) + m_localtime = m_startframe + fmod(m_localtime - m_startframe, m_endframe - m_startframe); + else + m_localtime = m_startframe - fmod(m_startframe - m_localtime, m_startframe - m_endframe); SetStartTime(curtime); + bIpoStart = true; } else { @@ -365,13 +320,9 @@ bool KX_IpoActuator::Update(double curtime, bool frame) } } - CIpoAction ipoaction( - (KX_GameObject*) GetParent(), - m_localtime, - m_recurse, - m_ipo_as_force, - m_force_ipo_local); - GetParent()->Execute(ipoaction); + if (m_bIpoPlaying && bIpoStart) + ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local); + ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse); break; } @@ -391,14 +342,9 @@ bool KX_IpoActuator::Update(double curtime, bool frame) { m_localtime = propval->GetNumber(); - CIpoAction ipoaction( - (KX_GameObject*) GetParent(), - m_localtime, - m_recurse, - m_ipo_as_force, - m_force_ipo_local); - GetParent()->Execute(ipoaction); - + if (bIpoStart) + ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local); + ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse); } else { result = false; @@ -493,6 +439,10 @@ PyMethodDef KX_IpoActuator::Methods[] = { METH_VARARGS, SetIpoAsForce_doc}, {"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce, METH_VARARGS, GetIpoAsForce_doc}, + {"setIpoAdd", (PyCFunction) KX_IpoActuator::sPySetIpoAdd, + METH_VARARGS, SetIpoAdd_doc}, + {"getIpoAdd", (PyCFunction) KX_IpoActuator::sPyGetIpoAdd, + METH_VARARGS, GetIpoAdd_doc}, {"setType", (PyCFunction) KX_IpoActuator::sPySetType, METH_VARARGS, SetType_doc}, {"getType", (PyCFunction) KX_IpoActuator::sPyGetType, @@ -512,11 +462,11 @@ PyObject* KX_IpoActuator::_getattr(const STR_String& attr) { /* set --------------------------------------------------------------------- */ char KX_IpoActuator::Set_doc[] = -"set(mode, startframe, endframe, force?)\n" -"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n" +"set(type, startframe, endframe, mode?)\n" +"\t - type: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n" "\t - startframe: first frame to use (int)\n" "\t - endframe : last frame to use (int)\n" -"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)" +"\t - mode? : special mode (0=normal, 1=interpret location as force, 2=additive)" "\tSet the properties of the actuator.\n"; PyObject* KX_IpoActuator::PySet(PyObject* self, PyObject* args, @@ -543,7 +493,8 @@ PyObject* KX_IpoActuator::PySet(PyObject* self, m_type = modenum; m_startframe = startFrame; m_endframe = stopFrame; - m_ipo_as_force = PyArgToBool(forceToggle); + m_ipo_as_force = forceToggle == 1; + m_ipo_add = forceToggle == 2; break; default: ; /* error */ @@ -641,6 +592,8 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self, } m_ipo_as_force = PyArgToBool(boolArg); + if (m_ipo_as_force) + m_ipo_add = false; Py_Return; } @@ -654,6 +607,36 @@ PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self, return BoolToPyArg(m_ipo_as_force); } +/* 6. setIpoAsForce: */ +char KX_IpoActuator::SetIpoAdd_doc[] = +"setIpoAdd(add?)\n" +"\t - add? : add flag (KX_TRUE, KX_FALSE)\n" +"\tSet whether to interpret the ipo as additive rather than absolute.\n"; +PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self, + PyObject* args, + PyObject* kwds) { + int boolArg; + + if (!PyArg_ParseTuple(args, "i", &boolArg)) { + return NULL; + } + + m_ipo_add = PyArgToBool(boolArg); + if (m_ipo_add) + m_ipo_as_force = false; + + Py_Return; +} +/* 7. getIpoAsForce: */ +char KX_IpoActuator::GetIpoAdd_doc[] = +"getIpoAsAdd()\n" +"\tReturns whether to interpret the ipo as additive rather than absolute.\n"; +PyObject* KX_IpoActuator::PyGetIpoAdd(PyObject* self, + PyObject* args, + PyObject* kwds) { + return BoolToPyArg(m_ipo_add); +} + /* 8. setType: */ char KX_IpoActuator::SetType_doc[] = "setType(mode)\n" @@ -701,7 +684,7 @@ PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self, return NULL; } - m_force_ipo_local = PyArgToBool(boolArg); + m_ipo_local = PyArgToBool(boolArg); Py_Return; } @@ -713,7 +696,7 @@ char KX_IpoActuator::GetForceIpoActsLocal_doc[] = PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self, PyObject* args, PyObject* kwds) { - return BoolToPyArg(m_force_ipo_local); + return BoolToPyArg(m_ipo_local); } diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 79e8daa3f87..ae554fb0fce 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -75,8 +75,11 @@ protected: /** Interpret the ipo as a force? */ bool m_ipo_as_force; - /** Apply a force-ipo locally? */ - bool m_force_ipo_local; + /** Add Ipo curve to current loc/rot/scale */ + bool m_ipo_add; + + /** The Ipo curve is applied in local coordinates */ + bool m_ipo_local; bool m_bIpoPlaying; @@ -113,7 +116,8 @@ public: bool recurse, int acttype, bool ipo_as_force, - bool force_ipo_local, + bool ipo_add, + bool ipo_local, PyTypeObject* T=&Type); virtual ~KX_IpoActuator() {}; @@ -144,6 +148,8 @@ public: KX_PYMETHOD_DOC(KX_IpoActuator,GetEnd); KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAsForce); KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAsForce); + KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAdd); + KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAdd); KX_PYMETHOD_DOC(KX_IpoActuator,SetType); KX_PYMETHOD_DOC(KX_IpoActuator,GetType); KX_PYMETHOD_DOC(KX_IpoActuator,SetForceIpoActsLocal); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 56a06786679..20187a193ba 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -55,6 +55,7 @@ #include "KX_Scene.h" #include "MT_CmMatrix4x4.h" #include "KX_Camera.h" +#include "KX_Light.h" #include "KX_PythonInit.h" #include "KX_PyConstraintBinding.h" #include "PHY_IPhysicsEnvironment.h" @@ -614,6 +615,9 @@ void KX_KetsjiEngine::Render() // pass the scene's worldsettings to the rasterizer SetWorldSettings(scene->GetWorldInfo()); + // shadow buffers + RenderShadowBuffers(scene); + // Avoid drawing the scene with the active camera twice when it's viewport is enabled if(cam && !cam->GetViewport()) { @@ -885,8 +889,48 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam) viewport.GetTop() ); -} +} + +void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) +{ + CListValue *lightlist = scene->GetLightList(); + int i, drawmode; + for(i=0; i<lightlist->GetCount(); i++) { + KX_LightObject *light = (KX_LightObject*)lightlist->GetValue(i); + + light->Update(); + + if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) { + /* make temporary camera */ + RAS_CameraData camdata = RAS_CameraData(); + KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false); + cam->SetName("__shadow__cam__"); + + MT_Transform camtrans; + + /* switch drawmode for speed */ + drawmode = m_rasterizer->GetDrawingMode(); + m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW); + + /* binds framebuffer object, sets up camera .. */ + light->BindShadowBuffer(m_rasterizer, cam, camtrans); + + /* update scene */ + scene->UpdateMeshTransformations(); + scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer()); + + /* render */ + m_rasterizer->ClearDepthBuffer(); + scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + + /* unbind framebuffer object, restore drawmode, free camera */ + light->UnbindShadowBuffer(m_rasterizer); + m_rasterizer->SetDrawingMode(drawmode); + cam->Release(); + } + } +} // update graphics void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 4c09bc3fcd5..77b69ec2d9e 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -179,6 +179,7 @@ private: void RenderFrame(KX_Scene* scene, KX_Camera* cam); void PostRenderFrame(); void RenderDebugProperties(); + void RenderShadowBuffers(KX_Scene *scene); void SetBackGround(KX_WorldInfo* worldinfo); void SetWorldSettings(KX_WorldInfo* worldinfo); void DoSound(KX_Scene* scene); diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 7decc5bc769..4e3d6180d22 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -36,14 +36,20 @@ #endif #include "KX_Light.h" +#include "KX_Camera.h" +#include "RAS_IRasterizer.h" #include "RAS_IRenderTools.h" #include "KX_PyMath.h" +#ifdef BLENDER_GLSL +#include "GPU_material.h" +#endif KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, class RAS_IRenderTools* rendertools, const RAS_LightObject& lightobj, + struct GPULamp *gpulamp, PyTypeObject* T ) : @@ -53,12 +59,12 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_lightobj = lightobj; m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr(); m_rendertools->AddLight(&m_lightobj); + m_gpulamp = gpulamp; }; KX_LightObject::~KX_LightObject() { - m_rendertools->RemoveLight(&m_lightobj); } @@ -78,6 +84,78 @@ CValue* KX_LightObject::GetReplica() return replica; } +void KX_LightObject::Update() +{ +#ifdef BLENDER_GLSL + if(m_gpulamp) { + float obmat[4][4]; + double *dobmat = GetOpenGLMatrixPtr()->getPointer(); + + for(int i=0; i<4; i++) + for(int j=0; j<4; j++, dobmat++) + obmat[i][j] = (float)*dobmat; + + GPU_lamp_update(m_gpulamp, obmat); + } +#endif +} + +bool KX_LightObject::HasShadowBuffer() +{ +#ifdef BLENDER_GLSL + return (m_gpulamp && GPU_lamp_has_shadow_buffer(m_gpulamp)); +#else + return false; +#endif +} + +int KX_LightObject::GetShadowLayer() +{ +#ifdef BLENDER_GLSL + if(m_gpulamp) + return GPU_lamp_shadow_layer(m_gpulamp); + else +#endif + return 0; +} + +void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans) +{ +#ifdef BLENDER_GLSL + float viewmat[4][4], winmat[4][4]; + int winsize; + + /* bind framebuffer */ + GPU_lamp_shadow_buffer_bind(m_gpulamp, viewmat, &winsize, winmat); + + /* setup camera transformation */ + MT_Matrix4x4 modelviewmat((float*)viewmat); + MT_Matrix4x4 projectionmat((float*)winmat); + + MT_Transform trans = MT_Transform((float*)viewmat); + camtrans.invert(trans); + + cam->SetModelviewMatrix(modelviewmat); + cam->SetProjectionMatrix(projectionmat); + + cam->NodeSetLocalPosition(camtrans.getOrigin()); + cam->NodeSetLocalOrientation(camtrans.getBasis()); + cam->NodeUpdateGS(0,true); + + /* setup rasterizer transformations */ + ras->SetProjectionMatrix(projectionmat); + ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(), + cam->GetCameraLocation(), cam->GetCameraOrientation()); +#endif +} + +void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras) +{ +#ifdef BLENDER_GLSL + GPU_lamp_shadow_buffer_unbind(m_gpulamp); +#endif +} + PyObject* KX_LightObject::_getattr(const STR_String& attr) { if (attr == "layer") diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 236d3e4e12e..62eb26c61a8 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -32,19 +32,33 @@ #include "RAS_LightObject.h" #include "KX_GameObject.h" +struct GPULamp; +class KX_Camera; +class RAS_IRasterizer; +class RAS_IRenderTools; +class MT_Transform; + class KX_LightObject : public KX_GameObject { Py_Header; protected: RAS_LightObject m_lightobj; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj + struct GPULamp *m_gpulamp; static char doc[]; public: - KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, PyTypeObject *T = &Type); + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct GPULamp *gpulamp, PyTypeObject *T = &Type); virtual ~KX_LightObject(); virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} + + /* GLSL shadow */ + bool HasShadowBuffer(); + int GetShadowLayer(); + void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans); + 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); diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 5c433cb68b1..8b379bcd44f 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -77,6 +77,12 @@ CValue* KX_ParentActuator::GetReplica() bool KX_ParentActuator::Update() { + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + KX_GameObject *obj = (KX_GameObject*) GetParent(); KX_Scene *scene = PHY_GetActiveScene(); switch (m_mode) { diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 337b1af6df7..065800379d8 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -601,6 +601,8 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj) } } } + // ready to set initial state + newobj->ResetState(); } @@ -886,6 +888,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) else if (bHasArmature) { BL_SkinDeformer* skinDeformer = new BL_SkinDeformer( + newobj, oldblendobj, blendobj, static_cast<BL_SkinMeshObject*>(mesh), true, @@ -897,7 +900,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj) else if (bHasDvert) { BL_MeshDeformer* meshdeformer = new BL_MeshDeformer( - oldblendobj, static_cast<BL_SkinMeshObject*>(mesh) + newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh) ); newobj->m_pDeformer = meshdeformer; } @@ -1002,12 +1005,13 @@ void KX_Scene::UpdateMeshTransformations() } } -void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam) +void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam, int layer) { int intersect = KX_Camera::INTERSECT; KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL; - bool dotest = (gameobj && gameobj->GetVisible()) || node->Left() || node->Right(); - + bool visible = (gameobj && gameobj->GetVisible() && (!layer || (gameobj->GetLayer() & layer))); + bool dotest = visible || node->Left() || node->Right(); + /* If the camera is inside the box, assume intersect. */ if (dotest && !node->inside( cam->NodeGetWorldPosition())) { @@ -1031,19 +1035,19 @@ void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam break; case KX_Camera::INTERSECT: if (gameobj) - MarkVisible(rasty, gameobj,cam); + MarkVisible(rasty, gameobj, cam, layer); if (node->Left()) - MarkVisible(node->Left(), rasty,cam); + MarkVisible(node->Left(), rasty, cam, layer); if (node->Right()) - MarkVisible(node->Right(), rasty,cam); + MarkVisible(node->Right(), rasty, cam, layer); break; case KX_Camera::INSIDE: - MarkSubTreeVisible(node, rasty, true,cam); + MarkSubTreeVisible(node, rasty, true, cam, layer); break; } } -void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible,KX_Camera* cam) +void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera* cam, int layer) { if (node->Client()) { @@ -1066,16 +1070,23 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi } } if (node->Left()) - MarkSubTreeVisible(node->Left(), rasty, visible,cam); + MarkSubTreeVisible(node->Left(), rasty, visible, cam, layer); if (node->Right()) - MarkSubTreeVisible(node->Right(), rasty, visible,cam); + MarkSubTreeVisible(node->Right(), rasty, visible, cam, layer); } -void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam) +void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam,int layer) { // User (Python/Actuator) has forced object invisible... if (!gameobj->GetVisible()) return; + + // Shadow lamp layers + if(layer && !(gameobj->GetLayer() & layer)) { + gameobj->MarkVisible(false); + return; + } + // If Frustum culling is off, the object is always visible. bool vis = !cam->GetFrustumCulling(); @@ -1125,20 +1136,20 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam } } -void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam) +void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer) { // FIXME: When tree is operational #if 1 // do this incrementally in the future for (int i = 0; i < m_objectlist->GetCount(); i++) { - MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam); + MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer); } #else if (cam->GetFrustumCulling()) - MarkVisible(m_objecttree, rasty, cam); + MarkVisible(m_objecttree, rasty, cam, layer); else - MarkSubTreeVisible(m_objecttree, rasty, true, cam); + MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer); #endif } diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 733df2f69a1..28dee1b5893 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -260,9 +260,9 @@ protected: /** * Visibility testing functions. */ - void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam); - void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam); - void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam); + void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam,int layer=0); + void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam,int layer=0); + void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam, int layer=0); double m_suspendedtime; double m_suspendeddelta; @@ -483,7 +483,7 @@ public: void SetNetworkScene(NG_NetworkScene *newScene); void SetWorldInfo(class KX_WorldInfo* wi); KX_WorldInfo* GetWorldInfo(); - void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam); + void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam, int layer=0); void UpdateMeshTransformations(); KX_Camera* GetpCamera(); SND_Scene* GetSoundScene(); diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp index 80ee15a9475..423543eef5c 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -137,14 +137,18 @@ void KX_TouchEventManager::NextFrame() // KX_GameObject* gameOb1 = ctrl1->getClientInfo(); KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(ctrl1->getNewClientInfo()); - list<SCA_ISensor*>::iterator sit; - for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) - static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL); - + if (client_info) { + for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) { + static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL); + } + } client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getNewClientInfo()); - for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) - static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL); + if (client_info) { + for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) { + static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL); + } + } } m_newCollisions.clear(); diff --git a/source/gameengine/PyDoc/BL_ActionActuator.py b/source/gameengine/PyDoc/BL_ActionActuator.py index 41f41080c31..d56888cde80 100644 --- a/source/gameengine/PyDoc/BL_ActionActuator.py +++ b/source/gameengine/PyDoc/BL_ActionActuator.py @@ -86,6 +86,14 @@ class BL_ActionActuator(SCA_IActuator): @param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND @type mode: integer """ + + def setContinue(cont): + """ + Set the actions continue option True or False. see getContinue. + + @param cont: The continue option. + @type cont: bool + """ def getType(): """ @@ -94,6 +102,13 @@ class BL_ActionActuator(SCA_IActuator): @rtype: integer @return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND """ + + def getContinue(): + """ + When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. + + @rtype: bool + """ def getAction(): """ diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index 50df1a1e2ea..b4492ca03a9 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -109,7 +109,7 @@ void RAS_BucketManager::RenderAlphaBuckets( // it is needed for compatibility. rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED); - int drawingmode; + RAS_IRasterizer::DrawMode drawingmode; std::multiset< alphamesh, backtofront>::iterator msit = alphameshset.begin(); for (; msit != alphameshset.end(); ++msit) { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index bff98abe058..cb10ba6bf37 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -27,6 +27,7 @@ */ #include "RAS_IPolygonMaterial.h" +#include "RAS_IRasterizer.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -148,4 +149,19 @@ const unsigned int RAS_IPolyMaterial::GetFlag() const return m_flag; } +bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const +{ + bool dolights = false; + + if(m_flag & RAS_BLENDERMAT) + dolights = (m_flag &RAS_MULTILIGHT)!=0; + else if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID); + else if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW); + else + dolights = (m_drawingmode & 16)!=0; + + return dolights; +} + unsigned int RAS_IPolyMaterial::m_newpolymatid = 0; + diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 09824f6975c..d2d1dba99d9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -140,6 +140,8 @@ public: const STR_String& GetMaterialName() const; const STR_String& GetTextureName() const; const unsigned int GetFlag() const; + + virtual bool UsesLighting(RAS_IRasterizer *rasty) const; /* * PreCalculate texture gen diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index dbedc492afa..d4a9177a85d 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -33,12 +33,23 @@ #pragma warning (disable:4786) #endif +#include "STR_HashedString.h" + #include "MT_CmMatrix4x4.h" #include "MT_Matrix4x4.h" +#include "RAS_TexVert.h" + +#include <vector> +using namespace std; + class RAS_ICanvas; class RAS_IPolyMaterial; -#include "RAS_MaterialBucket.h" + +typedef vector<unsigned short> KX_IndexArray; +typedef vector<RAS_TexVert> KX_VertexArray; +typedef vector< KX_VertexArray* > vecVertexArray; +typedef vector< KX_IndexArray* > vecIndexArrays; /** * 3D rendering device context interface. @@ -62,7 +73,18 @@ public: KX_WIREFRAME, KX_SOLID, KX_SHADED, - KX_TEXTURED + KX_TEXTURED, + KX_SHADOW + }; + + /** + * Drawing modes + */ + + enum DrawMode { + KX_MODE_LINES = 1, + KX_MODE_TRIANGLES, + KX_MODE_QUADS }; /** @@ -111,6 +133,7 @@ public: RAS_TEXCO_NORM, //< Normal coordinates RAS_TEXTANGENT, //< RAS_TEXCO_UV2, //< + RAS_TEXCO_VCOL, //< Vertex Color RAS_TEXCO_DISABLE //< Disable this texture unit (cached) }; @@ -197,45 +220,37 @@ public: * IndexPrimitives: Renders primitives. * @param vertexarrays is an array of vertex arrays * @param indexarrays is an array of index arrays - * @param mode determines the type of primitive stored in the vertex/index arrays: - * 0 triangles - * 1 lines (default) - * 2 quads - * @param polymat (reserved) + * @param mode determines the type of primitive stored in the vertex/index arrays * @param useObjectColor will render the object using @param rgbacolor instead of * vertex colors. */ - virtual void IndexPrimitives( const vecVertexArray& vertexarrays, + virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot)=0; + virtual void IndexPrimitivesMulti( + const vecVertexArray& vertexarrays, + const vecIndexArrays & indexarrays, + DrawMode mode, + bool useObjectColor, + const MT_Vector4& rgbacolor, + class KX_ListSlot** slot)=0; + /** * IndexPrimitives_3DText will render text into the polygons. * The text to be rendered is from @param rendertools client object's text property. */ virtual void IndexPrimitives_3DText( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, + DrawMode mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, const MT_Vector4& rgbacolor)=0; - virtual void IndexPrimitivesMulti( - const vecVertexArray& vertexarrays, - const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, - bool useObjectColor, - const MT_Vector4& rgbacolor, - class KX_ListSlot** slot)=0; - virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat)=0; /* This one should become our final version, methinks. */ /** diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 1beade7acf7..e295d69e48e 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -167,38 +167,30 @@ RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msEnd() } bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools *rendertools, int &drawmode) + RAS_IRenderTools *rendertools, RAS_IRasterizer::DrawMode &drawmode) { rendertools->SetViewMat(cameratrans); if (!rasty->SetMaterial(*m_material)) return false; - bool dolights = false; - const unsigned int flag = m_material->GetFlag(); - - if( flag & RAS_BLENDERMAT) - dolights = (flag &RAS_MULTILIGHT)!=0; + if (m_material->UsesLighting(rasty)) + rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER/*m_material->GetLightLayer()*/); else - dolights = (m_material->GetDrawingMode()&16)!=0; - - if ((rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) || !dolights) - { rendertools->ProcessLighting(-1); - } - else - { - rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER/*m_material->GetLightLayer()*/); - } - drawmode = (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ? - 1: (m_material->UsesTriangles() ? 0 : 2)); + if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) + drawmode = RAS_IRasterizer::KX_MODE_LINES; + else if(m_material->UsesTriangles()) + drawmode = RAS_IRasterizer::KX_MODE_TRIANGLES; + else + drawmode = RAS_IRasterizer::KX_MODE_QUADS; return true; } void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode) + RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, RAS_IRasterizer::DrawMode drawmode) { if (!ms.m_bVisible) return; @@ -225,6 +217,17 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms.m_DisplayList->SetModified(ms.m_mesh->MeshModified()); } + // verify if we can use display list, not for deformed object, and + // also don't create a new display list when drawing shadow buffers, + // then it won't have texture coordinates for actual drawing + KX_ListSlot **displaylist; + if(ms.m_pDeformer) + displaylist = 0; + else if(!ms.m_DisplayList && rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW) + displaylist = 0; + else + displaylist = &ms.m_DisplayList; + // Use the text-specific IndexPrimitives for text faces if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT) { @@ -245,12 +248,9 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms.m_mesh->GetVertexCache(m_material), ms.m_mesh->GetIndexCache(m_material), drawmode, - m_material, - rendertools, ms.m_bObjectColor, ms.m_RGBAcolor, - (ms.m_pDeformer)? 0: &ms.m_DisplayList - ); + displaylist); } // Use the normal IndexPrimitives @@ -260,12 +260,9 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa ms.m_mesh->GetVertexCache(m_material), ms.m_mesh->GetIndexCache(m_material), drawmode, - m_material, - rendertools, // needed for textprinting on polys ms.m_bObjectColor, ms.m_RGBAcolor, - (ms.m_pDeformer)? 0: &ms.m_DisplayList - ); + displaylist); } if(rasty->QueryLists()) { @@ -287,7 +284,7 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans, //rasty->SetMaterial(*m_material); - int drawmode; + RAS_IRasterizer::DrawMode drawmode; for (T_MeshSlotList::const_iterator it = m_meshSlots.begin(); ! (it == m_meshSlots.end()); ++it) { diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 5ad0c173a56..13d8a53714a 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -35,17 +35,13 @@ #include "MT_Transform.h" #include "RAS_IPolygonMaterial.h" +#include "RAS_IRasterizer.h" #include "RAS_Deformer.h" // __NLA #include <vector> #include <map> #include <set> using namespace std; -typedef vector<unsigned short> KX_IndexArray; -typedef vector<RAS_TexVert> KX_VertexArray; -typedef vector< KX_VertexArray* > vecVertexArray; -typedef vector< KX_IndexArray* > vecIndexArrays; - /** * KX_VertexIndex */ @@ -146,9 +142,9 @@ public: const MT_Vector4& rgbavec); void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode); + RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, RAS_IRasterizer::DrawMode drawmode); bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty, - RAS_IRenderTools *rendertools, int &drawmode); + RAS_IRenderTools *rendertools, RAS_IRasterizer::DrawMode& drawmode); unsigned int NumMeshSlots(); T_MeshSlotList::iterator msBegin(); diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index d7ab88a6b06..4420f16c56d 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -68,8 +68,8 @@ RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer) m_lightlayer(lightlayer), m_zsort(false), m_MeshMod(true), - m_class(0), - m_mesh(mesh) + m_mesh(mesh), + m_class(0) { } @@ -259,18 +259,18 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, const MT_Vector3& normal, bool flat, RAS_IPolyMaterial* mat, - int orgindex) + int origindex) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(mat); int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray]; - RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0); + RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0,origindex); #define KX_FIND_SHARED_VERTICES #ifdef KX_FIND_SHARED_VERTICES if(!flat) { - for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin(); - it != m_xyz_index_to_vertex_index_mapping[orgindex].end(); + for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[origindex].begin(); + it != m_xyz_index_to_vertex_index_mapping[origindex].end(); it++) { if ((*it).m_arrayindex1 == ao->m_index1 && @@ -293,22 +293,18 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray, idx.m_array = vtxarray; idx.m_index = numverts; idx.m_matid = mat; - m_xyz_index_to_vertex_index_mapping[orgindex].push_back(idx); + m_xyz_index_to_vertex_index_mapping[origindex].push_back(idx); return numverts; } - - -const vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat) +vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(mat); return ao->m_VertexArrayCache1; } - - int RAS_MeshObject::GetVertexArrayLength(RAS_IPolyMaterial* mat) { int len = 0; @@ -362,7 +358,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid, const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(mat); return ao->m_IndexArrayCache1; } @@ -371,16 +367,27 @@ const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat) KX_ArrayOptimizer* RAS_MeshObject::GetArrayOptimizer(RAS_IPolyMaterial* polymat) { - KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]); + KX_ArrayOptimizer** aop = m_matVertexArrayS[polymat]; - if (aop) + if(aop) return *aop; + // didn't find array, but an array might already exist + // for a material equal to this one + for(int i=0;i<m_matVertexArrayS.size();i++) { + RAS_IPolyMaterial *mat = (RAS_IPolyMaterial*)(m_matVertexArrayS.getKey(i)->getValue()); + if(*mat == *polymat) { + m_matVertexArrayS.insert(polymat, *m_matVertexArrayS.at(i)); + return *m_matVertexArrayS.at(i); + } + } + + // create new array int numelements = m_matVertexArrayS.size(); m_sortedMaterials.push_back(polymat); - + KX_ArrayOptimizer* ao = new KX_ArrayOptimizer(numelements); - m_matVertexArrayS.insert(*polymat,ao); + m_matVertexArrayS.insert(polymat, ao); return ao; } @@ -463,7 +470,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(short array, unsigned int index, RAS_IPolyMaterial* polymat) { - KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);//*(m_matVertexArrays[*polymat]); + KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat); return &((*(ao->m_VertexArrayCache1)[array])[index]); } @@ -471,13 +478,19 @@ RAS_TexVert* RAS_MeshObject::GetVertex(short array, void RAS_MeshObject::ClearArrayData() { - for (int i=0;i<m_matVertexArrayS.size();i++) - { + for (int i=0;i<m_matVertexArrayS.size();i++) { KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i); + + // we have duplicate entries, only free once + for(int j=i+1;j<m_matVertexArrayS.size();j++) { + if(ao == m_matVertexArrayS.at(j)) { + ao = NULL; + break; + } + } + if (ao) - { delete *ao; - } } } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index d9aa133efb2..0d06748f91f 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -142,7 +142,7 @@ protected: enum { BUCKET_MAX_INDICES = 65535 };//2048};//8192}; enum { BUCKET_MAX_TRIANGLES = 65535 }; - GEN_Map<class RAS_IPolyMaterial,KX_ArrayOptimizer*> m_matVertexArrayS; + GEN_Map<GEN_HashedPtr,KX_ArrayOptimizer*> m_matVertexArrayS; RAS_MaterialBucket::Set m_materials; Mesh* m_mesh; @@ -242,10 +242,10 @@ public: const MT_Vector3& normal, bool flat, RAS_IPolyMaterial* mat, - int orgindex + int origindex ); - const vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat); + vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat); int GetVertexArrayLength(RAS_IPolyMaterial* mat); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index 39080b80492..c2687319717 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -161,9 +161,7 @@ void RAS_ListRasterizer::ReleaseAlloc() void RAS_ListRasterizer::IndexPrimitives( const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) @@ -185,15 +183,13 @@ void RAS_ListRasterizer::IndexPrimitives( if (mUseVertexArrays) { RAS_VAOpenGLRasterizer::IndexPrimitives( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } else { RAS_OpenGLRasterizer::IndexPrimitives( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } @@ -208,9 +204,7 @@ void RAS_ListRasterizer::IndexPrimitives( void RAS_ListRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) @@ -230,18 +224,19 @@ void RAS_ListRasterizer::IndexPrimitivesMulti( } } - if (mUseVertexArrays) { + // workaround: note how we do not use vertex arrays for making display + // lists, since glVertexAttribPointerARB doesn't seem to work correct + // in display lists on ATI? either a bug in the driver or in Blender .. + if (mUseVertexArrays && !localSlot) { RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } else { RAS_OpenGLRasterizer::IndexPrimitivesMulti( vertexarrays, indexarrays, - mode, polymat, - rendertools, useObjectColor, + mode, useObjectColor, rgbacolor,slot ); } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index 4b3304d7396..b1b19144c12 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -52,9 +52,7 @@ public: virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot @@ -63,9 +61,7 @@ public: virtual void IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 18147b53f4c..dcc36bf5a39 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -368,23 +368,11 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) switch (m_drawingmode) { - case KX_BOUNDINGBOX: - { - } case KX_WIREFRAME: { glDisable (GL_CULL_FACE); break; } - case KX_TEXTURED: - { - } - case KX_SHADED: - { - } - case KX_SOLID: - { - } default: { } @@ -603,33 +591,14 @@ void RAS_OpenGLRasterizer::GetViewMatrix(MT_Matrix4x4 &mat) const void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot ) { - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - - const RAS_TexVert* vertexarray ; - unsigned int numindices,vt; + const RAS_TexVert* vertexarray; + unsigned int numindices, vt; for (vt=0;vt<vertexarrays.size();vt++) { @@ -643,7 +612,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, int vindex=0; switch (mode) { - case 1: + case KX_MODE_LINES: { glBegin(GL_LINES); vindex=0; @@ -655,7 +624,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, glEnd(); } break; - case 2: + case KX_MODE_QUADS: { glBegin(GL_QUADS); vindex=0; @@ -723,7 +692,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, glEnd(); break; } - case 0: + case KX_MODE_TRIANGLES: { glBegin(GL_TRIANGLES); vindex=0; @@ -788,32 +757,14 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays, void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays, const vecIndexArrays & indexarrays, - int mode, + DrawMode mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, const MT_Vector4& rgbacolor ) { - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - - const RAS_TexVert* vertexarray ; - + const RAS_TexVert* vertexarray; unsigned int numindices, vt; if (useObjectColor) @@ -838,7 +789,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa int vindex=0; switch (mode) { - case 1: + case KX_MODE_LINES: { glBegin(GL_LINES); vindex=0; @@ -850,7 +801,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa glEnd(); } break; - case 2: + case KX_MODE_QUADS: { vindex=0; for (unsigned int i=0;i<numindices;i+=4) @@ -883,7 +834,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa } break; } - case 0: + case KX_MODE_TRIANGLES: { glBegin(GL_TRIANGLES); vindex=0; @@ -999,6 +950,9 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv) case RAS_TEXCO_UV2: glVertexAttrib2fvARB(unit, tv.getUV2()); break; + case RAS_TEXCO_VCOL: + glVertexAttrib4ubvARB(unit, tv.getRGBA()); + break; default: break; } @@ -1037,32 +991,14 @@ void RAS_OpenGLRasterizer::Tangent( const RAS_TexVert& v1, void RAS_OpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot ) { - GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 1: - drawmode = GL_LINES; - break; - case 2: - drawmode = GL_QUADS; - break; - default: - drawmode = GL_LINES; - break; - } - const RAS_TexVert* vertexarray ; + const RAS_TexVert* vertexarray; unsigned int numindices,vt; for (vt=0;vt<vertexarrays.size();vt++) @@ -1077,7 +1013,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( int vindex=0; switch (mode) { - case 1: + case KX_MODE_LINES: { glBegin(GL_LINES); vindex=0; @@ -1089,7 +1025,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( glEnd(); } break; - case 2: + case KX_MODE_QUADS: { glBegin(GL_QUADS); vindex=0; @@ -1166,7 +1102,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti( glEnd(); break; } - case 0: + case KX_MODE_TRIANGLES: { glBegin(GL_TRIANGLES); vindex=0; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 1f0709e081a..0d54552db05 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -148,9 +148,7 @@ public: virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot @@ -159,7 +157,7 @@ public: virtual void IndexPrimitives_3DText( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, + DrawMode mode, class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools, bool useObjectColor, @@ -169,9 +167,7 @@ public: virtual void IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp index c4702fe5a74..c78a97ad7be 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp @@ -59,9 +59,9 @@ bool RAS_VAOpenGLRasterizer::Init(void) if (result) { glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -77,13 +77,16 @@ void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) { case KX_BOUNDINGBOX: case KX_WIREFRAME: - glDisable (GL_CULL_FACE); + glDisableClientState(GL_COLOR_ARRAY); + glDisable(GL_CULL_FACE); + break; + case KX_SOLID: + glDisableClientState(GL_COLOR_ARRAY); break; case KX_TEXTURED: case KX_SHADED: + case KX_SHADOW: glEnableClientState(GL_COLOR_ARRAY); - case KX_SOLID: - break; default: break; } @@ -102,30 +105,23 @@ void RAS_VAOpenGLRasterizer::Exit() void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) { static const GLsizei vtxstride = sizeof(RAS_TexVert); GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 2: - drawmode = GL_QUADS; - break; - case 1: //lines - default: - drawmode = GL_LINES; - break; - } + if(mode == KX_MODE_TRIANGLES) + drawmode = GL_TRIANGLES; + else if(mode == KX_MODE_QUADS) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + const RAS_TexVert* vertexarray; unsigned int numindices, vt; + if (drawmode != GL_LINES) { if (useObjectColor) @@ -157,9 +153,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays continue; glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); - glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); - glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); + glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1()); + if(glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); //if(m_Lock) // local->Begin(vertexarrays[vt]->size()); @@ -169,8 +166,6 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays //if(m_Lock) // local->End(); - - } glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -178,28 +173,21 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot) { static const GLsizei vtxstride = sizeof(RAS_TexVert); + GLenum drawmode; - switch (mode) - { - case 0: - drawmode = GL_TRIANGLES; - break; - case 2: - drawmode = GL_QUADS; - break; - case 1: //lines - default: - drawmode = GL_LINES; - break; - } + if(mode == KX_MODE_TRIANGLES) + drawmode = GL_TRIANGLES; + else if(mode == KX_MODE_QUADS) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + const RAS_TexVert* vertexarray; unsigned int numindices, vt; @@ -232,10 +220,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa continue; glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ()); - TexCoordPtr(vertexarray); - - glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal()); + TexCoordPtr(vertexarray); + if(glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA()); //if(m_Lock) // local->Begin(vertexarrays[vt]->size()); @@ -296,19 +284,22 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv) switch(m_attrib[unit]) { case RAS_TEXCO_ORCO: case RAS_TEXCO_GLOB: - glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ()); + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ()); break; case RAS_TEXCO_UV1: - glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); break; case RAS_TEXCO_NORM: - glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); break; case RAS_TEXTANGENT: - glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); break; case RAS_TEXCO_UV2: - glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); + break; + case RAS_TEXCO_VCOL: + glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); break; default: break; @@ -386,11 +377,12 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) case RAS_TEXCO_NORM: case RAS_TEXTANGENT: case RAS_TEXCO_UV2: - if(enable) glEnableVertexAttribArray(unit); - else glDisableVertexAttribArray(unit); + case RAS_TEXCO_VCOL: + if(enable) glEnableVertexAttribArrayARB(unit); + else glDisableVertexAttribArrayARB(unit); break; default: - glDisableVertexAttribArray(unit); + glDisableVertexAttribArrayARB(unit); break; } } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h index ea08887028f..e4cc4ace0e8 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -52,9 +52,7 @@ public: virtual void IndexPrimitives( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot); @@ -62,9 +60,7 @@ public: virtual void IndexPrimitivesMulti( const vecVertexArray& vertexarrays, const vecIndexArrays & indexarrays, - int mode, - class RAS_IPolyMaterial* polymat, - class RAS_IRenderTools* rendertools, + DrawMode mode, bool useObjectColor, const MT_Vector4& rgbacolor, class KX_ListSlot** slot); diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 61ac456b2bc..935633dc636 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -40,7 +40,8 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, - const short flag) + const short flag, + const unsigned int origindex) { xyz.getValue(m_localxyz); uv.getValue(m_uv1); @@ -49,6 +50,7 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, SetNormal(normal); tangent.getValue(m_tangent); m_flag = flag; + m_origindex = origindex; m_unit = 2; } @@ -107,44 +109,6 @@ void RAS_TexVert::SetNormal(const MT_Vector3& normal) normal.getValue(m_normal); } -#ifndef RAS_TexVert_INLINE - -// leave multiline for debugging -const float* RAS_TexVert::getUV1 () const -{ - return m_uv1; -} - -const float* RAS_TexVert::getUV2 () const -{ - return m_uv2; -} - - - -const float* RAS_TexVert::getNormal() const -{ - return m_normal; -} - -const float* RAS_TexVert::getTangent() const -{ - return m_tangent; -} - - -const float* RAS_TexVert::getLocalXYZ() const -{ - return m_localxyz; -} - -const unsigned char* RAS_TexVert::getRGBA() const -{ - return (unsigned char*) &m_rgba; -} - -#endif - // compare two vertices, and return TRUE if both are almost identical (they can be shared) bool RAS_TexVert::closeTo(const RAS_TexVert* other) { diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 84135db918f..bf092b4b230 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -42,8 +42,6 @@ static MT_Point2 g_pt2; #define TV_MAX 3//match Def in BL_Material.h -#define RAS_TexVert_INLINE 1 - class RAS_TexVert { @@ -55,9 +53,10 @@ class RAS_TexVert float m_normal[3]; // 3*2 = 6 short m_flag; // 2 unsigned int m_unit; // 4 + unsigned int m_origindex; // 4 //--------- - // 52 - //32 bytes total size, fits nice = 52 = not fit nice. + // 56 + // 32 bytes total size, fits nice = 56 = not fit nice. // We'll go for 64 bytes total size - 24 bytes left. public: short getFlag() const; @@ -71,11 +70,10 @@ public: const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, - const short flag); + const short flag, + const unsigned int origindex); ~RAS_TexVert() {}; - // leave multiline for debugging -#ifdef RAS_TexVert_INLINE const float* getUV1 () const { return m_uv1; }; @@ -99,13 +97,11 @@ public: const unsigned char* getRGBA() const { return (unsigned char *) &m_rgba; } -#else - const float* getUV1 () const; - const float* getUV2 () const; - const float* getNormal() const; - const float* getLocalXYZ() const; - const unsigned char* getRGBA() const; -#endif + + const unsigned int getOrigIndex() const { + return m_origindex; + } + void SetXYZ(const MT_Point3& xyz); void SetUV(const MT_Point2& uv); void SetUV2(const MT_Point2& uv); diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h index d65a2f0c256..c32885b915f 100644 --- a/source/gameengine/SceneGraph/SG_Controller.h +++ b/source/gameengine/SceneGraph/SG_Controller.h @@ -101,7 +101,9 @@ public: enum SG_Controller_option { SG_CONTR_NODEF = 0, SG_CONTR_IPO_IPO_AS_FORCE, - SG_CONTR_IPO_FORCES_ACT_LOCAL, + SG_CONTR_IPO_IPO_ADD, + SG_CONTR_IPO_LOCAL, + SG_CONTR_IPO_RESET, SG_CONTR_CAMIPO_LENS, SG_CONTR_CAMIPO_CLIPEND, SG_CONTR_CAMIPO_CLIPSTART, |