diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-11-10 13:45:43 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-11-10 13:45:43 +0400 |
commit | fecc3b9d68102630fc53f451a3f405f180b31384 (patch) | |
tree | 36d2ca28db9d0eb244ee9fad921d81f5d66adcbb /source/gameengine | |
parent | f5c9f2c2530d21474f8e2ee5ea7dfdb483b7ba7d (diff) |
add 2 new utility functions to the BGE mesh py api.
mesh.transform(matid, matrix)
mesh.transform_uv(matid, matrix, uv_index=-1))
much more efficient then looping over verts in python to transform them.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Ketsji/KX_MeshProxy.cpp | 140 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_MeshProxy.h | 4 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_MaterialBucket.h | 2 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_TexVert.cpp | 9 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_TexVert.h | 2 |
5 files changed, 156 insertions, 1 deletions
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 69be584343a..be4b0cd8031 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -75,6 +75,8 @@ PyMethodDef KX_MeshProxy::Methods[] = { {"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS}, {"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS}, {"getPolygon", (PyCFunction)KX_MeshProxy::sPyGetPolygon,METH_VARARGS}, + {"transform", (PyCFunction)KX_MeshProxy::sPyTransform,METH_VARARGS}, + {"transform_uv", (PyCFunction)KX_MeshProxy::sPyTransformUV,METH_VARARGS}, //{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS}, {NULL,NULL} //Sentinel }; @@ -218,6 +220,144 @@ PyObject *KX_MeshProxy::PyGetPolygon(PyObject *args, PyObject *kwds) return polyob; } +PyObject *KX_MeshProxy::PyTransform(PyObject *args, PyObject *kwds) +{ + int matindex; + PyObject *pymat; + bool ok = false; + + MT_Matrix4x4 transform; + + if (!PyArg_ParseTuple(args,"iO:transform", &matindex, &pymat) || + !PyMatTo(pymat, transform)) + { + return NULL; + } + + MT_Matrix4x4 ntransform = transform.inverse().transposed(); + ntransform[0][3] = ntransform[1][3] = ntransform[2][3] = 0.0f; + + /* transform mesh verts */ + unsigned int mit_index = 0; + for (list<RAS_MeshMaterial>::iterator mit = m_meshobj->GetFirstMaterial(); + (mit != m_meshobj->GetLastMaterial()); + ++mit, ++mit_index) + { + if (matindex == -1) { + /* always transform */ + } + else if (matindex == mit_index) { + /* we found the right index! */ + } + else { + continue; + } + + RAS_MeshSlot *slot = mit->m_baseslot; + RAS_MeshSlot::iterator it; + ok = true; + + for (slot->begin(it); !slot->end(it); slot->next(it)) { + size_t i; + for (i = it.startvertex; i < it.endvertex; i++) { + it.vertex[i].Transform(transform, ntransform); + } + } + + /* if we set a material index, quit when done */ + if (matindex == mit_index) { + break; + } + } + + if (ok == false) { + PyErr_Format(PyExc_ValueError, + "mesh.transform(...): invalid material index %d", matindex); + return NULL; + } + + m_meshobj->SetMeshModified(true); + + Py_RETURN_NONE; +} + +PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds) +{ + int matindex; + PyObject *pymat; + int uvindex = -1; + bool ok = false; + + MT_Matrix4x4 transform; + + if (!PyArg_ParseTuple(args,"iO|ii:transform_uv", &matindex, &pymat, &uvindex) || + !PyMatTo(pymat, transform)) + { + return NULL; + } + + if (uvindex < -1 || uvindex > 1) { + PyErr_Format(PyExc_ValueError, + "mesh.transform_uv(...): invalid uv index %d", uvindex); + return NULL; + } + + /* transform mesh verts */ + unsigned int mit_index = 0; + for (list<RAS_MeshMaterial>::iterator mit = m_meshobj->GetFirstMaterial(); + (mit != m_meshobj->GetLastMaterial()); + ++mit, ++mit_index) + { + if (matindex == -1) { + /* always transform */ + } + else if (matindex == mit_index) { + /* we found the right index! */ + } + else { + continue; + } + + RAS_MeshSlot *slot = mit->m_baseslot; + RAS_MeshSlot::iterator it; + ok = true; + + for (slot->begin(it); !slot->end(it); slot->next(it)) { + size_t i; + + for (i = it.startvertex; i < it.endvertex; i++) { + switch (uvindex) { + case 0: + it.vertex[i].TransformUV(transform); + break; + case 1: + it.vertex[i].TransformUV2(transform); + break; + case -1: + it.vertex[i].TransformUV(transform); + it.vertex[i].TransformUV2(transform); + break; + } + } + } + + /* if we set a material index, quit when done */ + if (matindex == mit_index) { + break; + } + } + + if (ok == false) { + PyErr_Format(PyExc_ValueError, + "mesh.transform_uv(...): invalid material index %d", matindex); + return NULL; + } + + m_meshobj->SetMeshModified(true); + + Py_RETURN_NONE; +} + PyObject *KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_MeshProxy* self = static_cast<KX_MeshProxy*>(self_v); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index 98e73aa626f..5366634ef98 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -71,8 +71,10 @@ public: KX_PYMETHOD(KX_MeshProxy,GetVertexArrayLength); KX_PYMETHOD(KX_MeshProxy,GetVertex); KX_PYMETHOD(KX_MeshProxy,GetPolygon); + KX_PYMETHOD(KX_MeshProxy,Transform); + KX_PYMETHOD(KX_MeshProxy,TransformUV); - static PyObject* pyattr_get_materials(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_materials(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_numMaterials(void * self, const KX_PYATTRIBUTE_DEF * attrdef); static PyObject *pyattr_get_numPolygons(void * self, const KX_PYATTRIBUTE_DEF * attrdef); }; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 16ecffb9a32..4c72f128817 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -189,6 +189,8 @@ class RAS_MeshMaterial public: RAS_MeshSlot *m_baseslot; class RAS_MaterialBucket *m_bucket; + + /* the KX_GameObject is used as a key here */ CTR_Map<CTR_HashedPtr,RAS_MeshSlot*> m_slots; diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 3b4f4cae30e..6d8cbfece15 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -151,3 +151,12 @@ void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat) SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue()); } +void RAS_TexVert::TransformUV(const MT_Matrix4x4& mat) +{ + SetUV((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue()); +} + +void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat) +{ + SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue()); +} diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 889769da5ed..bb151a64814 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -137,6 +137,8 @@ public: void Transform(const class MT_Matrix4x4& mat, const class MT_Matrix4x4& nmat); + void TransformUV(const MT_Matrix4x4& mat); + void TransformUV2(const MT_Matrix4x4& mat); // compare two vertices, to test if they can be shared, used for // splitting up based on uv's, colors, etc |