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.
This commit is contained in:
Campbell Barton
2012-11-10 09:45:43 +00:00
parent f5c9f2c253
commit fecc3b9d68
7 changed files with 177 additions and 2 deletions

View 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.

View File

@@ -22,7 +22,7 @@
# Contributor(s): Jacques Beaurain.
#
# ***** END GPL LICENSE BLOCK *****
remove_strict_flags()
set(INC
)

View 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);

View 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);
};

View 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;

View 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());
}

View 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