+void cmesh_apply_xform(struct cmesh *cm, float *xform, float *dir_xform)
+{
+ unsigned int i;
+ int j;
+ cgm_vec4 v;
+ cgm_vec3 n, t;
+ float *vptr;
+
+ for(i=0; i<cm->nverts; i++) {
+ if(!(vptr = get_vec4(cm, CMESH_ATTR_VERTEX, i, &v))) {
+ return;
+ }
+ cgm_wmul_m4v4(&v, xform);
+ for(j=0; j<cm->vattr[CMESH_ATTR_VERTEX].nelem; j++) {
+ *vptr++ = (&v.x)[j];
+ }
+
+ if(cmesh_has_attrib(cm, CMESH_ATTR_NORMAL)) {
+ if((vptr = get_vec3(cm, CMESH_ATTR_NORMAL, i, &n))) {
+ cgm_vmul_m3v3(&n, dir_xform);
+ for(j=0; j<cm->vattr[CMESH_ATTR_NORMAL].nelem; j++) {
+ *vptr++ = (&n.x)[j];
+ }
+ }
+ }
+ if(cmesh_has_attrib(cm, CMESH_ATTR_TANGENT)) {
+ if((vptr = get_vec3(cm, CMESH_ATTR_TANGENT, i, &t))) {
+ cgm_vmul_m3v3(&t, dir_xform);
+ for(j=0; j<cm->vattr[CMESH_ATTR_TANGENT].nelem; j++) {
+ *vptr++ = (&t.x)[j];
+ }
+ }
+ }
+ }
+}