static void drawSubspace(ConvexSubspace const &subspace) { float const scale = de::max(bmapDebugSize, 1.f); float const width = (DENG_GAMEVIEW_WIDTH / 16) / scale; Face const &poly = subspace.poly(); HEdge *base = poly.hedge(); HEdge *hedge = base; do { Vector2d start = hedge->origin(); Vector2d end = hedge->twin().origin(); glBegin(GL_LINES); glVertex2f(start.x, start.y); glVertex2f(end.x, end.y); glEnd(); ddouble length = (end - start).length(); if(length > 0) { Vector2d const unit = (end - start) / length; Vector2d const normal(-unit.y, unit.x); GL_BindTextureUnmanaged(GL_PrepareLSTexture(LST_DYNAMIC)); glEnable(GL_TEXTURE_2D); GL_BlendMode(BM_ADD); glBegin(GL_QUADS); glTexCoord2f(0.75f, 0.5f); glVertex2f(start.x, start.y); glTexCoord2f(0.75f, 0.5f); glVertex2f(end.x, end.y); glTexCoord2f(0.75f, 1); glVertex2f(end.x - normal.x * width, end.y - normal.y * width); glTexCoord2f(0.75f, 1); glVertex2f(start.x - normal.x * width, start.y - normal.y * width); glEnd(); glDisable(GL_TEXTURE_2D); GL_BlendMode(BM_NORMAL); } // Draw a bounding box for the leaf's face geometry. start = Vector2d(poly.aaBox().minX, poly.aaBox().minY); end = Vector2d(poly.aaBox().maxX, poly.aaBox().maxY); glBegin(GL_LINES); glVertex2f(start.x, start.y); glVertex2f( end.x, start.y); glVertex2f( end.x, start.y); glVertex2f( end.x, end.y); glVertex2f( end.x, end.y); glVertex2f(start.x, end.y); glVertex2f(start.x, end.y); glVertex2f(start.x, start.y); glEnd(); } while((hedge = &hedge->next()) != base); }
/** * On which side of the half-edge does the specified @a point lie? * * @param hedge Half-edge to test. * @param point Point to test in the map coordinate space. * * @return @c <0 Point is to the left/back of the segment. * @c =0 Point lies directly on the segment. * @c >0 Point is to the right/front of the segment. */ static coord_t pointOnHEdgeSide(HEdge const &hedge, Vector2d const &point) { Vector2d const direction = hedge.twin().origin() - hedge.origin(); ddouble pointV1[2] = { point.x, point.y }; ddouble fromOriginV1[2] = { hedge.origin().x, hedge.origin().y }; ddouble directionV1[2] = { direction.x, direction.y }; return V2d_PointOnLineSide(pointV1, fromOriginV1, directionV1); }
void buildSubspaceGeometries() { for(ConvexSubspaceProxy const &subspace : subspaces) { /// @todo Move BSP leaf construction here? BspLeaf &bspLeaf = *subspace.bspLeaf(); subspace.buildGeometry(bspLeaf, *mesh); // Account the new segments. /// @todo Refactor away. for(OrderedSegment const &oseg : subspace.segments()) { if(oseg.segment->hasHEdge()) { // There is now one more line segment. segmentCount += 1; } } } /* * Finalize the built geometry by adding a twin half-edge for any * which don't yet have one. */ for(ConvexSubspaceProxy const &convexSet : subspaces) for(OrderedSegment const &oseg : convexSet.segments()) { LineSegmentSide *seg = oseg.segment; if(seg->hasHEdge() && !seg->back().hasHEdge()) { HEdge *hedge = &seg->hedge(); DENG2_ASSERT(!hedge->hasTwin()); // Allocate the twin from the same mesh. hedge->setTwin(hedge->mesh().newHEdge(seg->back().from())); hedge->twin().setTwin(hedge); } } }