void TraverseVisibilitySensor(GF_Node *node, void *rs, Bool is_destroy) { GF_TraverseState *tr_state = (GF_TraverseState *)rs; M_VisibilitySensor *vs = (M_VisibilitySensor *)node; if (is_destroy || !vs->enabled) return; if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { /*work with twice bigger bbox to get sure we're notify when culled out*/ gf_vec_add(tr_state->bbox.max_edge, vs->center, vs->size); gf_vec_diff(tr_state->bbox.min_edge, vs->center, vs->size); gf_bbox_refresh(&tr_state->bbox); } else if (tr_state->traversing_mode==TRAVERSE_SORT) { Bool visible; u32 cull_flag; GF_BBox bbox; SFVec3f s; s = gf_vec_scale(vs->size, FIX_ONE/2); /*cull with normal bbox*/ gf_vec_add(bbox.max_edge, vs->center, s); gf_vec_diff(bbox.min_edge, vs->center, s); gf_bbox_refresh(&bbox); cull_flag = tr_state->cull_flag; tr_state->cull_flag = CULL_INTERSECTS; visible = visual_3d_node_cull(tr_state, &bbox, 0); tr_state->cull_flag = cull_flag; if (visible && !vs->isActive) { vs->isActive = 1; gf_node_event_out(node, 5/*"isActive"*/); vs->enterTime = gf_node_get_scene_time(node); gf_node_event_out(node, 3/*"enterTime"*/); } else if (!visible && vs->isActive) { vs->isActive = 0; gf_node_event_out(node, 5/*"isActive"*/); vs->exitTime = gf_node_get_scene_time(node); gf_node_event_out(node, 4/*"exitTime"*/); } } }
static void TraverseSpotLight(GF_Node *n, void *rs, Bool is_destroy) { M_SpotLight *sl = (M_SpotLight *)n; GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { Bool *vis = gf_node_get_private(n); gf_free(vis); return; } if (!sl->on) return; /*store local bounds for culling*/ if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { GF_BBox b; SFVec3f size; Bool *visible = gf_node_get_private(n); size.x = size.y = size.z = sl->radius; gf_vec_add(b.max_edge, sl->location, size); gf_vec_diff(b.min_edge, sl->location, size); gf_bbox_refresh(&b); *visible = visual_3d_node_cull(tr_state, &b, 0); /*if visible, disable culling on our parent branch - this is not very efficient but we only store one bound per grouping node, and we don't want the lights to interfere with it*/ if (*visible) tr_state->disable_cull = 1; return; } else if (tr_state->traversing_mode == TRAVERSE_LIGHTING) { Bool *visible = gf_node_get_private(n); if (*visible) { visual_3d_matrix_push(tr_state->visual); visual_3d_matrix_add(tr_state->visual, tr_state->model_matrix.m); visual_3d_add_spot_light(tr_state->visual, sl->ambientIntensity, sl->attenuation, sl->beamWidth, sl->color, sl->cutOffAngle, sl->direction, sl->intensity, sl->location); visual_3d_matrix_pop(tr_state->visual); } } }
static void TraversePointLight(GF_Node *n, void *rs, Bool is_destroy) { M_PointLight *pl = (M_PointLight *)n; GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { Bool *vis = gf_node_get_private(n); gf_free(vis); return; } if (!pl->on) return; /*store local bounds for culling*/ if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { SFVec3f size; GF_BBox b; Bool *visible = gf_node_get_private(n); size.x = size.y = size.z = pl->radius; gf_vec_add(b.max_edge, pl->location, size); gf_vec_diff(b.min_edge, pl->location, size); gf_bbox_refresh(&b); *visible = visual_3d_node_cull(tr_state, &b, 0); /*if visible, disable culling on our parent branch*/ if (*visible) tr_state->disable_cull = 1; return; } else if (tr_state->traversing_mode == TRAVERSE_LIGHTING) { Bool *visible = gf_node_get_private(n); if (*visible) { visual_3d_matrix_push(tr_state->visual); visual_3d_matrix_add(tr_state->visual, tr_state->model_matrix.m); visual_3d_add_point_light(tr_state->visual, pl->ambientIntensity, pl->attenuation, pl->color, pl->intensity, pl->location); visual_3d_matrix_pop(tr_state->visual); } } }