int Graph::nodeDist(int id1, int id2, int t, int &dist) { int x1, x2, y1, y2; if(nodePos(id1, t, x1, y1) && nodePos(id2, t, x2, y2)) { dist = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); return 1; } return 0; }
void SceneManager::updateQueuesRec( const Frustum &frustum1, const Frustum *frustum2, bool sorted, SceneNode &node, bool lightQueue, bool renderableQueue ) { if( !node._active ) return; if( node._type == SceneNodeTypes::Group ) { // LOD Vec3f nodePos( node._absTrans.c[3][0], node._absTrans.c[3][1], node._absTrans.c[3][2] ); float dist = (nodePos - frustum1.getOrigin()).length(); GroupNode *gn = (GroupNode *)&node; if( dist < gn->_minDist || dist >= gn->_maxDist ) return; } else if( lightQueue && node._type == SceneNodeTypes::Light ) { _lightQueue.push_back( &node ); } else if( renderableQueue && node._renderable ) { if( node._type == SceneNodeTypes::Emitter ) { // Emitters are a special case since we have to use their local bounding box // If the emitter is transformed particle positions don't change if( !frustum1.cullBox( *node.getLocalBBox() ) && (frustum2 == 0x0 || !frustum2->cullBox( *node.getLocalBBox() )) ) { if( sorted ) { node.tmpSortValue = nearestDistToAABB( frustum1.getOrigin(), node.getLocalBBox()->getMinCoords(), node.getLocalBBox()->getMaxCoords() ); } _renderableQueue.push_back( &node ); } } else { if( !frustum1.cullBox( node._bBox ) && (frustum2 == 0x0 || !frustum2->cullBox( node._bBox )) ) { if( sorted ) { node.tmpSortValue = nearestDistToAABB( frustum1.getOrigin(), node._bBox.getMinCoords(), node._bBox.getMaxCoords() ); } _renderableQueue.push_back( &node ); } } } // Recurse over children for( uint32 i = 0, s = (uint32)node._children.size(); i < s; ++i ) { updateQueuesRec( frustum1, frustum2, sorted, *node._children[i], lightQueue, renderableQueue ); } }
// Initialize a new geogram mesh corresponding to the current grid void OctreeGrid::createMesh( GEO::Mesh &mesh, const Eigen::Vector3d &origin, const Eigen::Vector3d &spacing) const { mesh.clear(false, false); // logger_debug("OctreeGrid", "createMesh(): Allocate vertices and cells"); // Create the mesh of regular grid mesh.vertices.create_vertices(numNodes()); for (int idx = 0; idx < numNodes(); ++idx) { Eigen::Vector3d pos = origin + nodePos(idx).cast<double>().cwiseProduct(spacing); mesh.vertices.point(idx) = GEO::vec3(pos[0], pos[1], pos[2]); } // Count num of leaf cells int numLeaves = 0; for (int c = 0; c < numCells(); ++c) { if (cellIsLeaf(c)) { ++numLeaves; } } GEO::index_t firstCube = mesh.cells.create_hexes(numLeaves); for (int q = 0, c = 0; q < numCells(); ++q) { if (!cellIsLeaf(q)) { continue; } Eigen::Vector3i diff[8] = { {0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}, {0,0,1}, {1,0,1}, {0,1,1}, {1,1,1} }; for (GEO::index_t lv = 0; lv < 8; ++lv) { int cornerId = Cube::invDelta(diff[lv]); int v = cellCornerId(q, cornerId); mesh.cells.set_vertex(firstCube + c, lv, v); } ++c; } // logger_debug("OctreeGrid", "createMesh(): Connecting cells"); //GEO::Logger::out("OctreeGrid") << "Computing borders..." << std::endl; //mesh.cells.compute_borders(); //GEO::Logger::out("OctreeGrid") << "Connecting cells..." << std::endl; //mesh.cells.connect(); // logger_debug("OctreeGrid", "createMesh(): Creating attributes..."); updateMeshAttributes(mesh); }
//-------------------------------------------------------------- void testApp::setup(){ cout << "-------------------oo" << endl; cout << "-------------------oo" << endl; ofSetFrameRate(30); ofSetVerticalSync(true); //ofEnableAlphaBlending(); //ofEnableSmoothing(); //ofSetCircleResolution(32); ofBackground(0); ofSetBackgroundAuto(true); //DirectoryUtils dirUtil; ofDirectory dir(""); dir.listDir(); cout << "FileCount: " << dir.numFiles() << endl; cout << "FilePath: " << dir.getPath(0) << endl; cout << "FilePath: " << dir.getAbsolutePath() << endl; cout << " " << endl; ofVec2f nodePos(10,50); ofVec2f nodeSize(200,17); for (int i = 0; i < dir.numFiles(); i++) { string filePath = dir.getAbsolutePath() + "/" + dir.getPath(i); files.push_back(filePath); cout << files[i] << endl; nodes.push_back(Node(nodePos, nodeSize, filePath)); nodePos += ofVec2f(0,20); } }
bool MWMechanics::AiWander::execute (const MWWorld::Ptr& actor) { if(mDuration) { // End package if duration is complete or mid-night hits: MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); if(currentTime.getHour() >= mStartTime.getHour() + mDuration) { if(!mRepeat) { stopWalking(actor, mPathFinder); return true; } else mStartTime = currentTime; } else if(int(currentTime.getHour()) == 0 && currentTime.getDay() != mStartTime.getDay()) { if(!mRepeat) { stopWalking(actor, mPathFinder); return true; } else mStartTime = currentTime; } } ESM::Position pos = actor.getRefData().getPosition(); if(!mStoredAvailableNodes) { mStoredAvailableNodes = true; mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->mCell); mCellX = actor.getCell()->mCell->mData.mX; mCellY = actor.getCell()->mCell->mData.mY; if(!mPathgrid) mDistance = 0; else if(mPathgrid->mPoints.empty()) mDistance = 0; if(mDistance) { mXCell = 0; mYCell = 0; if(actor.getCell()->mCell->isExterior()) { mXCell = mCellX * ESM::Land::REAL_SIZE; mYCell = mCellY * ESM::Land::REAL_SIZE; } Ogre::Vector3 npcPos(actor.getRefData().getPosition().pos); npcPos[0] = npcPos[0] - mXCell; npcPos[1] = npcPos[1] - mYCell; for(unsigned int counter = 0; counter < mPathgrid->mPoints.size(); counter++) { Ogre::Vector3 nodePos(mPathgrid->mPoints[counter].mX, mPathgrid->mPoints[counter].mY, mPathgrid->mPoints[counter].mZ); if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance) mAllowedNodes.push_back(mPathgrid->mPoints[counter]); } if(!mAllowedNodes.empty()) { Ogre::Vector3 firstNodePos(mAllowedNodes[0].mX, mAllowedNodes[0].mY, mAllowedNodes[0].mZ); float closestNode = npcPos.squaredDistance(firstNodePos); unsigned int index = 0; for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++) { Ogre::Vector3 nodePos(mAllowedNodes[counterThree].mX, mAllowedNodes[counterThree].mY, mAllowedNodes[counterThree].mZ); float tempDist = npcPos.squaredDistance(nodePos); if(tempDist < closestNode) index = counterThree; } mCurrentNode = mAllowedNodes[index]; mAllowedNodes.erase(mAllowedNodes.begin() + index); } if(mAllowedNodes.empty()) mDistance = 0; } } MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); bool cellChange = actor.getCell()->mCell->mData.mX != mCellX || actor.getCell()->mCell->mData.mY != mCellY; if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) { int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); // Check if actor is near the border of an inactive cell. If so, disable AiWander. // FIXME: This *should* pause the AiWander package instead of terminating it. if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2.0 - 200)) { MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; return true; } } if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) { int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); // Check if actor is near the border of an inactive cell. If so, disable AiWander. // FIXME: This *should* pause the AiWander package instead of terminating it. if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2.0 - 200)) { MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; return true; } } // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. if(mDistance && (cellChange || (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY))) mDistance = 0; if(mChooseAction) { mPlayedIdle = 0; unsigned short idleRoll = 0; for(unsigned int counter = 1; counter < mIdle.size(); counter++) { unsigned short idleChance = mIdleChanceMultiplier * mIdle[counter]; unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mIdleChanceMultiplier)); if(randSelect < idleChance && randSelect > idleRoll) { mPlayedIdle = counter; idleRoll = randSelect; } } if(!mPlayedIdle && mDistance) { mChooseAction = false; mMoveNow = true; } else { // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mStartTime = currentTime; playIdle(actor, mPlayedIdle + 1); mChooseAction = false; mIdleNow = true; } } if(mIdleNow) { if(!checkIdle(actor, mPlayedIdle + 1)) { mPlayedIdle = 0; mIdleNow = false; mChooseAction = true; } } if(mMoveNow && mDistance) { if(!mPathFinder.isPathConstructed()) { unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; mAllowedNodes.erase(mAllowedNodes.begin() + randNode); mAllowedNodes.push_back(mCurrentNode); mCurrentNode = temp; ESM::Pathgrid::Point dest; dest.mX = destNodePos[0] + mXCell; dest.mY = destNodePos[1] + mYCell; dest.mZ = destNodePos[2]; ESM::Pathgrid::Point start; start.mX = pos.pos[0]; start.mY = pos.pos[1]; start.mZ = pos.pos[2]; mPathFinder.buildPath(start,dest,mPathgrid,mXCell,mYCell); mWalking = true; } } if(mWalking) { float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; // Unclog path nodes by allowing the NPC to be a small distance away from the center. This way two NPCs can be // at the same path node at the same time and both will complete instead of endlessly walking into eachother: Ogre::Vector3 destNodePos(mCurrentNode.mX, mCurrentNode.mY, mCurrentNode.mZ); Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos); actorPos[0] = actorPos[0] - mXCell; actorPos[1] = actorPos[1] - mYCell; float distance = actorPos.squaredDistance(destNodePos); if(distance < 1200 || mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) { stopWalking(actor, mPathFinder); mMoveNow = false; mWalking = false; mChooseAction = true; } } return false; }
bool AiWander::execute (const MWWorld::Ptr& actor,float duration) { if (actor.getClass().isNpc()) actor.getClass().getNpcStats(actor).setDrawState(DrawState_Nothing); MWBase::World *world = MWBase::Environment::get().getWorld(); if(mDuration) { // End package if duration is complete or mid-night hits: MWWorld::TimeStamp currentTime = world->getTimeStamp(); if(currentTime.getHour() >= mStartTime.getHour() + mDuration) { if(!mRepeat) { stopWalking(actor); return true; } else mStartTime = currentTime; } else if(int(currentTime.getHour()) == 0 && currentTime.getDay() != mStartTime.getDay()) { if(!mRepeat) { stopWalking(actor); return true; } else mStartTime = currentTime; } } ESM::Position pos = actor.getRefData().getPosition(); if(!mStoredAvailableNodes) { mStoredAvailableNodes = true; mPathgrid = world->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->mCell); mCellX = actor.getCell()->mCell->mData.mX; mCellY = actor.getCell()->mCell->mData.mY; if(!mPathgrid) mDistance = 0; else if(mPathgrid->mPoints.empty()) mDistance = 0; if(mDistance) { mXCell = 0; mYCell = 0; if(actor.getCell()->mCell->isExterior()) { mXCell = mCellX * ESM::Land::REAL_SIZE; mYCell = mCellY * ESM::Land::REAL_SIZE; } Ogre::Vector3 npcPos(actor.getRefData().getPosition().pos); npcPos[0] = npcPos[0] - mXCell; npcPos[1] = npcPos[1] - mYCell; for(unsigned int counter = 0; counter < mPathgrid->mPoints.size(); counter++) { Ogre::Vector3 nodePos(mPathgrid->mPoints[counter].mX, mPathgrid->mPoints[counter].mY, mPathgrid->mPoints[counter].mZ); if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance) mAllowedNodes.push_back(mPathgrid->mPoints[counter]); } if(!mAllowedNodes.empty()) { Ogre::Vector3 firstNodePos(mAllowedNodes[0].mX, mAllowedNodes[0].mY, mAllowedNodes[0].mZ); float closestNode = npcPos.squaredDistance(firstNodePos); unsigned int index = 0; for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++) { Ogre::Vector3 nodePos(mAllowedNodes[counterThree].mX, mAllowedNodes[counterThree].mY, mAllowedNodes[counterThree].mZ); float tempDist = npcPos.squaredDistance(nodePos); if(tempDist < closestNode) index = counterThree; } mCurrentNode = mAllowedNodes[index]; mAllowedNodes.erase(mAllowedNodes.begin() + index); } } } if(mAllowedNodes.empty()) mDistance = 0; // Don't try to move if you are in a new cell (ie: positioncell command called) but still play idles. if(mDistance && (mCellX != actor.getCell()->mCell->mData.mX || mCellY != actor.getCell()->mCell->mData.mY)) mDistance = 0; if(mChooseAction) { mPlayedIdle = 0; unsigned short idleRoll = 0; for(unsigned int counter = 0; counter < mIdle.size(); counter++) { unsigned short idleChance = mIdleChanceMultiplier * mIdle[counter]; unsigned short randSelect = (int)(rand() / ((double)RAND_MAX + 1) * int(100 / mIdleChanceMultiplier)); if(randSelect < idleChance && randSelect > idleRoll) { mPlayedIdle = counter+2; idleRoll = randSelect; } } if(!mPlayedIdle && mDistance) { mChooseAction = false; mMoveNow = true; } else { // Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: MWWorld::TimeStamp currentTime = world->getTimeStamp(); mStartTime = currentTime; playIdle(actor, mPlayedIdle); mChooseAction = false; mIdleNow = true; } } if(mIdleNow) { if(!checkIdle(actor, mPlayedIdle)) { mPlayedIdle = 0; mIdleNow = false; mChooseAction = true; } } if(mMoveNow && mDistance) { if(!mPathFinder.isPathConstructed()) { assert(mAllowedNodes.size()); unsigned int randNode = (int)(rand() / ((double)RAND_MAX + 1) * mAllowedNodes.size()); Ogre::Vector3 destNodePos(mAllowedNodes[randNode].mX, mAllowedNodes[randNode].mY, mAllowedNodes[randNode].mZ); ESM::Pathgrid::Point dest; dest.mX = destNodePos[0] + mXCell; dest.mY = destNodePos[1] + mYCell; dest.mZ = destNodePos[2]; ESM::Pathgrid::Point start; start.mX = pos.pos[0]; start.mY = pos.pos[1]; start.mZ = pos.pos[2]; mPathFinder.buildPath(start, dest, mPathgrid, mXCell, mYCell, false); if(mPathFinder.isPathConstructed()) { // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): ESM::Pathgrid::Point temp = mAllowedNodes[randNode]; mAllowedNodes.erase(mAllowedNodes.begin() + randNode); mAllowedNodes.push_back(mCurrentNode); mCurrentNode = temp; mMoveNow = false; mWalking = true; } // Choose a different node and delete this one from possible nodes because it is uncreachable: else mAllowedNodes.erase(mAllowedNodes.begin() + randNode); } } if(mWalking) { float zAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]); // TODO: use movement settings instead of rotating directly world->rotateObject(actor, 0, 0, zAngle, false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2])) { stopWalking(actor); mMoveNow = false; mWalking = false; mChooseAction = true; } } return false; }
double ClusteringCoefficient::sequentialAvgLocal(const Graph &G) { WARN("DEPRECATED: use centrality.LocalClusteringCoefficient and take average"); std::vector<std::vector<node> > edges(G.upperNodeIdBound()); // copy edges with edge ids G.parallelForNodes([&](node u) { edges[u].reserve(G.degree(u)); G.forEdgesOf(u, [&](node _u, node v, edgeid eid) { edges[u].emplace_back(v); }); }); //Node attribute: marker std::vector<bool> nodeMarker(G.upperNodeIdBound(), false); //Edge attribute: triangle count std::vector<count> triangleCount(G.upperNodeIdBound(), 0); // bucket sort count n = G.numberOfNodes(); std::vector<node> sortedNodes(n); { std::vector<index> nodePos(n + 1, 0); G.forNodes([&](node u) { ++nodePos[n - G.degree(u)]; }); // exclusive prefix sum index tmp = nodePos[0]; index sum = tmp; nodePos[0] = 0; for (index i = 1; i < nodePos.size(); ++i) { tmp = nodePos[i]; nodePos[i] = sum; sum += tmp; } G.forNodes([&](node u) { sortedNodes[nodePos[n - G.degree(u)]++] = u; }); } for (node u : sortedNodes) { //Mark all neighbors for (auto v : edges[u]) { nodeMarker[v] = true; } //For all neighbors: check for already marked neighbors. for (auto v : edges[u]) { for (auto w = edges[v].begin(); w != edges[v].end(); ++w) { // delete the edge to u as we do not need to consider it again. // the opposite edge doesn't need to be deleted as we will never again consider // outgoing edges of u as u cannot be reached anymore after the uv loop. if (*w == u) { // move last element to current position in order to avoid changing too much *w = edges[v].back(); edges[v].pop_back(); if (w == edges[v].end()) // break if we were at the last element already break; } if (nodeMarker[*w]) { // triangle found - count it! ++triangleCount[u]; ++triangleCount[*w]; ++triangleCount[v]; } } nodeMarker[v] = false; // all triangles with u and v have been counted already } } double coefficient = 0; count size = 0; G.forNodes([&](node u) { count d = G.degree(u); if (d > 1) { coefficient += triangleCount[u] * 2.0 / (d * (d - 1)); size++; } }); return coefficient / size; }
void TMXLayer::updateTotalQuads() { if(_quadsDirty) { Size tileSize = CC_SIZE_PIXELS_TO_POINTS(_tileSet->_tileSize); Size texSize = _tileSet->_imageSize; _tileToQuadIndex.clear(); (*_totalQuads).resize(int(_layerSize.width * _layerSize.height)); //[CY MOD] (*_indices).resize(6 * int(_layerSize.width * _layerSize.height)); //[CY MOD] _tileToQuadIndex.resize(int(_layerSize.width * _layerSize.height),-1); _indicesVertexZOffsets.clear(); int quadIndex = 0; for(int y = 0; y < _layerSize.height; ++y) { for(int x =0; x < _layerSize.width; ++x) { int tileIndex = getTileIndexByPos(x, y); int tileGID = _tiles[tileIndex]; if(tileGID == 0) continue; _tileToQuadIndex[tileIndex] = quadIndex; auto& quad = (*_totalQuads)[quadIndex]; //[CY MOD] Vec3 nodePos(float(x), float(y), 0); _tileToNodeTransform.transformPoint(&nodePos); float left, right, top, bottom, z; z = getVertexZForPos(Vec2(x, y)); auto iter = _indicesVertexZOffsets.find(z); if(iter == _indicesVertexZOffsets.end()) { _indicesVertexZOffsets[z] = 1; } else { iter->second++; } // vertices if (tileGID & kTMXTileDiagonalFlag) { left = nodePos.x; right = nodePos.x + tileSize.height; bottom = nodePos.y + tileSize.width; top = nodePos.y; } else { left = nodePos.x; right = nodePos.x + tileSize.width; bottom = nodePos.y + tileSize.height; top = nodePos.y; } if(tileGID & kTMXTileVerticalFlag) std::swap(top, bottom); if(tileGID & kTMXTileHorizontalFlag) std::swap(left, right); if(tileGID & kTMXTileDiagonalFlag) { // FIXME: not working correcly quad.bl.vertices.x = left; quad.bl.vertices.y = bottom; quad.bl.vertices.z = z; quad.br.vertices.x = left; quad.br.vertices.y = top; quad.br.vertices.z = z; quad.tl.vertices.x = right; quad.tl.vertices.y = bottom; quad.tl.vertices.z = z; quad.tr.vertices.x = right; quad.tr.vertices.y = top; quad.tr.vertices.z = z; } else { quad.bl.vertices.x = left; quad.bl.vertices.y = bottom; quad.bl.vertices.z = z; quad.br.vertices.x = right; quad.br.vertices.y = bottom; quad.br.vertices.z = z; quad.tl.vertices.x = left; quad.tl.vertices.y = top; quad.tl.vertices.z = z; quad.tr.vertices.x = right; quad.tr.vertices.y = top; quad.tr.vertices.z = z; } // texcoords Rect tileTexture = _tileSet->getRectForGID(tileGID); left = (tileTexture.origin.x) / texSize.width; right = (tileTexture.origin.x+tileTexture.size.width) / texSize.width; bottom = (tileTexture.origin.y)/ texSize.height; top = (tileTexture.origin.y+tileTexture.size.height) / texSize.height; quad.bl.texCoords.u = left; quad.bl.texCoords.v = bottom; quad.br.texCoords.u = right; quad.br.texCoords.v = bottom; quad.tl.texCoords.u = left; quad.tl.texCoords.v = top; quad.tr.texCoords.u = right; quad.tr.texCoords.v = top; quad.bl.colors = Color4B::WHITE; quad.br.colors = Color4B::WHITE; quad.tl.colors = Color4B::WHITE; quad.tr.colors = Color4B::WHITE; ++quadIndex; } } int offset = 0; for(auto iter = _indicesVertexZOffsets.begin(); iter != _indicesVertexZOffsets.end(); ++iter) { std::swap(offset, iter->second); offset += iter->second; } updateVertexBuffer(); _quadsDirty = false; } }