// ********************************************************************************************************* void CDisplayerVisualEntity::drawBBox(const NLMISC::CMatrix &modelMatrix, const NLMISC::CAABBox &bbox, NLMISC::CRGBA colOverZ, NLMISC::CRGBA colUnderZ) { //H_AUTO(R2_CDisplayerVisualEntity_drawBBox) //nlwarning("bbox = (%f, %f, %f) - (%f, %f, %f), color = (%d, %d, %d, %d)", bbox.getMin().x, bbox.getMin().y, bbox.getMin().z, // bbox.getMax().x, bbox.getMax().y, bbox.getMax().z, (int) colOverZ.R, (int) colOverZ.G, (int) colOverZ.B, (int) colOverZ.A); // for z-precision, work with camera at (0, 0, 0) static volatile bool fixMatrixPos = false; CMatrix oldViewMatrix = Driver->getViewMatrix(); Driver->setModelMatrix(modelMatrix); CMatrix viewMat = oldViewMatrix; if (fixMatrixPos) { viewMat.setPos(CVector::Null); } Driver->setViewMatrix(viewMat); // draw below zbuffer UMaterial::ZFunc oldZfunc = GenericMat.getZFunc(); bool oldZWrite = GenericMat.getZWrite(); GenericMat.setZFunc(UMaterial::greater); GenericMat.setZWrite(false); ::drawBox(bbox.getMin(), bbox.getMax(), colUnderZ ); GenericMat.setZFunc(oldZfunc); GenericMat.setZWrite(oldZWrite); ::drawBox(bbox.getMin(), bbox.getMax(), colOverZ); Driver->setViewMatrix(oldViewMatrix); }
// *************************************************************************** void CVisualCollisionMesh::CStaticGrid::create(uint nbQuads, uint nbElts, const NLMISC::CAABBox &gridBBox) { /* *********************************************** * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance * It can be loaded/called through CAsyncFileManager for instance * ***********************************************/ nlassert(nbQuads>0 && isPowerOf2(nbQuads)); // init the grid _GridSize= nbQuads; _GridSizePower= getPowerOf2(nbQuads); _Grid.resize(_GridSize*_GridSize); // start with 0 elt in each case memset(_Grid.getPtr(), 0, _Grid.size() * sizeof(CCase)); // init the Elt Build _EltBuild.resize(nbElts); // total size is 0 _GridDataSize= 0; // bbox init _GridPos= gridBBox.getMin(); _GridScale= gridBBox.getSize(); _GridScale.x= _GridSize / _GridScale.x; _GridScale.y= _GridSize / _GridScale.y; // reset intersection data _ItSession= 0; }
// ********************************************************************************************************* void CDisplayerVisualShape::drawBBox(NLMISC::CRGBA color) const { //H_AUTO(R2_CDisplayerVisualShape_drawBBox) if (getRotateInProgress()) return; // no drawn while drawing (bbox moved one frame too late, must solve this) NLMISC::CAABBox bbox; _Instance.getShapeAABBox(bbox); Driver->setModelMatrix(_BBoxMatrix); ::drawBox(bbox.getMin(), bbox.getMax(), color); }
// ********************************************************************************************************* NLMISC::CAABBox CDisplayerVisualShape::getSelectBox() const { //H_AUTO(R2_CDisplayerVisualShape_getSelectBox) if (_Instance.empty()) return CDisplayerVisual::getSelectBox(); // TODO nico : cache the bbox NLMISC::CAABBox bbox; _Instance.getShapeAABBox(bbox); bbox.setMinMax(_Scale * bbox.getMin(), _Scale * bbox.getMax()); return bbox; }
// *************************************************************************** uint CVisualCollisionMesh::CStaticGrid::select(const NLMISC::CAABBox &bbox, std::vector<uint16> &res) { /* *********************************************** * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance * It can be loaded/called through CAsyncFileManager for instance * ***********************************************/ // increment the intersection session _ItSession++; // enlarge the result array as needed if(res.size()<_Sessions.size()) res.resize(_Sessions.size()); // the number of selected element uint numSel= 0; // compute the 2D bbox CVector minp= bbox.getMin() - _GridPos; CVector maxp= bbox.getMax() - _GridPos; sint xmin= (sint)floorf(minp.x*_GridScale.x); sint ymin= (sint)floorf(minp.y*_GridScale.y); sint xmax= (sint)ceilf(maxp.x*_GridScale.x); sint ymax= (sint)ceilf(maxp.y*_GridScale.y); clamp(xmin, 0, (sint)_GridSize-1); clamp(ymin, 0, (sint)_GridSize-1); clamp(xmax, xmin+1, (sint)_GridSize); clamp(ymax, ymin+1, (sint)_GridSize); // for each case touched, increment NumElts for(uint y=ymin;y<(uint)ymax;y++) { for(uint x=xmin;x<(uint)xmax;x++) { CCase &gcase= _Grid[(y<<_GridSizePower)+x]; // for each element in this case for(uint i= gcase.Start;i<gcase.Start + gcase.NumElts;i++) { uint elt= _GridData[i]; // if not alread inserted in the dest if(_Sessions[elt]!=_ItSession) { // mark as intersected _Sessions[elt]= _ItSession; // append res[numSel++]= elt; } } } } // return the number of selected elements return numSel; }
// ********************************************************************************************************* bool CDisplayerVisualEntity::isInProjection(const NLMISC::CVector2f &pos) const { //H_AUTO(R2_CDisplayerVisualEntity_isInProjection) if (getActualSelectionDisplayMode() == CircleSelection) return false; nlassert(getSelectionType() == LocalSelectBox || getSelectionType() == GroundProjected); CVector localPos = getInvertedMatrix() * pos; NLMISC::CAABBox selectBox = getSelectBox(); CVector pmin = selectBox.getMin(); CVector pmax = selectBox.getMax(); if (localPos.x < pmin.x || localPos.x > pmax.x || localPos.y < pmin.y || localPos.y > pmax.y) return false; return true; }
// *************************************************************************** void CVisualCollisionMesh::CStaticGrid::add(uint16 id, const NLMISC::CAABBox &bbox) { /* *********************************************** * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance * It can be loaded/called through CAsyncFileManager for instance * ***********************************************/ CVector minp= bbox.getMin() - _GridPos; CVector maxp= bbox.getMax() - _GridPos; // compute the 2D bbox sint xmin= (sint)floorf(minp.x*_GridScale.x); sint ymin= (sint)floorf(minp.y*_GridScale.y); sint xmax= (sint)ceilf(maxp.x*_GridScale.x); sint ymax= (sint)ceilf(maxp.y*_GridScale.y); clamp(xmin, 0, (sint)_GridSize-1); clamp(ymin, 0, (sint)_GridSize-1); clamp(xmax, xmin+1, (sint)_GridSize); clamp(ymax, ymin+1, (sint)_GridSize); // set in the elt build _EltBuild[id].X0= xmin; _EltBuild[id].Y0= ymin; _EltBuild[id].X1= xmax; _EltBuild[id].Y1= ymax; // for each case touched, increment NumElts for(uint y=ymin;y<(uint)ymax;y++) { for(uint x=xmin;x<(uint)xmax;x++) { _Grid[(y<<_GridSizePower)+x].NumElts++; _GridDataSize++; } } }