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); }
/** * Attempt to spread the obj from the given contact from the source subspace * and into the (relative) back subsapce. * * @param subspace Convex subspace to attempt to spread over to. * * @return Always @c true. (This function is also used as an iterator.) */ void spreadInSubspace(ConvexSubspace &subspace) { HEdge *base = subspace.poly().hedge(); HEdge *hedge = base; do { maybeSpreadOverEdge(hedge); } while((hedge = &hedge->next()) != base); }
/** * @return @c true if the ray passes @a bspLeaf; otherwise @c false. */ bool crossBspLeaf(BspLeaf const &bspLeaf) { if(!bspLeaf.hasSubspace()) return false; ConvexSubspace const &subspace = bspLeaf.subspace(); // Check polyobj lines. LoopResult blocked = subspace.forAllPolyobjs([this] (Polyobj &pob) { for(Line *line : pob.lines()) { if(!crossLine(line->front())) return LoopAbort; } return LoopContinue; }); if(blocked) return false; // Check lines for the edges of the subspace geometry. HEdge *base = subspace.poly().hedge(); HEdge *hedge = base; do { if(hedge->hasMapElement()) { if(!crossLine(hedge->mapElementAs<LineSideSegment>().lineSide())) return false; } } while((hedge = &hedge->next()) != base); // Check lines for the extra meshes. blocked = subspace.forAllExtraMeshes([this] (Mesh &mesh) { for(HEdge *hedge : mesh.hedges()) { // Is this on the back of a one-sided line? if(!hedge->hasMapElement()) continue; if(!crossLine(hedge->mapElementAs<LineSideSegment>().lineSide())) return LoopAbort; } return LoopContinue; }); return !blocked; }