コード例 #1
0
bool Game::cop_isObjectNotIntersectingBox() {
	debug(DBG_OPCODES, "Game::cop_isObjectNotIntersectingBox()");
	int16 var1A = _objectScript.fetchNextWord();
	int var18 = findObjectByName(_objectScript.currentObjectNum, _objectScript.testObjectNum, &_objectScript.objectFound);
	if (var18 != -1) {
		SceneObject *so = derefSceneObject(var18);
		if (so->statePrev != 0) {
			int16 var1E = getObjectTransformXPos(var18);
			int16 var22 = getObjectTransformYPos(var18);
			var18 = findObjectByName(_objectScript.currentObjectNum, _objectScript.testObjectNum, &_objectScript.objectFound);
			if (var18 != -1) {
				so = derefSceneObject(var18);
				if (so->statePrev != 0) {
					int16 var20 = getObjectTransformXPos(var18);
					int16 var24 = getObjectTransformYPos(var18);
					bool foundBox = false;
					for (int i = 0; i < _boxesCountTable[var1A]; ++i) {
						if (intersectsBox(var1A, i, var1E, var22, var20, var24)) {
							foundBox = true;
							break;
						}
					}
					if (foundBox) {
						if (var18 == _objectScript.testObjectNum) {
							_objectScript.dataOffset = _objectScript.testDataOffset;
							assert(0); // XXX
							return true;
						}
						return false;
					}
					foundBox = false;
					for (int i = 0; i < _boxesCountTable[10 + var1A]; ++i) {
						if (intersectsBox(10 + var1A, i, var1E, var22, var20, var24)) {
							foundBox = true;
							break;
						}
					}
					if (foundBox) {
						if (var18 == _objectScript.testObjectNum) {
							_objectScript.dataOffset = _objectScript.testDataOffset;
							assert(0); // XXX
							return true;
						}
						return false;
					}
					return true;
				}
			}
		}
	}
	if (var18 == _objectScript.testObjectNum) {
		_objectScript.dataOffset = _objectScript.testDataOffset;
		assert(0); // XXX
		return true;
	}
	return false;
}
コード例 #2
0
ファイル: 2dcommon.cpp プロジェクト: Convey-Compliance/mongo
    // Fills the stack, but only checks a maximum number of maxToCheck points at a time.
    // Further calls to this function will continue the expand/check neighbors algorithm.
    void GeoBrowse::fillStack(int maxToCheck, int maxToAdd, bool onlyExpand) {
        if(maxToAdd < 0) maxToAdd = maxToCheck;
        int maxFound = _foundInExp + maxToCheck;
        verify(maxToCheck > 0);
        verify(maxFound > 0);
        verify(_found <= 0x7fffffff); // conversion to int
        int maxAdded = static_cast<int>(_found) + maxToAdd;
        verify(maxAdded >= 0); // overflow check

        bool isNeighbor = _centerPrefix.constrains();

        // Starting a box expansion
        if (_state == START) {
            // Get the very first hash point, if required
            if(! isNeighbor)
                _prefix = expandStartHash();

            if (!BtreeLocation::initial(_descriptor, _params, _min, _max, _prefix)) {
                _state = isNeighbor ? DONE_NEIGHBOR : DONE;
            } else {
                _state = DOING_EXPAND;
                _lastPrefix.reset();
            }
        }

        // Doing the actual box expansion
        if (_state == DOING_EXPAND) {
            while (true) {
                // Record the prefix we're actively exploring...
                _expPrefix.reset(new GeoHash(_prefix));

                // Find points inside this prefix
                while (checkAndAdvance(&_min, _prefix, _foundInExp)
                        && _foundInExp < maxFound && _found < maxAdded) {}
                while (checkAndAdvance(&_max, _prefix, _foundInExp)
                        && _foundInExp < maxFound && _found < maxAdded) {}

                if(_foundInExp >= maxFound || _found >= maxAdded) return;

                // We've searched this prefix fully, remember
                _lastPrefix.reset(new GeoHash(_prefix));

                // If we've searched the entire space, we're finished.
                if (! _prefix.constrains()) {
                    _state = DONE;
                    notePrefix();
                    return;
                }

                // If we won't fit in the box, and we're not doing a sub-scan, increase the size
                if (! fitsInBox(_converter->sizeEdge(_prefix)) && _fringe.size() == 0) {
                    // If we're still not expanded bigger than the box size, expand again
                    _prefix = _prefix.up();
                    continue;
                }

                // We're done and our size is large enough
                _state = DONE_NEIGHBOR;

                // Go to the next sub-box, if applicable
                if(_fringe.size() > 0) _fringe.pop_back();
                // Go to the next neighbor if this was the last sub-search
                if(_fringe.size() == 0) _neighbor++;
                break;
            }
            notePrefix();
        }

        // If we doeighbors
        if(onlyExpand) return;

        // If we're done expanding the current box...
        if(_state == DONE_NEIGHBOR) {
            // Iterate to the next neighbor
            // Loop is useful for cases where we want to skip over boxes entirely,
            // otherwise recursion increments the neighbors.
            for (; _neighbor < 9; _neighbor++) {
                // If we have no fringe for the neighbor, make sure we have the default fringe
                if(_fringe.size() == 0) _fringe.push_back("");

                if(! isNeighbor) {
                    _centerPrefix = _prefix;
                    _centerBox = makeBox(_centerPrefix);
                    isNeighbor = true;
                }

                int i = (_neighbor / 3) - 1;
                int j = (_neighbor % 3) - 1;

                if ((i == 0 && j == 0) ||
                        (i < 0 && _centerPrefix.atMinX()) ||
                        (i > 0 && _centerPrefix.atMaxX()) ||
                        (j < 0 && _centerPrefix.atMinY()) ||
                        (j > 0 && _centerPrefix.atMaxY())) {

                    continue; // main box or wrapped edge
                    // TODO:  We may want to enable wrapping in future, probably best as layer
                    // on top of this search.
                }

                // Make sure we've got a reasonable center
                verify(_centerPrefix.constrains());

                GeoHash _neighborPrefix = _centerPrefix;
                _neighborPrefix.move(i, j);

                while(_fringe.size() > 0) {
                    _prefix = _neighborPrefix + _fringe.back();
                    Box cur(makeBox(_prefix));

                    double intAmt = intersectsBox(cur);

                    // No intersection
                    if(intAmt <= 0) {
                        _fringe.pop_back();
                        continue;
                    } else if(intAmt < 0.5 && _prefix.canRefine()
                            && _fringe.back().size() < 4 /* two bits */) {
                        // Small intersection, refine search
                        string lastSuffix = _fringe.back();
                        _fringe.pop_back();
                        _fringe.push_back(lastSuffix + "00");
                        _fringe.push_back(lastSuffix + "01");
                        _fringe.push_back(lastSuffix + "11");
                        _fringe.push_back(lastSuffix + "10");
                        continue;
                    }

                    // Restart our search from a diff box.
                    _state = START;
                    verify(! onlyExpand);
                    verify(_found <= 0x7fffffff);
                    fillStack(maxFound - _foundInExp, maxAdded - static_cast<int>(_found));
                    // When we return from the recursive fillStack call, we'll either have
                    // checked enough points or be entirely done.  Max recurse depth is < 8 *
                    // 16.
                    // If we're maxed out on points, return
                    if(_foundInExp >= maxFound || _found >= maxAdded) {
                        // Make sure we'll come back to add more points
                        verify(_state == DOING_EXPAND);
                        return;
                    }

                    // Otherwise we must be finished to return
                    verify(_state == DONE);
                    return;
                }
            }
            // Finished with neighbors
            _state = DONE;
        }
    }