gboolean _cogl_matrix_stack_equal (CoglMatrixStack *stack0, CoglMatrixStack *stack1) { CoglMatrixState *state0 = _cogl_matrix_stack_top (stack0); CoglMatrixState *state1 = _cogl_matrix_stack_top (stack1); if (state0->is_identity != state1->is_identity) return FALSE; if (state0->is_identity) return TRUE; else return cogl_matrix_equal (&state0->matrix, &state1->matrix); }
CoglBool cogl_matrix_entry_equal (CoglMatrixEntry *entry0, CoglMatrixEntry *entry1) { for (; entry0 && entry1; entry0 = entry0->parent, entry1 = entry1->parent) { entry0 = _cogl_matrix_entry_skip_saves (entry0); entry1 = _cogl_matrix_entry_skip_saves (entry1); if (entry0 == entry1) return TRUE; if (entry0->op != entry1->op) return FALSE; switch (entry0->op) { case COGL_MATRIX_OP_LOAD_IDENTITY: return TRUE; case COGL_MATRIX_OP_TRANSLATE: { CoglMatrixEntryTranslate *translate0 = (CoglMatrixEntryTranslate *)entry0; CoglMatrixEntryTranslate *translate1 = (CoglMatrixEntryTranslate *)entry1; /* We could perhaps use an epsilon to compare here? * I expect the false negatives are probaly never going to * be a problem and this is a bit cheaper. */ if (translate0->x != translate1->x || translate0->y != translate1->y || translate0->z != translate1->z) return FALSE; } break; case COGL_MATRIX_OP_ROTATE: { CoglMatrixEntryRotate *rotate0 = (CoglMatrixEntryRotate *)entry0; CoglMatrixEntryRotate *rotate1 = (CoglMatrixEntryRotate *)entry1; if (rotate0->angle != rotate1->angle || rotate0->x != rotate1->x || rotate0->y != rotate1->y || rotate0->z != rotate1->z) return FALSE; } break; case COGL_MATRIX_OP_ROTATE_QUATERNION: { CoglMatrixEntryRotateQuaternion *rotate0 = (CoglMatrixEntryRotateQuaternion *)entry0; CoglMatrixEntryRotateQuaternion *rotate1 = (CoglMatrixEntryRotateQuaternion *)entry1; int i; for (i = 0; i < 4; i++) if (rotate0->values[i] != rotate1->values[i]) return FALSE; } break; case COGL_MATRIX_OP_ROTATE_EULER: { CoglMatrixEntryRotateEuler *rotate0 = (CoglMatrixEntryRotateEuler *)entry0; CoglMatrixEntryRotateEuler *rotate1 = (CoglMatrixEntryRotateEuler *)entry1; if (rotate0->heading != rotate1->heading || rotate0->pitch != rotate1->pitch || rotate0->roll != rotate1->roll) return FALSE; } break; case COGL_MATRIX_OP_SCALE: { CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0; CoglMatrixEntryScale *scale1 = (CoglMatrixEntryScale *)entry1; if (scale0->x != scale1->x || scale0->y != scale1->y || scale0->z != scale1->z) return FALSE; } break; case COGL_MATRIX_OP_MULTIPLY: { CoglMatrixEntryMultiply *mult0 = (CoglMatrixEntryMultiply *)entry0; CoglMatrixEntryMultiply *mult1 = (CoglMatrixEntryMultiply *)entry1; if (!cogl_matrix_equal (mult0->matrix, mult1->matrix)) return FALSE; } break; case COGL_MATRIX_OP_LOAD: { CoglMatrixEntryLoad *load0 = (CoglMatrixEntryLoad *)entry0; CoglMatrixEntryLoad *load1 = (CoglMatrixEntryLoad *)entry1; /* There's no need to check any further since an * _OP_LOAD makes all the ancestors redundant as far as * the final matrix value is concerned. */ return cogl_matrix_equal (load0->matrix, load1->matrix); } case COGL_MATRIX_OP_SAVE: /* We skip over saves above so we shouldn't see save entries */ g_warn_if_reached (); } } return FALSE; }