/*! \pre m_transformed_vertex_buffer must be unlocked */ void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh) { if(gim_trimesh_has_tranformed_reply(trimesh) == 0) return; //Don't perform transformation //Vertices GBUFFER_ARRAY * psource_vertex_buffer = &trimesh->m_source_vertex_buffer; GBUFFER_ARRAY * ptransformed_vertex_buffer = &trimesh->m_transformed_vertex_buffer; //Temp transform mat4f transform; COPY_MATRIX_4X4(transform,trimesh->m_transform); GIM_PROCESS_BUFFER_ARRAY(transform,(*psource_vertex_buffer),(*ptransformed_vertex_buffer),MULT_MAT_VEC4_KERNEL,vec3f,vec3f); }
void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform) { GREAL diff = 0.0f; float * originaltrans = &trimesh->m_transform[0][0]; float * newtrans = &transform[0][0]; GUINT32 i; for (i=0;i<16;i++) { diff += fabs(originaltrans[i]-newtrans[i]); } // if(IS_ZERO(diff)) return ;///don't need to update if(diff< 0.00001f) return ;///don't need to update COPY_MATRIX_4X4(trimesh->m_transform,transform); gim_trimesh_post_update(trimesh); }
/* * The uviewdirection subroutine computes and returns a 4x4 rotation * matrix that puts the negative z axis along the direction v21 and * puts the y axis along the up vector. * * Note that this code is fairly tolerant of "weird" paramters. * It normalizes when necessary, it does nothing when vectors are of * zero length, or are co-linear. This code shouldn't croak, no matter * what the user sends in as arguments. */ void uview_direction (gleDouble m[4][4], /* returned */ gleDouble v21[3], /* input */ gleDouble up[3]) /* input */ { gleDouble amat[4][4]; gleDouble bmat[4][4]; gleDouble cmat[4][4]; gleDouble v_hat_21[3]; gleDouble v_xy[3]; gleDouble sine, cosine; gleDouble len; gleDouble up_proj[3]; gleDouble tmp[3]; /* find the unit vector that points in the v21 direction */ VEC_COPY (v_hat_21, v21); VEC_LENGTH (len, v_hat_21); if (len != 0.0) { len = 1.0 / len; VEC_SCALE (v_hat_21, len, v_hat_21); /* rotate z in the xz-plane until same latitude */ sine = sqrt ( 1.0 - v_hat_21[2] * v_hat_21[2]); ROTY_CS (amat, (-v_hat_21[2]), (-sine)); } else { /* error condition: zero length vecotr passed in -- do nothing */ IDENTIFY_MATRIX_4X4 (amat); } /* project v21 onto the xy plane */ v_xy[0] = v21[0]; v_xy[1] = v21[1]; v_xy[2] = 0.0; VEC_LENGTH (len, v_xy); /* rotate in the x-y plane until v21 lies on z axis --- * but of course, if its already there, do nothing */ if (len != 0.0) { /* want xy projection to be unit vector, so that sines/cosines pop out */ len = 1.0 / len; VEC_SCALE (v_xy, len, v_xy); /* rotate the projection of v21 in the xy-plane over to the x axis */ ROTZ_CS (bmat, v_xy[0], v_xy[1]); /* concatenate these together */ MATRIX_PRODUCT_4X4 (cmat, amat, bmat); } else { /* no-op -- vector is already in correct position */ COPY_MATRIX_4X4 (cmat, amat); } /* up vector really should be perpendicular to the x-form direction -- * Use up a couple of cycles, and make sure it is, * just in case the user blew it. */ VEC_PERP (up_proj, up, v_hat_21); VEC_LENGTH (len, up_proj); if (len != 0.0) { /* normalize the vector */ len = 1.0/len; VEC_SCALE (up_proj, len, up_proj); /* compare the up-vector to the y-axis to get the cosine of the angle */ tmp [0] = cmat [1][0]; tmp [1] = cmat [1][1]; tmp [2] = cmat [1][2]; VEC_DOT_PRODUCT (cosine, tmp, up_proj); /* compare the up-vector to the x-axis to get the sine of the angle */ tmp [0] = cmat [0][0]; tmp [1] = cmat [0][1]; tmp [2] = cmat [0][2]; VEC_DOT_PRODUCT (sine, tmp, up_proj); /* rotate to align the up vector with the y-axis */ ROTZ_CS (amat, cosine, -sine); /* This xform, although computed last, acts first */ MATRIX_PRODUCT_4X4 (m, amat, cmat); } else { /* error condition: up vector is indeterminate (zero length) * -- do nothing */ COPY_MATRIX_4X4 (m, cmat); } }