BOOL plDistributor::ISpaceClear(int iRepNode, const Matrix3& l2w, Box3& clearBox, plMeshCacheTab& cache) const { if( !fDistTree ) return true; // If we have high isolation, // clearBox = Box3(Point3(-fSpacing*0.5f, -fSpacing*0.5f, 0), Point3(fSpacing*0.5f, fSpacing*0.5f, fSpacing)); // Else if we have medium isolation // clearBox = cache[iRepNode]->getBoundingBox(); // The mesh's bounds // Else if we have low isolation or None isolation // clearBox = Box3(Point3(-kSmallSpace, -kSmallSpace, 0), Point3(kSmallSpace, kSmallSpace, kSmallSpace)); // kSmallSpace ~= 0.5f or one or something // We want to set up the box (for high, low and none) in Post OTM space. So instead of multiplying // by l2w, we want to multiply box = box * invOTM * l2w (because l2w already has OTM folded in). When using // the mesh bounds (Medium), l2w is the right transform. // objectTM = otm * nodeTM // invOTM * objectTM = nodeTM // invOTM = nodeTM * invObjectTM const float kSmallSpace = 0.5f; switch( fIsolation ) { case kIsoHigh: { INode* repNode = fRepNodes[iRepNode]; Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0)); Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0)); Matrix3 invOTM = nodeTM * Inverse(objectTM); clearBox = Box3(Point3(-fSpacing*0.5f, -fSpacing*0.5f, 0.f), Point3(fSpacing*0.5f, fSpacing*0.5f, fSpacing)); clearBox = clearBox * invOTM; } break; case kIsoMedium: clearBox = cache[iRepNode].fMesh->getBoundingBox(); // The mesh's bounds break; case kIsoLow: case kIsoNone: default: { INode* repNode = fRepNodes[iRepNode]; Matrix3 objectTM = repNode->GetObjectTM(TimeValue(0)); Matrix3 nodeTM = repNode->GetNodeTM(TimeValue(0)); Matrix3 invOTM = nodeTM * Inverse(objectTM); clearBox = Box3(Point3(-kSmallSpace, -kSmallSpace, 0.f), Point3(kSmallSpace, kSmallSpace, kSmallSpace)); clearBox = clearBox * invOTM; } break; } clearBox = clearBox * l2w; return fDistTree->BoxClear(clearBox, fFade); }
BOOL plDistributor::IConformCheck(Matrix3& l2w, int iRepNode, plMeshCacheTab& cache, int& iCache) const { Matrix3 OTM = IOTM(iRepNode); Mesh* mesh = cache[iRepNode].fMesh; Point3 dir = l2w.VectorTransform(Point3(0.f, 0.f, 1.f)); dir = FNormalize(dir); const float kOneOverSqrt2 = 0.707107f; Point3 scalePt(kOneOverSqrt2, kOneOverSqrt2, 0.f); scalePt = l2w.VectorTransform(scalePt); float maxScaledDist = fMaxConform * scalePt.Length(); Box3 bnd = mesh->getBoundingBox() * OTM; bnd = Box3(Point3(bnd.Min().x, bnd.Min().y, -bnd.Max().z), bnd.Max()); bnd = bnd * l2w; Tab<int32_t> faces; IFindFaceSet(bnd, faces); int i; for( i = 0; i < mesh->getNumVerts(); i++ ) { Point3 pt = mesh->getVert(i) * OTM; pt.z = 0; pt = pt * l2w; Point3 projPt; if( !IProjectVertex(pt, dir, maxScaledDist, faces, projPt) ) return false; } return true; }
Box3 plDistributor::ISetupGrid(const Point3& p0, const Point3& p1, const Point3& p2) const { // Add half spacing to max's to protect against precision errors. Box3 box(p0, p0); box += p1; box += p2; Point3 mins, maxs; int i; for( i = 0; i < 3; i++ ) { float t = box.Min()[i]; t /= fSpacing; t = floor(t); t *= fSpacing; mins[i] = t; t = box.Max()[i]; t /= fSpacing; t = ceil(t); t *= fSpacing; maxs[i] = t + fSpacing*0.5f; } box = Box3(mins, maxs); return box; }
/****************************************************************************** * Renders the modifier's visual representation and computes its bounding box. ******************************************************************************/ Box3 SliceModifier::renderVisual(TimePoint time, ObjectNode* contextNode, SceneRenderer* renderer) { TimeInterval interval; Box3 bb = contextNode->localBoundingBox(time); if(bb.isEmpty()) return Box3(); Plane3 plane = slicingPlane(time, interval); FloatType sliceWidth = 0; if(_widthCtrl) sliceWidth = _widthCtrl->getFloatValue(time, interval); ColorA color(0.8f, 0.3f, 0.3f); if(sliceWidth <= 0) { return renderPlane(renderer, plane, bb, color); } else { plane.dist += sliceWidth / 2; Box3 box = renderPlane(renderer, plane, bb, color); plane.dist -= sliceWidth; box.addBox(renderPlane(renderer, plane, bb, color)); return box; } }
/****************************************************************************** * Computes the bounding box of the visual representation of the modifier. ******************************************************************************/ Box3 SliceModifier::boundingBox(TimePoint time, ObjectNode* contextNode, ModifierApplication* modApp) { if(isBeingEdited()) return renderVisual(time, contextNode, nullptr); else return Box3(); }
Box3 plDistribComponent_old::GetFade() { Point3 pmin; if( fCompPB->GetInt(kFadeInActive) ) { pmin.Set(fCompPB->GetFloat(kFadeInTran), fCompPB->GetFloat(kFadeInOpaq), 0); if( pmin[0] == pmin[1] ) pmin[2] = 0; else if( pmin[0] < pmin[1] ) pmin[2] = -1.f; else pmin[2] = 1.f; } else { pmin.Set(0.f,0.f,0.f); } Point3 pmax; pmax.Set(fCompPB->GetFloat(kFadeOutTran), fCompPB->GetFloat(kFadeOutOpaq), 0); if( pmax[0] == pmax[1] ) pmax[2] = 0; else if( pmax[0] < pmax[1] ) pmax[2] = -1.f; else pmax[2] = 1.f; return Box3(pmin, pmax); }
void PointHelpObject::GetWorldBoundBox( TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } Matrix3 tm; tm = inode->GetObjectTM(t); Box3 lbox; GetLocalBoundBox(t, inode, vpt, lbox); box = Box3(tm.GetTrans(), tm.GetTrans()); for (int i=0; i<8; i++) { box += lbox * tm; } /* if(!(extDispFlags & EXT_DISP_ZOOM_EXT) && showAxis) box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, FALSE); else box = Box3(tm.GetTrans(), tm.GetTrans()); */ }
BOOL plDistributor::IConformAll(Matrix3& l2w, int iRepNode, plMeshCacheTab& cache, int& iCache) const { Matrix3 OTM = IOTM(iRepNode); Mesh* mesh = cache[iRepNode].fMesh; Point3 dir = l2w.VectorTransform(Point3(0.f, 0.f, 1.f)); dir = FNormalize(dir); const float kOneOverSqrt2 = 0.707107f; Point3 scalePt(kOneOverSqrt2, kOneOverSqrt2, 0.f); scalePt = l2w.VectorTransform(scalePt); float maxScaledDist = fMaxConform * scalePt.Length(); Box3 bnd = mesh->getBoundingBox() * OTM; bnd = Box3(Point3(bnd.Min().x, bnd.Min().y, -bnd.Max().z), bnd.Max()); bnd = bnd * l2w; Tab<int32_t> faces; IFindFaceSet(bnd, faces); // l2w, iRepNode, cache, &iCache, maxScaledDist, dir iCache = cache.Count(); cache.SetCount(iCache + 1); cache[iCache] = cache[iRepNode]; cache[iCache].fMesh = new Mesh(*mesh); mesh = cache[iCache].fMesh; Matrix3 v2w = OTM * l2w; Matrix3 w2v = Inverse(v2w); BOOL retVal = true; int i; for( i = 0; i < mesh->getNumVerts(); i++ ) { Point3 pt = mesh->getVert(i) * OTM; pt.z = 0; pt = pt * l2w; Point3 projPt; if( !IProjectVertex(pt, dir, maxScaledDist, faces, projPt) ) { retVal = false; break; } Point3 del = w2v.VectorTransform(projPt - pt); mesh->getVert(i) += del; } if( !retVal ) { // delete cache[iCache].fMesh; delete mesh; cache.SetCount(iCache); iCache = iRepNode; } return retVal; }
void MainState::layoutScreen() { int w = _game->window()->width(); int h = _game->window()->height(); glViewport(0, 0, w, h); _camera.setViewBox(Box3( Vector3( 0, 0, -1), Vector3(640, 640 * h / w, 1) )); }
Box3 Sphere::getBoundingBox( ) const { auto result = Box3(); getBoundingBox( result ); return result; }
static void computeBestFitOBB(TheaArray<Vector3> const & points, Box3 & result, bool has_up, Vector3 const & up) { if (points.empty()) { result = Box3(); return; } else if (points.size() == 1) { result = Box3(AxisAlignedBox3(points[0])); return; } Vector3 centroid; CoordinateFrame3 cframe; if (has_up) { centroid = CentroidN<Vector3, 3>::compute(points.begin(), points.end()); Vector3 u, v; up.createOrthonormalBasis(u, v); cframe = CoordinateFrame3::_fromAffine(AffineTransform3(basisMatrix(u, v, up), centroid)); } else { Plane3 plane; LinearLeastSquares3<Vector3>::fitPlane(points.begin(), points.end(), plane, ¢roid); planeToCFrame(plane, centroid, cframe); } OBB best_obb; computeOBB(points, cframe, best_obb, true); Matrix3 rot = Matrix3::rotationAxisAngle((has_up ? up : Vector3::unitY()), Math::degreesToRadians(10)); for (int a = 10; a < 180; a += 10) { cframe._setRotation(cframe.getRotation() * rot); computeOBB(points, cframe, best_obb, false); } result = Box3(AxisAlignedBox3(best_obb.lo, best_obb.hi), best_obb.cframe); }
Line::Line(float x, float y, float toX, float toY){ this->x = x; this->y = y; this->toX = toX; this->toY = toY; drawLine(x, y, toX, toY, 0, 0); _bounds = Box3(x, y, toX - x, toY - y); }
Sphere& Sphere::setFromPoints( const std::vector<Vector3>& points) { auto box = Box3(); auto center = Vector3(); box.setFromPoints( points ).center( center ); return setFromPoints(points, center); }
/****************************************************************************** * Computes the bounding box of the the 3D visual elements * shown only in the interactive viewports. ******************************************************************************/ Box3 ViewportSceneRenderer::boundingBoxInteractive(TimePoint time, Viewport* viewport) { OVITO_CHECK_POINTER(viewport); Box3 bb; // Visit all pipeline objects in the scene. renderDataset()->sceneRoot()->visitObjectNodes([this, viewport, time, &bb](ObjectNode* node) -> bool { // Ignore node if it is the view node of the viewport or if it is the target of the view node. if(viewport->viewNode()) { if(viewport->viewNode() == node || viewport->viewNode()->lookatTargetNode() == node) return true; } // Evaluate geometry pipeline of object node. const PipelineFlowState& state = node->evalPipeline(time); for(const auto& dataObj : state.objects()) { for(DisplayObject* displayObj : dataObj->displayObjects()) { if(displayObj && displayObj->isEnabled()) { TimeInterval interval; bb.addBox(displayObj->viewDependentBoundingBox(time, viewport, dataObj, node, state).transformed(node->getWorldTransform(time, interval))); } } } if(PipelineObject* pipelineObj = dynamic_object_cast<PipelineObject>(node->dataProvider())) boundingBoxModifiers(pipelineObj, node, bb); return true; }); // Include visual geometry of input mode overlays in bounding box. MainWindow* mainWindow = viewport->dataset()->mainWindow(); if(mainWindow) { for(const auto& handler : mainWindow->viewportInputManager()->stack()) { if(handler->hasOverlay()) bb.addBox(handler->overlayBoundingBox(viewport, this)); } } // Include construction grid in bounding box. if(viewport->isGridVisible()) { FloatType gridSpacing; Box2I gridRange; std::tie(gridSpacing, gridRange) = determineGridRange(viewport); if(gridSpacing > 0) { bb.addBox(viewport->gridMatrix() * Box3( Point3(gridRange.minc.x() * gridSpacing, gridRange.minc.y() * gridSpacing, 0), Point3(gridRange.maxc.x() * gridSpacing, gridRange.maxc.y() * gridSpacing, 0))); } } return bb; }
void PointHelpObject::GetLocalBoundBox( TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } Matrix3 tm = inode->GetObjectTM(t); float size; int screenSize; pblock2->GetValue(pointobj_size, t, size, FOREVER); pblock2->GetValue(pointobj_screensize, t, screenSize, FOREVER); float zoom = 1.0f; if (screenSize) { zoom = vpt->GetScreenScaleFactor(tm.GetTrans())*ZFACT; } if (zoom==0.0f) zoom = 1.0f; size *= zoom; box = Box3(Point3(0,0,0), Point3(0,0,0)); box += Point3(size*0.5f, 0.0f, 0.0f); box += Point3( 0.0f, size*0.5f, 0.0f); box += Point3( 0.0f, 0.0f, size*0.5f); box += Point3(-size*0.5f, 0.0f, 0.0f); box += Point3( 0.0f, -size*0.5f, 0.0f); box += Point3( 0.0f, 0.0f, -size*0.5f); //JH 6/18/03 //This looks odd but I'm being conservative an only excluding it for //the case I care about which is when computing group boxes // box.EnlargeBy(10.0f/zoom); if(!(extDispFlags & EXT_DISP_GROUP_EXT)) box.EnlargeBy(10.0f/zoom); /* if (showAxis) box = GetAxisBox(vpt,tm,showAxis?axisLength:0.0f, TRUE); else box = Box3(Point3(0,0,0), Point3(0,0,0)); */ }
ptr<Box3> Box3::create( glm::vec3 min_vec, glm::vec3 max_vec ){ return make_shared<Box3>( Box3(min_vec, max_vec) ); }
Box3 CJRenderMapsContext::ObjectSpaceBoundingBox() { return Box3();// TBD }
InputField::InputField(float x, float y, float width, float height, Color color) : _hasFocus(false), _text("") { setPosition(Vector3(x, y)); _color = color; this->setBoundingBox(Box3(x, y, width, height)); }
Box3 Box3::clone() const { return Box3(*this); }
Box3 Box3::clone() { return Box3(*this); }
Box3 plMaxNodeBase::GetFade() { GetMD; return (pMD) ? pMD->GetFade() : Box3(Point3(0,0,0), Point3(0,0,0)); }
void BufferGeometry::computeBoundingBox() { if ( !boundingBox ) { boundingBox = Box3(); } const auto& p = attributes.get( AttributeKey::position() ); if ( p ) { const auto& positions = p->array; auto& bb = *boundingBox; if( positions.size() >= 3 ) { bb.min.x = bb.max.x = positions[ 0 ]; bb.min.y = bb.max.y = positions[ 1 ]; bb.min.z = bb.max.z = positions[ 2 ]; } for ( size_t i = 3, il = positions.size(); i < il; i += 3 ) { float x = positions[ i ]; float y = positions[ i + 1 ]; float z = positions[ i + 2 ]; // bounding box if ( x < bb.min.x ) { bb.min.x = x; } else if ( x > bb.max.x ) { bb.max.x = x; } if ( y < bb.min.y ) { bb.min.y = y; } else if ( y > bb.max.y ) { bb.max.y = y; } if ( z < bb.min.z ) { bb.min.z = z; } else if ( z > bb.max.z ) { bb.max.z = z; } } } if ( p == nullptr || p->array.size() == 0 ) { boundingBox->min.set( 0, 0, 0 ); boundingBox->max.set( 0, 0, 0 ); } }