/* pushpull.c: push/pull operations */ #include "error.h" #include "element.h" #define RegularChild(child) (child->child_nr >= 0 && child->child_nr <= 3) void PushRadiance(ELEMENT *parent, ELEMENT *child, COLOR *parent_rad, COLOR *child_rad) { if (parent->iscluster || child->basis->size == 1) { COLORADD(child_rad[0], parent_rad[0], child_rad[0]); } else if (RegularChild(child) && child->basis==parent->basis) { FilterColorDown(parent_rad, &(*child->basis->regular_filter)[child->child_nr], child_rad, child->basis->size); } else { Fatal(-1, "PushRadiance", "Not implemented for higher order approximations on irregular child elements or for different parent and child basis"); } } void PushImportance(ELEMENT *parent, ELEMENT *child, float *parent_imp, float *child_imp) { *child_imp += *parent_imp; } void PullRadiance(ELEMENT *parent, ELEMENT *child, COLOR *parent_rad, COLOR *child_rad) { float areafactor = child->area/parent->area; if (parent->iscluster || child->basis->size == 1) { COLORADDSCALED(parent_rad[0], areafactor, child_rad[0], parent_rad[0]); } else if (RegularChild(child) && child->basis==parent->basis) { FilterColorUp(child_rad, &(*child->basis->regular_filter)[child->child_nr], parent_rad, child->basis->size, areafactor); } else { Fatal(-1, "PullRadiance", "Not implemented for higher order approximations on irregular child elements or for different parent and child basis"); } } void PullImportance(ELEMENT *parent, ELEMENT *child, float *parent_imp, float *child_imp) { *parent_imp += child->area/parent->area * (*child_imp); }