Node* TreeBARSub(Tree* aTree, Node* curnode, int which, int index) { Node* sibling = curnode->parent->child[which]; if (isRed(sibling)) { sibling->red = 0; curnode->parent->red = 1; TreeRotate(aTree, curnode->parent, !which, index); sibling = curnode->parent->child[which]; } if (!sibling) curnode = curnode->parent; else if (isBlack(sibling->child[!which]) && isBlack(sibling->child[which])) { sibling->red = 1; curnode = curnode->parent; } else { if (isBlack(sibling->child[which])) { sibling->child[!which]->red = 0; sibling->red = 1; TreeRotate(aTree, sibling, which, index); sibling = curnode->parent->child[which]; } sibling->red = curnode->parent->red; curnode->parent->red = 0; sibling->child[which]->red = 0; TreeRotate(aTree, curnode->parent, !which, index); curnode = aTree->index[index].root; } return curnode; }
void remedyDoubleBlack(const BTPosition& r) { // fix double-black r BTPosition x, y, z; x = BST::T.parent(r); y = BST::T.sibling(r); if (isBlack(y)) { if (hasRedChild(y)) { // Case 1: restructuring z = redChild(y); Color oldColor = color(x); // save top vertex color z = BST::T.restructure(z); // restructure x,y,z setColor(z, oldColor); setBlack(r); // fix colors setBlack(BST::T.leftChild(z)); setBlack(BST::T.rightChild(z)); } else { // Case 2: recoloring setBlack(r); setRed(y); // r=black, y=red if (isBlack(x) && !BST::T.isRoot(x)) remedyDoubleBlack(x); // fix double-black x setBlack(x); } } else { // Case 3: adjustment if (y == BST::T.rightChild(x)) z = BST::T.rightChild(y); // z is the grandchild else z = BST::T.leftChild(y); // ...on same side as y BST::T.restructure(z); // restructure x,y,z setBlack(y); setRed(x); // y=black, x=red remedyDoubleBlack(r); // fix by Case 1 or 2 } }
bool Map::IsPassible(QRect rect) { if(rect.center().x() > 1024 || rect.center().x() < 0 || rect.center().y() > 768 || rect.center().y() < 0) return true; //bottom for(int x = rect.left(); x < rect.right(); x++) { if(isBlack(x,rect.bottom())) return false; } //top for(int x = rect.left(); x < rect.right(); x++) { if(isBlack(x,rect.top())) return false; }\ //left for(int y = rect.top(); y < rect.bottom(); y++) { if(isBlack(rect.left(),y)) return false; } //right for(int y = rect.top(); y < rect.bottom(); y++) { if(isBlack(rect.right(),y)) return false; } return true; }
bool RBTree<T>::remove(T key) { bool found = true; pTreeNode<pair<bool, T> >* foundNode = BinSearch(key, this->root); // if the tree is empty or the data is not found if (!(foundNode && foundNode->getData() == key)) { found = false; } else // remove by successor { pTreeNode<pair<bool, T> >* heir = successor(foundNode); pTreeNode<pair<bool, T> >* child = NULL == heir->right ? heir->left : heir->right; pTreeNode<pair<bool, T> >* parent = heir->parent; bool childIsLeft = true; foundNode->injectData(heir->getData()); // detach child from heir (if child exists) if (NULL != child) // at least 1 child { child->parent = parent; } if (NULL == parent) // if heir is the root { this->root = child; if (NULL != this->root) { isBlack(this->root) = true; } } else { childIsLeft = heir == parent->left; if (true == childIsLeft) { parent->left = child; } else { parent->right = child; } if (true == isBlack(heir)) { // child could be null, so parent is passed in deleteFixUp(parent, childIsLeft); } } delete heir; } return found; }
// Hough Transformation void ImageDeskew::calc() { int hMin = (int) ((cImage.size().height) / 4.0); int hMax = (int) ((cImage.size().height) * 3.0 / 4.0); for (int y = hMin; y < hMax; y++) { for (int x = 1; x < (cImage.size().width - 2); x++) { // only lower edges are considered if (isBlack(x, y)) { if (!isBlack(x, y + 1)) { calc(x, y); } } } } }
void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, struct NVGcolor col) { struct NVGpaint bg; char icon[8]; float cornerRadius = 4.0f; float tw = 0, iw = 0; bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,isBlack(col)?16:32), nvgRGBA(0,0,0,isBlack(col)?16:32) ); nvgBeginPath(vg); nvgRoundedRect(vg, x+1,y+1, w-2,h-2, cornerRadius-1); if (!isBlack(col) ) { nvgFillColor(vg, col); nvgFill(vg); } nvgFillPaint(vg, bg); nvgFill(vg); nvgBeginPath(vg); nvgRoundedRect(vg, x+0.5f,y+0.5f, w-1,h-1, cornerRadius-0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,48) ); nvgStroke(vg); nvgFontSize(vg, 20.0f); nvgFontFace(vg, "sans-bold"); tw = nvgTextBounds(vg, 0,0, text, NULL, NULL); if (preicon != 0) { nvgFontSize(vg, h*1.3f); nvgFontFace(vg, "icons"); iw = nvgTextBounds(vg, 0,0, cpToUTF8(preicon,icon), NULL, NULL); iw += h*0.15f; } if (preicon != 0) { nvgFontSize(vg, h*1.3f); nvgFontFace(vg, "icons"); nvgFillColor(vg, nvgRGBA(255,255,255,96) ); nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); nvgText(vg, x+w*0.5f-tw*0.5f-iw*0.75f, y+h*0.5f, cpToUTF8(preicon,icon), NULL); } nvgFontSize(vg, 20.0f); nvgFontFace(vg, "sans-bold"); nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); nvgFillColor(vg, nvgRGBA(0,0,0,160) ); nvgText(vg, x+w*0.5f-tw*0.5f+iw*0.25f,y+h*0.5f-1,text, NULL); nvgFillColor(vg, nvgRGBA(255,255,255,160) ); nvgText(vg, x+w*0.5f-tw*0.5f+iw*0.25f,y+h*0.5f,text, NULL); }
//移动一个棋子严格到(fx,fy)-(jx,jy)线段上,以达到将军或者躲将的目的 void MoveToFuckOrAvoid::Segment:: F**k(int id, bool red, int fx, int fy, int jx, int jy){ //red表示当前是走红还是走黑,(fx, fy)表示车,(jx, jy)表示将 string str = red? "JCMPXSB" : "jcmpxsb"; for(int i = 0; i < nrow; i++){ for(int j = 0; j < ncol; j++){ if(!red && !isBlack(id, i, j)) continue; else if(red && !isRed(id, i, j)) continue; char c = d[id].At(i, j); int dx[5], dy[5], n = 0; if(c == str[1]) Che_segment(id, i, j, fx, fy, jx, jy, dx, dy, n); else if(c == str[2]) Ma_segment(id, i, j, fx, fy, jx, jy, dx, dy, n); else if(c == str[3]) Che_segment(id, i, j, fx, fy, jx, jy, dx, dy, n);//没错 else if(c == str[4]) Xiang_segment(id, i, j, fx, fy, jx, jy, dx, dy, n); else if(c == str[5]) Shi_segment(id, i, j, fx, fy, jx, jy, dx, dy, n); else if(c == str[6]) Bin_segment(id, red, i, j, fx, fy, jx, jy, dx, dy, n); for(int k = 0; k < n; k++){ if(d[id].At(dx[k], dy[k]) != '_') continue; if(red) Newd(id, fx, fy, i, j, dx[k], dy[k]); else Newd(id, -1, -1, i, j, dx[k], dy[k]); Filter(red); } } } }
Score Evaluator::calculateMaterialScore(const Position& position) const { Score score = Score::zero(); auto& blackHand = position.getBlackHand(); score += material::Pawn * blackHand.get(PieceType::pawn ()); score += material::Lance * blackHand.get(PieceType::lance ()); score += material::Knight * blackHand.get(PieceType::knight()); score += material::Silver * blackHand.get(PieceType::silver()); score += material::Gold * blackHand.get(PieceType::gold ()); score += material::Bishop * blackHand.get(PieceType::bishop()); score += material::Rook * blackHand.get(PieceType::rook ()); auto& whiteHand = position.getWhiteHand(); score -= material::Pawn * whiteHand.get(PieceType::pawn ()); score -= material::Lance * whiteHand.get(PieceType::lance ()); score -= material::Knight * whiteHand.get(PieceType::knight()); score -= material::Silver * whiteHand.get(PieceType::silver()); score -= material::Gold * whiteHand.get(PieceType::gold ()); score -= material::Bishop * whiteHand.get(PieceType::bishop()); score -= material::Rook * whiteHand.get(PieceType::rook ()); Bitboard occ = nosseOr(position.getBOccupiedBitboard(), position.getWOccupiedBitboard()); occ.unset(position.getBlackKingSquare()); occ.unset(position.getWhiteKingSquare()); BB_EACH(square, occ) { auto piece = position.getPieceOnBoard(square); if (piece.isBlack()) { score += material::score(piece); } else { score -= material::score(piece); } }
/** * Remove an item from a tree * @param aTree the list to which the item is to be added * @param curnode the list item content itself */ void* TreeRemoveNodeIndex(Tree* aTree, Node* curnode, int index) { Node* redundant = curnode; Node* curchild = NULL; int size = curnode->size; void* content = curnode->content; /* if the node to remove has 0 or 1 children, it can be removed without involving another node */ if (curnode->child[LEFT] && curnode->child[RIGHT]) /* 2 children */ redundant = TreeSuccessor(curnode); /* now redundant must have at most one child */ curchild = redundant->child[(redundant->child[LEFT] != NULL) ? LEFT : RIGHT]; if (curchild) /* we could have no children at all */ curchild->parent = redundant->parent; if (redundant->parent == NULL) aTree->index[index].root = curchild; else { if (redundant == redundant->parent->child[LEFT]) redundant->parent->child[LEFT] = curchild; else redundant->parent->child[RIGHT] = curchild; } if (redundant != curnode) { curnode->content = redundant->content; curnode->size = redundant->size; } if (isBlack(redundant)) { if (curchild == NULL) { if (redundant->parent) { Node temp; memset(&temp, '\0', sizeof(Node)); temp.parent = (redundant) ? redundant->parent : NULL; temp.red = 0; TreeBalanceAfterRemove(aTree, &temp, index); } } else TreeBalanceAfterRemove(aTree, curchild, index); } #if defined(UNIT_TESTS) free(redundant); #else (aTree->heap_tracking) ? myfree(__FILE__, __LINE__, redundant) : free(redundant); #endif if (index == 0) { aTree->size -= size; --(aTree->count); } return content; }
void test_isBlack_given_NULL_should_return_1(void) { int result; Node *root = NULL; result = isBlack(&root); TEST_ASSERT_EQUAL(1, result); }
bool Map::ManageBulletCollision(QRect rect, double radius) { if(rect.center().x() > 1024 || rect.center().x() < 0 || rect.center().y() > 768 || rect.center().y() < 0) return true; //bottom for(int x = rect.left(); x < rect.right(); x++) { if(isBlack(x,rect.bottom())) { Explode(rect.center().x(),rect.bottom(),radius); return false; } } //top for(int x = rect.left(); x < rect.right(); x++) { if(isBlack(x,rect.top())) { Explode(rect.center().x(),rect.top(),radius); return false; } }\ //left for(int y = rect.top(); y < rect.bottom(); y++) { if(isBlack(rect.left(),y)) { Explode(rect.left(),rect.center().y(),radius); return false; } } //right for(int y = rect.top(); y < rect.bottom(); y++) { if(isBlack(rect.right(),y)) { Explode(rect.right(),rect.center().y(),radius); return false; } } return true; }
void remedyDoubleRed(const BTPosition& z) { // fix double-red z BTPosition v = BST::T.parent(z); // v is z's parent if (BST::T.isRoot(v) || isBlack(v)) return; // v is black, all ok // z, v are double-red if (isBlack(BST::T.sibling(v))) { // Case 1: restructuring v = BST::T.restructure(z); setBlack(v); // top vertex now black setRed(BST::T.leftChild(v)); setRed(BST::T.rightChild(v)); // children are red } else { // Case 2: recoloring setBlack(v); // make v black setBlack(BST::T.sibling(v)); // ..and its sibling BTPosition u = BST::T.parent(v); // u is v's parent if (BST::T.isRoot(u)) return; setRed(u); // make u red remedyDoubleRed(u); // may need to fix u now } }
//移动黑将,躲避将军 void TurnBlack::Move_j(int id, int jx, int jy){ for(int k = 0; k < 4; k++){ int zx = jx + JiangX[k], zy = jy + JiangY[k]; if(!Jiang_object(id, jx, jy, zx, zy)) continue; if(isBlack(id, zx, zy)) continue; Newd(id, -1, -1, jx, jy, zx, zy); Filter(false); } }
/*Determine if given Board Char matches Color*/ int sameCol(char c, Color col){ if (isBlack(c) && col == BLACK){ return 1; } if (isWhite(c) && col == WHITE){ return 1; } return 0; }
void test_isBlack_given_a_node_with_red_color_should_return_0(void) { int result; setNode(&node2, NULL, NULL, 'r'); Node *root = &node2; result = isBlack(&root); TEST_ASSERT_EQUAL(0, result); }
int createPath(const RTScene& scene, Rand& rand, int maxVerts, const float3& initialAlpha, const Ray& initialRay, bool includeLightIntersections, PathVertex vertices[]) { int numVerts = 0; Ray ray = initialRay; float3 alpha = initialAlpha; for(int i = 0; i < maxVerts; i++) { float3 woWorld = -ray.dir; IntersectionQuery query(ray); Intersection isect; Intersection lightIsect; intersectScene(scene, query, &isect, &lightIsect); if(hitLightFirst(isect, lightIsect)) { if(includeLightIntersections) { vertices[i] = PathVertex(lightIsect.normal, woWorld, lightIsect.position, lightIsect.material, alpha); return numVerts + 1; } else { return numVerts; } } if(!isect.hit) break; else numVerts++; vertices[i] = PathVertex(isect.normal, woWorld, isect.position, isect.material, alpha); if(i == (maxVerts - 1)) break; ShadingCS isectShadingCS(isect.normal); float3 wi; float3 weight; isect.material->sample(isectShadingCS.local(woWorld), rand.next01f2(), &wi, &weight); if(isBlack(weight)) { break; } float3 wiWorld = isectShadingCS.world(wi); ray.origin = isect.position; ray.dir = wiWorld; alpha *= weight; } return numVerts; }
/*Determine if given Board Char is opposed to given Location*/ int isOpposite(char c, char board[BOARD_SIZE][BOARD_SIZE], Location *loc){ Color col = getColFromLoc(board, loc); if (col == WHITE){ return isBlack(c); } if (col == BLACK){ return isWhite(c); } return 0; }
void TreeBalanceAfterRemove(Tree* aTree, Node* curnode, int index) { while (curnode != aTree->index[index].root && isBlack(curnode)) { /* curnode->content == NULL must equal curnode == NULL */ if (((curnode->content) ? curnode : NULL) == curnode->parent->child[LEFT]) curnode = TreeBARSub(aTree, curnode, RIGHT, index); else curnode = TreeBARSub(aTree, curnode, LEFT, index); } curnode->red = 0; }
char Chessboard::getColor(char row, char col) const { checkForValidRow(row); checkForValidCol(col); if (isWhite(row, col)) { return WHITE_PIECE; } if (isBlack(row, col)) { return BLACK_PIECE; } return OPEN_SQUARE; }
bool ImageDeskew::isBlack(int x, int y) { // for black/white binary image, if pixel value equals 0, then black if (cBinary) { uint8_t* pixelPtr = (uint8_t*)cImage.data; int pixelValue = pixelPtr[y * cImage.cols * cImage.channels() + x * cImage.channels() + 0]; if (pixelValue == 0) { return true; } else { return false; } } int luminanceValue = 140; return isBlack(x, y, luminanceValue); }
void qtauPiano::paintEvent(QPaintEvent *event) { //FIXME: all notes are redrawn -- TODO @ add transpose support //do not hardcode minimum and maximum notes QVector<QRect> whites; QVector<QRect> blacks; double pixels_per_semitone = _ns.octHeight/12.0; int basenote = (_ns.baseOctave+_ns.numOctaves)*12-1;//basenote is a B in a flipped geometry for(int i=_ns.baseOctave*12;i<=basenote;i++) { int w = this->width(); QRect r(0,(basenote-i)*pixels_per_semitone,w,pixels_per_semitone); //gray for thirds ?? (as in rosegarden) if(isBlack(i)) blacks.append(r); else whites.append(r); //TODO only visible keys } QPainter p(this); p.translate(-_offset); p.setBrush(Qt::white); p.drawRects(whites); p.setBrush(QColor(cdef_color_black_key_bg)); p.drawRects(blacks); for(int i=12;i<96;i++) { int w = this->width(); QRect r(0,(95-i)*pixels_per_semitone,w,pixels_per_semitone); if(i%12==0) //draw hover notename (transposed) { int oct = i/12-2; p.drawText(r,"C"+QVariant(oct).toString());//TODO -- allow transpose } } }
bool SuperShader::Component::similarTo(const Component& other) const{ // Black and white are only similar to themselves if (isBlack()) { return other.isBlack(); } else if (other.isBlack()) { return false; } if (isWhite()) { return other.isWhite(); } else if (other.isWhite()) { return false; } // Two components are similar if they both have/do not have texture // maps. return map.isNull() == other.map.isNull(); }
void CamCapture::showSegmentation() { CvScalar pixel; for (int x = 0; x < width_var; ++x) { for (int y = 0; y < height_var; ++y) { if(isRed(x,y)) { setPixel3C(pixel,0,0,255); } else if(isBlue(x, y)) { setPixel3C(pixel,255,0,0); } else if(isYellow(x, y)) { setPixel3C(pixel,0,255,255); } else if(isGreen(x, y)) { setPixel3C(pixel,0,255,0); } else if(isWhite(x, y)) { setPixel3C(pixel, 255, 255, 255); } else if(isBlack(x, y)) { setPixel3C(pixel, 127, 127, 127); } else { setPixel3C(pixel,0,0,0); } cvSet2D(showSeg, y, x, pixel); } } }
//尝试吃掉危险红棋子 void TurnBlack::Eat_fucker(int id, int fx, int fy){ string str = "jcmpxsb"; for(int i = 0; i < nrow; i++){ for(int j = 0; j < ncol; j++){ if(!isBlack(id, i, j)) continue; char c = d[id].At(i, j); int t = -1; if(c == str[0] && Jiang_object(id, i, j, fx, fy)) t = 0; else if(c == str[1] && Che_object(id, i, j, fx, fy)) t = 1; else if(c == str[2] && Ma_object(id, i, j, fx, fy)) t = 2; else if(c == str[3] && Pao_object(id, i, j, fx, fy)) t = 3; else if(c == str[3] && d[id].At(fx, fy) == '_' && Che_object(id, i, j, fx, fy)) t = -3;//有用 else if(c == str[4] && Xiang_object(id, i, j, fx, fy)) t = 4; else if(c == str[5] && Shi_object(id, i, j, fx, fy)) t = 5; else if(c == str[6] && Bin_object(id, false, i, j, fx, fy)) t = 6; else continue; Newd(id, -1, -1, i, j, fx, fy); Filter(false); } } }
bool RBTree<T>::insert(T key) { bool unique = true; bool childIsLeft = false; // find primary insertion place: // NULL -> empty tree, // data = key -> duplicate, // data > key -> left is NULL -> child is left, // data < key -> right is NULL -> child is right, pTreeNode<pair<bool, T> >* topNode = BinSearch(key, this->root); // Insert to empty tree if (NULL == topNode) { this->root = new pTreeNode<pair<bool, T> >(pair<bool, T>(true, key)); } else if (topNode->getData() == key) { topNode->injectData(key); unique = false; } else { // this Node is red and has parent set to insertAfter pTreeNode<pair<bool, T> >* child = new pTreeNode<pair<bool, T> >(pair<bool, T>(false, key)); bool parentIsLeft = false; child->parent = topNode; childIsLeft = topNode->getData() > key; if (true == childIsLeft) { topNode->left = child; } else { topNode->right = child; } // maintain RedBlack properties // note: grandparent is black in loop, since parent is red while (NULL != child->parent && false == isBlack(child->parent)) { // due to iteration, topNode is not yet // guaranteed to be child's parent parentIsLeft = child->parent == child->parent->parent->left; // make topNode the uncle of the child topNode = parentIsLeft ? child->parent->parent->right : child->parent->parent->left; // case 1: uncle is red if (NULL != topNode && false == isBlack(topNode)) { isBlack(child->parent) = isBlack(topNode) = true; isBlack(topNode->parent) = false; // Move up to the grandparent child = topNode->parent; childIsLeft = (this->root != child && child->parent->left == child); } else // uncle is a black Node or nil { // case 2: parent and child orientation are not aligned // rotate parent, stay at the same level (the parent becometh the child) if (childIsLeft != parentIsLeft) { child = child->parent; rotate(child, parentIsLeft); } // case 3: orientations are aligned // parent must be black (in order to take over grandparent's position) // grandparent change to red isBlack(child->parent) = true; isBlack(child->parent->parent) = false; rotate(child->parent->parent, !parentIsLeft); // parent moves up } } // property 1: root is black isBlack(this->root) = true; } return unique; }
void RBTree<T>::deleteFixUp(pTreeNode<pair<bool, T> >* parent, bool childIsLeft) { pTreeNode<pair<bool, T> >* child; pTreeNode<pair<bool, T> >* sibling; child = childIsLeft ? parent->left : parent->right; while (child != this->root && (NULL == child || isBlack(child))) { sibling = childIsLeft ? parent->right : parent->left; // sibling cannot be NULL, parent cannot be NULL if (false == isBlack(sibling)) { isBlack(sibling) = true; isBlack(parent) = false; // rotate in the child's direction rotate(parent, childIsLeft); sibling = childIsLeft ? parent->right : parent->left; } // sibling can be childless which are treated as black if ((NULL == sibling->left || isBlack(sibling->left)) && (NULL == sibling->right || isBlack(sibling->right))) { isBlack(sibling) = false; // moving up in the tree child = parent; parent = child->parent; if (parent && parent->left == child) childIsLeft = true; else childIsLeft = false; } else { if (true == childIsLeft && (NULL == sibling->right || isBlack(sibling->right))) { if (NULL != sibling->left) { isBlack(sibling->left) = true; } isBlack(sibling) = false; rotate(sibling, false); // right rotate sibling = parent->right; } if (false == childIsLeft && (NULL == sibling->left || isBlack(sibling->left))) { if (NULL != sibling->right) { isBlack(sibling->right) = true; } isBlack(sibling) = false; rotate(sibling, true); // left rotate sibling = parent->left; } if (true == childIsLeft && NULL != sibling->right) { isBlack(sibling->right) = true; } if (false == childIsLeft && NULL != sibling->left) { isBlack(sibling->left) = true; } isBlack(sibling) = isBlack(parent); isBlack(parent) = true; rotate(parent, childIsLeft); // rotate in child's direction child = this->root; } } isBlack(child) = true; }
void Maze::createWalls() { MazeWall wall; Transition curr = Transition_NONE; // horizontal for (int x = 1; x < m_sizeX; ++x) { Transition prev = Transition_NONE; for (int y = 0; y < m_sizeY; ++y) { if (isBlack(x - 1, y)) { curr = isBlack(x, y) ? Transition_NONE : Transition_WHITE; } else { curr = isBlack(x, y) ? Transition_BLACK : Transition_NONE; } if (curr != prev) { if (prev != Transition_NONE) { // save end points and fflush wall.verts[2].z = 0; wall.verts[3].z = m_wallsHeight; wall.verts[2].x = wall.verts[3].x = x - 0.5f; wall.verts[2].y = wall.verts[3].y = y - 0.5f; // tex coords const float diffY(wall.verts[2].y - wall.verts[1].y); wall.texCoords[2] = vec2(diffY, 1.0); wall.texCoords[3] = vec2(diffY, 0.0); wall.variant = rand() % WALLS_VARIANTS; m_walls.push_back(wall); } if (curr != Transition_NONE) { // initialize new wall wall.verts[1].z = 0; wall.verts[0].z = m_wallsHeight; wall.verts[0].x = wall.verts[1].x = x - 0.5f; wall.verts[0].y = wall.verts[1].y = y - 0.5f; // tex coords wall.texCoords[0] = vec2(0.0, 0.0); wall.texCoords[1] = vec2(0.0, 1.0); wall.normal = vec3((curr == Transition_BLACK) ? 1 : -1, 0, 0); } prev = curr; } } } curr = Transition_NONE; // vertical for (int y = 1; y < m_sizeY; ++y) { Transition prev = Transition_NONE; for (int x = 0; x < m_sizeX; ++x) { if (isBlack(x, y - 1)) { curr = isBlack(x, y) ? Transition_NONE : Transition_WHITE; } else { curr = isBlack(x, y) ? Transition_BLACK : Transition_NONE; } if (curr != prev) { if (prev != Transition_NONE) { // save end points and fflush wall.verts[2].z = 0; wall.verts[3].z = m_wallsHeight; wall.verts[2].x = wall.verts[3].x = x - 0.5f; wall.verts[2].y = wall.verts[3].y = y - 0.5f; // tex coords const float diffX(wall.verts[2].x - wall.verts[1].x); wall.texCoords[2] = vec2(diffX, 1.0); wall.texCoords[3] = vec2(diffX, 0.0); wall.variant = rand() % WALLS_VARIANTS; m_walls.push_back(wall); } if (curr != Transition_NONE) { // initialize new wall wall.verts[1].z = 0; wall.verts[0].z = m_wallsHeight; wall.verts[0].x = wall.verts[1].x = x - 0.5f; wall.verts[0].y = wall.verts[1].y = y - 0.5f; // tex coords wall.texCoords[0] = vec2(0.0, 0.0); wall.texCoords[1] = vec2(0.0, 1.0); wall.normal = vec3(0, (curr == Transition_BLACK) ? -1 : 1, 0); } prev = curr; } } } std::sort(m_walls.begin(), m_walls.end()); }
bool Card::sameColorWith(const Card *other) const{ return isBlack() == other->isBlack(); }
bool isDelta() const { //not delta if it's a light... return isBlack(material->emission) && material->isDelta(); }
void bdptRun(const RTScene& scene, int bounces, Rand& rand, Sample* sample) { PathVertex lpVerts[16]; PathVertex epVerts[16]; //we disregard direct light->eye connection //we include direct eye->light connection int maxEyeVertices = bounces + 1; //explicit vertices (the one at the eye is implicit) int maxLightVertices = bounces; int numLPV = createLightPath(scene, rand, maxLightVertices, lpVerts); //starts at 2 vertices int numEPV = createEyePath(scene, rand, maxEyeVertices, sample->ray, epVerts); //number of edges in the eye path that is non-specular //the direct connection edge does not count int epVariableNonSpecularEdges = 0; //initial excludes direct connection for(int epvIdx = 0; epvIdx < numEPV; epvIdx++) { auto & ev = epVerts[epvIdx]; if(ev.isDelta()) continue; //can't connect using shadow rays, or direct light //the current ev is already non delta if(epvIdx > 0 && !epVerts[epvIdx - 1].isDelta()) epVariableNonSpecularEdges++; if(!isBlack(ev.material->emission)) //we're the direct eye-light connection { int numTechniques = epVariableNonSpecularEdges + 1; float bdptWeight = 1.f / numTechniques; sample->radiance += bdptWeight * ev.throughput * ev.material->emission; continue; } if(epvIdx == (maxEyeVertices - 1)) continue; ShadingCS evShadingCS(ev.normal); //direct lighting { int numTechniques = epVariableNonSpecularEdges + 2; //derived on paper... float bdptWeight = 1.f / numTechniques; sample->radiance += bdptWeight * ev.throughput * directLight(rand, scene, ev, evShadingCS); } float3 evWo = evShadingCS.local(ev.woWorld); //number of free non-specular light path edges (includes v0-v1) //disregard direct lighting (start at lpvIdx of 1) int lpVariableNonSpecularEdges = 0; for(int lpvIdx = 1; lpvIdx < numLPV; lpvIdx++) { int lvCount = lpvIdx + 1; auto & lv = lpVerts[lpvIdx]; if(lv.isDelta()) continue; //the current vertex is already non-specular //lpvIdx starts at one... //if lpvIdx is 1, we know 0 and 1 are non deltas if(lpvIdx == 1 || (!lpVerts[lpvIdx-1].isDelta())) lpVariableNonSpecularEdges++; int vCount = epvIdx + 2 + lpvIdx + 1; int currentBounces = vCount - 2; if(currentBounces > bounces) break; int numTechniques = lpVariableNonSpecularEdges + epVariableNonSpecularEdges + 2; //derived on paper float bdptWeight = 1.f / numTechniques; bool visible = visibleAndFacing(lv.position, lv.normal, ev.position, ev.normal, scene); if(visible) { ShadingCS lvShadingCS(lv.normal); const float3 ev2lv = normalize(lv.position - ev.position); float3 evWi = evShadingCS.local(ev2lv); const float3 evWiWorld = ev2lv; const float3 lvWiWorld = -ev2lv; float3 evBrdfEval = ev.material->eval(evWi, evWo); float3 lvBrdfEval; if(lpvIdx == 0) { lvBrdfEval = float3(1); } else { float3 lvWi = lvShadingCS.local(lvWiWorld); float3 lvWo = lvShadingCS.local(lv.woWorld); lvBrdfEval = lv.material->eval(lvWi, lvWo); } float g = dot(evWiWorld, ev.normal) * dot(lvWiWorld, lv.normal) / glm::distance2(lv.position, ev.position); float3 lpT = lvBrdfEval * lv.throughput; float3 epT = evBrdfEval * ev.throughput; float3 T = lpT * epT * g; sample->radiance += bdptWeight * T; } } } }