int GetCellIndex(const Vec3f &aPoint) const { const Vec3f distMin = aPoint - mBBoxMin; const Vec3f coordF( std::floor(mInvCellSize * distMin.x), std::floor(mInvCellSize * distMin.y), std::floor(mInvCellSize * distMin.z)); const Vec3i coordI = Vec3i(int(coordF.x), int(coordF.y), int(coordF.z)); return GetCellIndex(coordI); }
void GridModel::UpdateGrid() { unsigned int i, j; unsigned int index = 0; unsigned int x,y,z; bool not_dirty; for( i = 0; i < _modified_chunks.size(); i++ )//bad { not_dirty = true; for( j = 0; j < _dirty_chunks.size(); j++ ) { if ( _dirty_chunks[j] == _modified_chunks[i] ) { not_dirty = false; break; } } if (not_dirty) _modified_chunks[i]->RecalcColor( _cells, dimm ); } _modified_chunks.clear(); for( i = 0; i < _dirty_chunks.size(); i++ ) { index = GetCellIndex( (_dirty_chunks[i]->GetCenter() ), x, y, z); _dirty_chunks[i]->CreateMesh( _cells, _interacted, dimm ); if ( _dirty_chunks[i]->GetVAO() != NULL )// If mesh creating was successfull. { _renderable_chunks[index] = _dirty_chunks[i]->GetVAO(); _modified_chunks.push_back(_dirty_chunks[i]); } else _renderable_chunks.erase( index ); } _dirty_chunks.clear(); }
void CUniformGrid::AddBody(CGameNode * node) { const int CurrentIndex = node->GetGridIndex(); const int NewIndex = GetCellIndex(node->GetPosition()); if (-1 != CurrentIndex) { if (NewIndex == CurrentIndex) { // Nothing to do, already in right place return; } else { // Got this unit but in wrong cell, so remove first RemoveBody(node); } } m_GridArray[NewIndex].push_back(node); node->SetGridIndex(NewIndex); }
GridModel::GridModel( int power ) { dimm = 1<<power; //grid dimension size = dimm*dimm*dimm;//total size half_dimm = dimm>>1; _cells = new UINT8[size];//cells - voxels. _interacted = new bool[size];//array to store bool - if voxel was changed during this frame. memset( _interacted, 0, size*sizeof(bool) ); power_for_chunk = max( unsigned(power-4), unsigned(4) );//chunk_size unsigned int _chunk_power = power - power_for_chunk; chunk_dimm = 1<<_chunk_power;//dimension for array of chunk chunk_size = chunk_dimm*chunk_dimm*chunk_dimm; _chunks = new VoxelChunk*[chunk_size]; internal_chunk_size = 1<<power_for_chunk;//internal chunk size, dimm == chunk_dimm*internal_chunk_size Point center;//center of voxel is always (+-xx.5, +-yy.5, +-zz.5) int iter = 0; unsigned int tmp1, tmp2, tmp3; float radius = 0.0f; for ( int i = 0; i < dimm; i++ ) { center.coord[0] = float(i - half_dimm);//well, but not here =) for ( int j = 0; j < dimm; j++ ) { center.coord[1] = float(j - half_dimm); for ( int k = 0; k < dimm; k++ ) { center.coord[2] = float(k - half_dimm); iter = i*dimm*dimm+ j*dimm+ k; _cells[iter] = 0; radius = sqrtf( center.coord[0]*center.coord[0] + center.coord[1]*center.coord[1] + center.coord[2]*center.coord[2]); if ( radius < dimm/2 - 1 ) _cells[iter] = 255; //floating_rock(i, j, k, _cells, dimm); if ( iter != GetCellIndex(center, tmp1, tmp2, tmp3) ) { std::cout<<"Error!"; } } } } int tmp_lbl[3]; int tmp_ufr[3]; float _h_s = float(internal_chunk_size>>1); for ( int i = 0; i < chunk_dimm; i++ ) { tmp_lbl[0] = int(i<<power_for_chunk) - int(dimm/2); center.coord[0] = float(tmp_lbl[0]) + _h_s;//but here it is tmp_ufr[0] = tmp_lbl[0] + internal_chunk_size; for ( int j = 0; j < chunk_dimm; j++ ) { tmp_lbl[1] = int(j<<power_for_chunk) - int(dimm/2); center.coord[1] = float(tmp_lbl[1]) + _h_s; tmp_ufr[1] = tmp_lbl[1] + internal_chunk_size; for ( int k = 0; k < chunk_dimm; k++ ) { tmp_lbl[2] = int(k<<power_for_chunk) - int(dimm/2); center.coord[2] = float(tmp_lbl[2]) + _h_s; tmp_ufr[2] = tmp_lbl[2] + internal_chunk_size; iter = i*chunk_dimm*chunk_dimm+ j*chunk_dimm+ k; _chunks[ iter ] = new VoxelChunk( center, tmp_lbl, tmp_ufr ); _chunks[ iter ]->MarkDirty(); _dirty_chunks.push_back( _chunks[ iter ] ); } } } /* init mutex*/ #ifdef USE_SPINLOCK pthread_spin_init(&spinlock, 0); #else pthread_mutex_init(&mutex, NULL); #endif }
void build( const tParticle* aParticles, uint32_t count, float aRadius) { mRadius = aRadius; mRadiusSqr = sqr(mRadius); mCellSize = mRadius * 2.f; mInvCellSize = 1.f / mCellSize; mBBoxMin = Vec3f( 1e36f); mBBoxMax = Vec3f(-1e36f); // Build bounding box of the particiles for(size_t i=0; i<count; i++) { if(isValid(aParticles[i])) { const Vec3f &pos = getPosition(aParticles[i]); for(int j=0; j<3; j++) { mBBoxMax[j] = std::max(mBBoxMax[j], pos[j]); mBBoxMin[j] = std::min(mBBoxMin[j], pos[j]); } } } auto center = (mBBoxMin + mBBoxMax) / 2.f; // For numerical stability at the border of the scene: mBBoxMin = center + 1.1f * (mBBoxMin - center); mBBoxMax = center + 1.1f * (mBBoxMax - center); mIndices.resize(count); memset(&mCellEnds[0], 0, mCellEnds.size() * sizeof(int)); // set mCellEnds[x] to number of particles within x for(size_t i=0; i<count; i++) { if(isValid(aParticles[i])) { const Vec3f &pos = getPosition(aParticles[i]); mCellEnds[GetCellIndex(pos)]++; } } // run exclusive prefix sum to really get the cell starts // mCellEnds[x] is now where the cell starts int sum = 0; for(size_t i=0; i<mCellEnds.size(); i++) { int temp = mCellEnds[i]; mCellEnds[i] = sum; sum += temp; } for(size_t i=0; i<count; i++) { if(isValid(aParticles[i])) { const Vec3f &pos = getPosition(aParticles[i]); const int targetIdx = mCellEnds[GetCellIndex(pos)]++; mIndices[targetIdx] = int(i); } } // now mCellEnds[x] points to the index right after the last // element of cell x //// DEBUG //for(size_t i=0; i<aParticles.size(); i++) //{ // const Vec3f &pos = aParticles[i].GetPosition(); // Vec2i range = GetCellRange(GetCellIndex(pos)); // bool found = false; // for(;range.x < range.y; range.x++) // { // if(mIndices[range.x] == i) // found = true; // } // if(!found) // printf("Error at particle %d\n", i); //} }
int process( const tParticle* aParticles, const Vec3f& queryPos, const tFunc& aFunc) const { const Vec3f distMin = queryPos - mBBoxMin; const Vec3f distMax = mBBoxMax - queryPos; for(int i=0; i<3; i++) { if(distMin[i] < 0.f || distMax[i] < 0.f) { return -1; } } const Vec3f cellPt = mInvCellSize * distMin; const Vec3f coordF( std::floor(cellPt.x), std::floor(cellPt.y), std::floor(cellPt.z)); const int px = int(coordF.x); const int py = int(coordF.y); const int pz = int(coordF.z); const Vec3f fractCoord = cellPt - coordF; const int pxo = px + (fractCoord.x < 0.5f ? -1 : +1); const int pyo = py + (fractCoord.y < 0.5f ? -1 : +1); const int pzo = pz + (fractCoord.z < 0.5f ? -1 : +1); int found = 0; for(int j=0; j<8; j++) { Vec2i activeRange; switch(j) { case 0: activeRange = GetCellRange(GetCellIndex(Vec3i(px , py , pz ))); break; case 1: activeRange = GetCellRange(GetCellIndex(Vec3i(px , py , pzo))); break; case 2: activeRange = GetCellRange(GetCellIndex(Vec3i(px , pyo, pz ))); break; case 3: activeRange = GetCellRange(GetCellIndex(Vec3i(px , pyo, pzo))); break; case 4: activeRange = GetCellRange(GetCellIndex(Vec3i(pxo, py , pz ))); break; case 5: activeRange = GetCellRange(GetCellIndex(Vec3i(pxo, py , pzo))); break; case 6: activeRange = GetCellRange(GetCellIndex(Vec3i(pxo, pyo, pz ))); break; case 7: activeRange = GetCellRange(GetCellIndex(Vec3i(pxo, pyo, pzo))); break; } for(; activeRange.x < activeRange.y; activeRange.x++) { const int particleIndex = mIndices[activeRange.x]; const tParticle &particle = aParticles[particleIndex]; const float distSqr = sqr_length(queryPos - getPosition(particle)); if(distSqr <= mRadiusSqr) { aFunc(particle); ++found; } } } return found; }
void CEmotionButton::DoEvent(TEventUI& event) { switch( event.Type) { case UIEVENT_MOUSEMOVE: { RECT rc1, rc2, invalidRect; int lastCol = -1, curCol = -1; unsigned char changetype = _PosChangeType::NoChange; //预览矩形是否需要改变 POINT pt = event.ptMouse; int tmpSel = GetCellIndex(pt.x, pt.y); //是否超出了图片数量 if((tmpSel + curPage * CELLCOUNT_PAGE) >= m_ImageCount) tmpSel = -1; if(tmpSel != curSel) { //两个cell 索引行进 lastSel = curSel; curSel = tmpSel; curFrame = 0; //预览矩形需要移动吗? lastCol = (lastSel % 15); curCol = (curSel % 15); //每行15个 GetBlueRect(lastSel, &rc1); GetBlueRect(curSel, &rc2); UnionRect(&invalidRect, &rc1, &rc2); invalidRect.right++; invalidRect.bottom++; //判断缩略矩形是否发生位置改变? if(pvstatus == _PVStatus::Hide) { if(curSel >= 0) { if((curSel%15) > 7) { pvstatus = _PVStatus::Left; changetype = _PosChangeType::HideToLeft; } else { pvstatus = _PVStatus::Right; changetype = _PosChangeType::HideToRight; } } } else if(pvstatus == _PVStatus::Left) { if(curSel < 0) { pvstatus = _PVStatus::Hide; changetype = _PosChangeType::LeftToHide; } else if(curCol < 4 || (curCol == 4 && lastCol == 4)) { pvstatus = _PVStatus::Right; changetype = _PosChangeType::LeftToRight; } } else if(pvstatus == _PVStatus::Right) { if(curSel < 0) { pvstatus = _PVStatus::Hide; changetype = _PosChangeType::RightToHide; } else if(curCol > 10 || (curCol == 10 && lastCol == 10)) { pvstatus = _PVStatus::Left; changetype = _PosChangeType::RightToLeft; } } //刷新蓝色矩形框 UpdateSelectedFace(curPage, curSel, curFrame, pvstatus); this->Invalidate(); if(changetype == _PosChangeType::NoChange) { //刷新预览图片 if(pvstatus == _PVStatus::Left) { this->Invalidate(); //InvalidateRect(hDlg, &rcLeft, FALSE); } else if(pvstatus == _PVStatus::Right) { this->Invalidate(); //InvalidateRect(hDlg, &rcRight, FALSE); } } else { CopyRect(&rc1, &rcLeft); CopyRect(&rc2, &rcRight); rc1.right++; rc1.bottom++; rc2.right++; rc2.bottom++; //擦除原位置的缩略图 switch(changetype & 0xf0) { case 0x00: break; case 0x10: this->Invalidate(); //InvalidateRect(hDlg, &rc1, FALSE); break; case 0x20: this->Invalidate(); //InvalidateRect(hDlg, &rc2, FALSE); break; } //显示新位置上的缩略图 switch(changetype & 0x0f) { case 0x00: pvstatus == _PVStatus::Hide; break; case 0x01: this->Invalidate(); //InvalidateRect(hDlg, &rc1, FALSE); break; case 0x02: this->Invalidate(); //InvalidateRect(hDlg, &rc2, FALSE); break; } } //安装定时器(显示动画) if(curSel >= 0) { UINT frameDelay = 200; CxImage* pImg = GetSelectedImage(curPage, curSel); CxImage* pFrame = pImg->GetFrame(curFrame); //QQ表情的帧延时通常是10毫秒,显示速度过快,因此增大到50毫秒 if(pFrame != NULL) frameDelay = max(frameDelay, pFrame->GetFrameDelay()); frameCount = pImg->GetNumFrames(); this->m_pManager->SetTimer(this, TIMER_SHOWGIF, frameDelay); } else { this->m_pManager->KillTimer(this, TIMER_SHOWGIF); } } //使系统通知我们 WM_MOUSELEAVE ; TrackMouseEvent(&m_tme); //注意版本需求:_WIN32_WINNT 0x0510 } break; case UIEVENT_MOUSELEAVE: { if(curSel >= 0) { RECT rc; GetBlueRect(curSel, &rc); lastSel = curSel; curSel = -1; curFrame = 0; pvstatus = _PVStatus::Hide; UpdateSelectedFace(curPage, curSel, curFrame, pvstatus); this->Invalidate(); //InvalidateRect(hDlg, &rc, FALSE); } } break; case UIEVENT_TIMER: { this->m_pManager->KillTimer(this, TIMER_SHOWGIF); if(curSel >= 0 && frameCount > 1) { CxImage *pImg = GetSelectedImage(curPage, curSel); CxImage *pFrame = NULL; UINT frameDelay = 200; LPRECT lpRect = (pvstatus == _PVStatus::Left)? &rcLeft:&rcRight; //移动到下一帧! curFrame = (curFrame + 1) % frameCount; //QQ表情的帧延时通常是10毫秒,显示速度过快,因此增大到100毫秒 pFrame = pImg->GetFrame(curFrame); if(pFrame) frameDelay = max(frameDelay, pFrame->GetFrameDelay()); UpdateSelectedFace(curPage, curSel, curFrame, pvstatus); this->Invalidate(); //InvalidateRect(hDlg, lpRect, FALSE); //下一帧的定时时间 this->m_pManager->SetTimer(this, TIMER_SHOWGIF, frameDelay); } } break; } }
bool CSakiBoard::IsOccupied(int x, int y) { auto index = GetCellIndex(x, y); return (m_cells[index] != 0); }