add 2 new utility functions to the BGE mesh py api.
authorCampbell Barton <ideasman42@gmail.com>
Sat, 10 Nov 2012 09:45:43 +0000 (09:45 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 10 Nov 2012 09:45:43 +0000 (09:45 +0000)
  mesh.transform(matid, matrix)
  mesh.transform_uv(matid, matrix, uv_index=-1))

much more efficient then looping over verts in python to transform them.

doc/python_api/rst/bge.types.rst
intern/itasc/CMakeLists.txt
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_MeshProxy.h
source/gameengine/Rasterizer/RAS_MaterialBucket.h
source/gameengine/Rasterizer/RAS_TexVert.cpp
source/gameengine/Rasterizer/RAS_TexVert.h

index 431b264..5093cfe 100644 (file)
@@ -1957,6 +1957,26 @@ Types
       :return: a polygon object.
       :rtype: :class:`PolyProxy`
 
+   .. method:: transform(matid, matrix)
+
+      Transforms the vertices of a mesh.
+
+      :arg matid: material index, -1 transforms all.
+      :type matid: integer
+      :arg matrix: transformation matrix.
+      :type matrix: 4x4 matrix [[float]]
+
+   .. method:: transform_uv(matid, matrix, uv_index=-1)
+
+      Transforms the vertices UV's of a mesh.
+
+      :arg matid: material index, -1 transforms all.
+      :type matid: integer
+      :arg matrix: transformation matrix.
+      :type matrix: 4x4 matrix [[float]]
+      :arg matid: optional uv index, -1 for all, otherwise 0 or 1.
+      :type matid: integer
+
 .. class:: SCA_MouseSensor(SCA_ISensor)
 
    Mouse Sensor logic brick.
index 99c64d9..bc3ea0c 100644 (file)
@@ -22,7 +22,7 @@
 # Contributor(s): Jacques Beaurain.
 #
 # ***** END GPL LICENSE BLOCK *****
-
+remove_strict_flags()
 set(INC
 
 )
index 69be584..be4b0cd 100644 (file)
@@ -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);
index 98e73aa..5366634 100644 (file)
@@ -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);
 };
index 16ecffb..4c72f12 100644 (file)
@@ -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;
 
 
index 3b4f4ca..6d8cbfe 100644 (file)
@@ -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());
+}
index 889769d..bb151a6 100644 (file)
@@ -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