void QtDrawing3d::DrawSence(const bsp_node *tree, QPainter *painter) { polygon3d_node *pn; std::stack<polygon3d_node *> drawingStack; const bsp_node *nxt = tree; if (bsp_empty(tree)) { return; } pn = (polygon3d_node *)head_node(&tree->polygons); side_eye = point3d_classify_poly(&eye, &pn->polygon3d); //drawingStack.push(pn); //while(!drawingStack.empty()) { // if (nxt->front) { // pn = (polygon3d_node *)head_node(&(tree->front)->polygons); // nxt = tree->front; // } //} if (side_eye > 0) { DrawSence(tree->back, painter); DrawPolygon(tree, painter); DrawSence(tree->front, painter); } else if (side_eye < 0){ DrawSence(tree->front, painter); DrawPolygon(tree, painter); DrawSence(tree->back, painter); } else { DrawSence(tree->back, painter); DrawSence(tree->front, painter); } }
/****************************************************************************** ** Name: bsp_clear ** Params: ** Return: ** Descriptions: ** Clear all polygon in tree *******************************************************************************/ son_bool_t bsp_clear(bsp_node *tree) { bsp_node *nxt = tree; polygon3d_node *pol_node, *tmp; unsigned short n, i; if (NULL == nxt || nxt->polygons.count == 0) return son_FALSE; bsp_clear(nxt->back); bsp_clear(nxt->front); n = nxt->polygons.count; pol_node = (polygon3d_node *)head_node(&nxt->polygons); for (i = 1; i < n; ++i) { tmp = pol_node; pol_node = \ (polygon3d_node *)next_node(&nxt->polygons, (node2 *)pol_node); polygon3d_clear(&tmp->polygon3d); free(tmp); nxt->polygons.count--; } polygon3d_clear(&pol_node->polygon3d); nxt->polygons.count--; free(pol_node); free(tree); return son_TRUE; }
void QtDrawing3d::DrawSence(QPainter *painter) { if (bsp_empty(s_world)) return; polygon3d_node * pn = (polygon3d_node *)head_node(&s_world->polygons); side_eye = point3d_classify_poly(&eye, &pn->polygon3d); DrawSence(s_world, painter); }
ListNode *swapPairs(ListNode *head) { ListNode head_node(0); head_node.next = head; ListNode *p = &head_node, *q; while (p->next && p->next->next) { q = p->next->next; p->next->next = q->next; q->next = p->next; p->next = q; p = q->next; } return head_node.next; }
void QtDrawing3d::DrawPolygon(const bsp_node *tree, QPainter *painter) { if (!tree) return; polygon3d_node *pn; unsigned short n_pol = tree->polygons.count; son_point3d_t points[MAX_POINT_PER_POLY]; unsigned short i,j; son_point3d_t prjPnt[MAX_POINT_PER_POLY]; static int colorflag = 0; double shade; QPainterPath path; son_point3d_t mv; pn = (polygon3d_node *)head_node(&tree->polygons); for (j = 0; j < n_pol; j++) { polygon3d_get_points(&pn->polygon3d, points); matrix4_mult_vector(&m_modelViewMatrix, &points[0], &mv); proj_point_2_plane(&mv, &m_n, &m_p, &prjPnt[0]); path.moveTo(prjPnt[0].v[0], prjPnt[0].v[1]); for (i = 1; i < pn->polygon3d.n_ver; ++i) { matrix4_mult_vector(&m_modelViewMatrix, &points[i], &mv); proj_point_2_plane(&mv, &m_n, &m_p, &prjPnt[i]); path.lineTo(prjPnt[i].v[0], prjPnt[i].v[1]); } path.closeSubpath(); shade = ComputeLight(&pn->polygon3d); m_color = QColor(pn->polygon3d.color[0] * shade, pn->polygon3d.color[1] * shade, pn->polygon3d.color[2] * shade); painter->fillPath(path, QBrush(m_color)); pn = (polygon3d_node *)next_node(&tree->polygons, (node2 *)pn); } }
/****************************************************************************** ** Name: bsp_add ** Params: ** Return: ** Descriptions: ** Add one node to the tree *******************************************************************************/ son_bool_t bsp_add(bsp_node **tree, const son_polygon3d_t *polygon) { son_bool_t rc = son_FALSE; polygon3d_node *poly_node; bsp_node *n; classi_poly_plane_t classi; son_polygon3d_t front, back; node2 *h_poly; polygon3d_init(&front); polygon3d_init(&back); memcpy(front.color, polygon->color, sizeof(polygon->color)); memcpy(back.color, polygon->color, sizeof(polygon->color)); if (son_TRUE == bsp_empty(*tree)) { if (NULL == *tree) { *tree = (bsp_node *)malloc(sizeof(bsp_node)); bsp_init(*tree); } poly_node = (polygon3d_node *)malloc(sizeof(polygon3d_node)); polygon3d_init(&poly_node->polygon3d); polygon3d_cpy(polygon, &poly_node->polygon3d); add_2_tail(&(*tree)->polygons, (node2*)(poly_node)); } else { h_poly = head_node(&(*tree)->polygons); rc = polygon3d_classify(&((polygon3d_node *)h_poly)->polygon3d, polygon, &classi, &front, &back); switch (classi) { case CLASSI_POLY_BACK: bsp_add(&((*tree)->back), &back); break; case CLASSI_POLY_FRONT: bsp_add(&(*tree)->front, &front); break; case CLASSI_POLY_COINCIDE: { poly_node = (polygon3d_node *)malloc(sizeof(polygon3d_node)); polygon3d_init(&poly_node->polygon3d); rc = polygon3d_cpy(polygon, &poly_node->polygon3d); add_2_tail(&(*tree)->polygons, (node2*)(poly_node)); } break; case CLASSI_POLY_SPANNING: { if (front.n_ver) { bsp_add(&(*tree)->front, &front); } if (back.n_ver) { bsp_add(&(*tree)->back, &back); } } break; case CLASSI_POLY_UNKNOWN: default: break; } if (front.n_ver) polygon3d_clear(&front); if (back.n_ver) polygon3d_clear(&back); } return rc; }