void plRTSpotLight::GetLocalBoundBox( TimeValue t, INode *node, ViewExp *vpt, Box3 &box ) { Point3 loc = node->GetObjectTM( t ).GetTrans(); float scaleFactor = vpt->NonScalingObjectSize() * vpt->GetVPWorldWidth( loc ) / 360.0f; float width, depth; box = fMesh.getBoundingBox(); // Because we want to scale about the origin, not the box center, we have to do this funky offset Point3 boxCenter = box.Center(); box.Translate( -boxCenter ); box.Scale( scaleFactor ); boxCenter *= scaleFactor; box.Translate( boxCenter ); // Include points for the spotlight. That means either the attenuated cone or // our unattenuated cone display if( ( extDispFlags & EXT_DISP_ONLY_SELECTED ) ) { if( GetUseAtten() ) depth = GetAtten( t, ATTEN_END ); else depth = 100.f + 50.f; // Include arrows width = depth * tan( DegToRad( GetFallsize( t ) / 2.f ) ); box += Point3( -width, -width, 0.f ); box += Point3( width, width, -depth ); } }
bool Ray::IntersectBox( Box3 a_box, matrix a_mat_transform ) { // translate by position a_mat_transform = a_mat_transform * matrix::Translation( a_box.GetCenter() ); v3 halfsize = a_box.Size()*0.5f; float tmin = -FLT_MAX; float tmax = FLT_MAX; v4 nmin; v4 nmax; const v4 p = a_mat_transform.w - v4(m_pos,1.0f); for ( size_t i=0; i!=3; ++i ) { v4 box_basis_vector = a_mat_transform[i]; const float e = dot( box_basis_vector, p ); float f = dot( box_basis_vector, v4(m_dir,0.0f) ); if ( fabs(f) > EPSILON ) { f = 1.0f/f; float t1 = ( e + halfsize[i] ) * f; float t2 = ( e - halfsize[i] ) * f; float flip = 1.f; if ( t1 > t2 ) { // swap float tmp = t1; t1 = t2; t2 = tmp; flip = -flip; } if ( t1 > tmin ) { tmin = t1; nmin = a_mat_transform[i] * flip; } if ( t2 < tmax ) { tmax = t2; nmax =-a_mat_transform[i] * flip; } if ( tmin > tmax ) return false; if ( tmax < 0.f ) return false; } else if ( ( ( -e - halfsize[i] ) > 0.f ) || ( ( -e + halfsize[i] ) < 0.f ) ) { // ray parallel to the stab return false; } } if ( tmin > 0.f ) return NewHit( tmin, nmin.xyz() ); return NewHit( tmax, nmax.xyz() ); }
void WindObject::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } Box3 meshBox; Matrix3 mat = inode->GetObjectTM(t); box.Init(); int hoopson; pblock2->GetValue(PB_HOOPSON,t,hoopson,FOREVER); if (hoopson) { float decay; pblock2->GetValue(PB_DECAY,t,decay,FOREVER); if (decay>0.0f) { float range,xy; range=2.0f*(decay > 0.0f?0.6931472f / decay:0.0f); int type;pblock2->GetValue(PB_TYPE,t,type,ivalid); if (type==FORCE_PLANAR) { pblock2->GetValue(PB_DISPLENGTH,t,xy,FOREVER); xy*=3.0f; } else xy=range; Box3 rangeBox(Point3(-xy,-xy,-range),Point3(xy,xy,range)); for(int i = 0; i < 8; i++) box += mat * rangeBox[i]; } } GetLocalBoundBox(t,inode,vpt,meshBox); for(int i = 0; i < 8; i++) box += mat * meshBox[i]; }
/* void ParticleMesherObject::GetWorldBoundBox(TimeValue t, INode * inode, ViewExp* vp, Box3& box ) { box.Init(); Matrix3 mat = inode->GetObjectTM(t); Point3 a(-10.0f,-10.0f,-10.0f); Point3 b(10.0f,10.0f,10.0f); a = a * mat; b = b * mat; box+= a; box+= b; } void ParticleMesherObject::GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vp, Box3& box ) { box.Init(); Point3 a(-10.0f,-10.0f,-10.0f); Point3 b(10.0f,10.0f,10.0f); box+= a; box+= b; } */ void ParticleMesherObject::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel ) { BOOL useBounds; pblock2->GetValue(particlemesher_usecustombounds, 0, useBounds, FOREVER); if (useBounds) { box.Init(); Point3 a(-10.0f,-10.0f,-10.0f); Point3 b(10.0f,10.0f,10.0f); pblock2->GetValue(particlemesher_customboundsa, 0, a, FOREVER); pblock2->GetValue(particlemesher_customboundsb, 0, b, FOREVER); if (tm) { a = a * *tm; b = b * *tm; } box+= a; box+= b; if (box.IsEmpty()) SimpleObject2::GetDeformBBox(t,box,tm,useSel); } else { SimpleObject2::GetDeformBBox(t,box,tm,useSel); } }
void EditFaceDataMod::GetSubObjectTMs (SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) { if (!mc->localData) return; if (selLevel == SEL_OBJECT) return; // shouldn't happen. EditFaceDataModData *modData = (EditFaceDataModData *) mc->localData; Mesh *mesh = modData->GetCacheMesh(); MNMesh *mnmesh = modData->GetCacheMNMesh(); if (!mesh && !mnmesh) return; Matrix3 tm = node->GetObjectTM(t); Box3 box; if (mesh) { BitArray sel = mesh->VertexTempSel (); if (!sel.NumberSet()) return; for (int i=0; i<mesh->numVerts; i++) if (sel[i]) box += mesh->verts[i] * tm; } else { int numSel, which; float value; bool valueDetermined; modData->DescribeSelection (numSel, which, value, valueDetermined); if (!numSel) return; if (numSel==1) { for (int j=0; j<mnmesh->f[which].deg; j++) box += mnmesh->P(mnmesh->f[which].vtx[j]) * tm; } else { for (int i=0; i<mnmesh->numf; i++) { if (mnmesh->f[i].GetFlag (MN_DEAD)) continue; if (!modData->GetFaceSel()[i]) continue; for (int j=0; j<mnmesh->f[i].deg; j++) box += mnmesh->P(mnmesh->f[i].vtx[j]) * tm; } } } Matrix3 ctm(1); ctm.SetTrans (box.Center()); cb->TM (ctm,0); }
void TapeHelpObject::GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } Matrix3 m = inode->GetObjectTM(t); Point3 pt; Point3 q[4]; float scaleFactor = vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(m.GetTrans())/(float)360.0; box = mesh.getBoundingBox(); box.Scale(scaleFactor); float d; if (GetTargetPoint(t,inode,pt)) { d = Length(m.GetTrans()-pt)/Length(inode->GetObjectTM(t).GetRow(2)); box += Point3(float(0),float(0),-d); } if(GetSpecLen()) { GetLinePoints(t, q, GetLength(t) ); box += q[0]; box += q[1]; } }
/****************************************************************************** * Computes the bounding box of the 3d visual viewport overlay rendered by the input mode. ******************************************************************************/ Box3 ParticleInformationInputMode::overlayBoundingBox(Viewport* vp, ViewportSceneRenderer* renderer) { Box3 bbox = ViewportInputMode::overlayBoundingBox(vp, renderer); for(const auto& pickedParticle : _pickedParticles) bbox.addBox(selectionMarkerBoundingBox(vp, pickedParticle)); return bbox; }
void TapeHelpObject::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } int i, nv; Matrix3 tm; float dtarg; Point3 pt; Point3 q[2]; GetMat(t,inode,*vpt,tm); nv = mesh.getNumVerts(); box.Init(); for (i=0; i<nv; i++) box += tm*mesh.getVert(i); if (GetTargetPoint(t,inode,pt)) { tm = inode->GetObjectTM(t); dtarg = Length(tm.GetTrans()-pt)/Length(tm.GetRow(2)); box += tm*Point3(float(0),float(0),-dtarg); } if(GetSpecLen()) { GetLinePoints(t, q, GetLength(t) ); box += tm * q[0]; box += tm * q[1]; } }
/****************************************************************************** * 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; } }
plLayerInterface* plLayerConverter::IConvertAngleAttenLayer(plPlasmaMAXLayer *layer, plMaxNode *maxNode, uint32_t blendFlags, bool preserveUVOffset, bool upperLayer) { hsGuardBegin( "plPlasmaMAXLayer::IConvertAngleAttenLayer" ); if( !upperLayer ) { fErrorMsg->Set(true, maxNode->GetName(), "Angle Attenuation layers can only be used as a top layer").Show(); fErrorMsg->Set(); return nil; } plAngleAttenLayer* aaLay = (plAngleAttenLayer*)layer; Box3 fade = aaLay->GetFade(); float tr0 = cosf(DegToRad(180.f - fade.Min().x)); float op0 = cosf(DegToRad(180.f - fade.Min().y)); float tr1 = cosf(DegToRad(180.f - fade.Max().x)); float op1 = cosf(DegToRad(180.f - fade.Max().y)); int loClamp = aaLay->GetLoClamp(); int hiClamp = aaLay->GetHiClamp(); int uvwSrc = aaLay->Reflect() ? plLayerInterface::kUVWReflect : plLayerInterface::kUVWNormal; plLayer* lut = ICreateAttenuationLayer(plString::FromUtf8(layer->GetName()), maxNode, uvwSrc, tr0, op0, tr1, op1, loClamp, hiClamp); return lut; hsGuardEnd; }
void plRTProjDirLight::GetLocalBoundBox( TimeValue t, INode *node, ViewExp *vpt, Box3 &box ) { Point3 loc = node->GetObjectTM( t ).GetTrans(); float scaleFactor = vpt->NonScalingObjectSize() * vpt->GetVPWorldWidth( loc ) / 360.0f; float width, height, depth; box = fMesh.getBoundingBox(); // Because we want to scale about the origin, not the box center, we have to do this funky offset Point3 boxCenter = box.Center(); box.Translate( -boxCenter ); box.Scale( scaleFactor ); boxCenter *= scaleFactor; box.Translate( boxCenter ); if( ( extDispFlags & EXT_DISP_ONLY_SELECTED ) ) { fProjPB->GetValue( kWidth, t, width, FOREVER ); fProjPB->GetValue( kHeight, t, height, FOREVER ); fProjPB->GetValue( kRange, t, depth, FOREVER ); width /= 2.f; height /= 2.f; box += Point3( -width, -height, 0.f ); box += Point3( width, height, -depth ); } }
Box3 SceneEnumProc::Bound() { Box3 bound; bound.Init(); MySceneEntry *e = head; #if _3DSMAX_VERSION >= 2013 ViewExp &vpt = i->GetViewExp(NULL); #else ViewExp *vpt = i->GetViewport(NULL); #endif while(e) { Box3 bb; #if _3DSMAX_VERSION >= 2013 e->obj->GetWorldBoundBox(time, e->node, &vpt, bb); #else e->obj->GetWorldBoundBox(time, e->node, vpt, bb); #endif bound += bb; e = e->next; } return bound; }
hsBool plMaxNodeBase::Contains(const Point3& worldPt) { TimeValue currTime = 0;//hsConverterUtils::Instance().GetTime(GetInterface()); Object *obj = EvalWorldState(currTime).obj; if( !obj ) return false; Matrix3 l2w = GetObjectTM(currTime); Matrix3 w2l = Inverse(l2w); Point3 pt = w2l * worldPt; if( obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0) ) { DummyObject* dummy = (DummyObject*)obj; Box3 bnd = dummy->GetBox(); return bnd.Contains(pt); } if( obj->CanConvertToType(triObjectClassID) ) { TriObject *meshObj = (TriObject *)obj->ConvertToType(currTime, triObjectClassID); if( !meshObj ) return false; Mesh& mesh = meshObj->mesh; Box3 bnd = mesh.getBoundingBox(); if( !bnd.Contains(pt) ) { if( meshObj != obj ) meshObj->DeleteThis(); return false; } hsBool retVal = true; int i; for( i = 0; i < mesh.getNumFaces(); i++ ) { Face& face = mesh.faces[i]; Point3 p0 = mesh.verts[face.v[0]]; Point3 p1 = mesh.verts[face.v[1]]; Point3 p2 = mesh.verts[face.v[2]]; Point3 n = CrossProd(p1 - p0, p2 - p0); if( DotProd(pt, n) > DotProd(p0, n) ) { retVal = false; break; } } if( meshObj != obj ) meshObj->DeleteThis(); return retVal; } // If we can't figure out what it is, the point isn't inside it. return false; }
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; }
Mesh* TriPatchObject::GetRenderMesh(TimeValue t, INode *inode, View& view, BOOL& needDelete) { UpdatePatchMesh(t); TessApprox tess = patch.GetProdTess(); if (tess.type == TESS_SET) { needDelete = FALSE; patch.InvalidateMesh(); // force this... // temporarlily set the view tess to prod tess TessApprox tempTess = patch.GetViewTess(); patch.SetViewTess(tess); PrepareMesh(t); patch.SetViewTess(tempTess); return &patch.GetMesh(); } else { Mesh *nmesh = new Mesh/*(mesh)*/; Matrix3 otm = inode->GetObjectTM(t); Box3 bbox; GetDeformBBox(t, bbox); tess.merge *= Length(bbox.Width())/1000.0f; TessApprox disp = patch.GetDispTess(); disp.merge *= Length(bbox.Width())/1000.0f; GetGTessFunction(); (*psGTessFunc)(&patch, BEZIER_PATCH, &otm, nmesh, &tess, &disp, &view, inode->GetMtl(), FALSE, FALSE); if (tess.merge > 0.0f && patch.GetProdTessWeld()) WeldMesh(nmesh, tess.merge); needDelete = TRUE; return nmesh; } }
void ParticleMesherObject::UpdateUI() { Point3 min,max; pblock2->GetValue(particlemesher_customboundsa,0,min,FOREVER); pblock2->GetValue(particlemesher_customboundsb,0,max,FOREVER); Box3 box; box.Init(); box += min; box += max; TSTR text; BOOL useBounds; pblock2->GetValue(particlemesher_usecustombounds, 0, useBounds, FOREVER); if (useBounds) { if (box.IsEmpty()) text.printf(_T("%s"),GetString(IDS_EMPTY)); else { text.printf(_T("(%0.0f,%0.0f,%0.0f)"),min.x,min.y,min.z); SetWindowText(GetDlgItem(hParams,IDC_BOUNDSTEXT), text); text.printf(_T("(%0.0f,%0.0f,%0.0f)"),max.x,max.y,max.z); SetWindowText(GetDlgItem(hParams,IDC_BOUNDSTEXT2), text); } //make sure we only enable the button in the modify panel // bug 257747 1/30/01 watje if (ip) { ICustButton *iBut = GetICustButton(GetDlgItem(hParams,IDC_PICKBB)); if (ip->GetCommandPanelTaskMode()==TASK_MODE_MODIFY) { if (iBut) iBut->Enable(TRUE); } ReleaseICustButton(iBut); } } else { text.printf(_T(" ")); SetWindowText(GetDlgItem(hParams,IDC_BOUNDSTEXT), text); text.printf(_T(" ")); SetWindowText(GetDlgItem(hParams,IDC_BOUNDSTEXT2), text); ICustButton *iBut = GetICustButton(GetDlgItem(hParams,IDC_PICKBB)); if (iBut) iBut->Enable(FALSE); ReleaseICustButton(iBut); } }
int UVW_ChannelClass::EdgeIntersect(Point3 p, float threshold, int i1,int i2) { static int startEdge = 0; if (startEdge >= ePtrList.Count()) startEdge = 0; if (ePtrList.Count() == 0) return -1; int ct = 0; BOOL done = FALSE; int hitEdge = -1; while (!done) { //check bounding volumes Box3 bounds; bounds.Init(); int index1 = ePtrList[startEdge]->a; int index2 = ePtrList[startEdge]->b; if (v[index1].IsHidden() && v[index2].IsHidden()) { } else if (v[index1].IsFrozen() && v[index1].IsFrozen()) { } else { Point3 p1(0.0f,0.0f,0.0f); p1[i1] = v[index1].GetP()[i1]; p1[i2] = v[index1].GetP()[i2]; // p1.z = 0.0f; bounds += p1; Point3 p2(0.0f,0.0f,0.0f); p2[i1] = v[index2].GetP()[i1]; p2[i2] = v[index2].GetP()[i2]; // p2.z = 0.0f; bounds += p2; bounds.EnlargeBy(threshold); if (bounds.Contains(p)) { //check edge distance if (LineToPoint(p, p1, p2) < threshold) { hitEdge = startEdge; done = TRUE; // LineToPoint(p, p1, p2); } } } ct++; startEdge++; if (ct == ePtrList.Count()) done = TRUE; if (startEdge >= ePtrList.Count()) startEdge = 0; } return hitEdge; }
/* void extendBy(const XfBox3<Type> &bb) { } bool intersect(const Vec3<Type> &pt) const { Vec3<Type> p; m_invertedMatrix.multVecMatrix(pt, p); return Box3<Type>::intersect(p); } bool intersect(const Box3<Type> &bb) const { return false; } bool intersect (const XfBox3<Type> &bb) const { return false; } */ Box3<Type> project () const { Box3<Type> box = (Box3<Type>)*this; if (!box.isEmpty()) box.transform(m_matrix); return box; }
static inline void normalizeBox3(const Box3& target, const Box3& env, Box3& output) { auto scale = env.Diagonal(); auto center = env.Center(); output.Set((target.Min()-center)/scale*2.0, (target.Max()-center)/scale*2.0); }
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; }
//! Extend the boundaries of the box by the given \a a_box parameter. void extendBy(const Box3<Type> & a_box) { if(isEmpty()){ *this = a_box; }else{ extendBy(a_box.getMin()); extendBy(a_box.getMax()); } }
int MorphByBone::GetMirrorBone(int id) { int whichBone = 0; if (id == -1) whichBone = currentBone; else whichBone = id; //make sure it is a valid node if ((whichBone < 0) || (whichBone >= boneData.Count()) ) { return -1; } if (GetNode(whichBone) == NULL) return -1; Matrix3 itm = Inverse(localDataList[0]->selfObjectTM); Point3 mirrorMin, mirrorMax; Box3 mbox; mbox.Init(); mbox += boneData[whichBone]->localBounds.pmin * boneData[whichBone]->currentBoneObjectTM * itm; mbox += boneData[whichBone]->localBounds.pmax * boneData[whichBone]->currentBoneObjectTM * itm; mirrorMin = mbox.pmin; mirrorMax = mbox.pmax; int closestBone = -1; float closestDist = 0.0f; for (int i = 0; i < boneData.Count(); i++) { INode *node = GetNode(i); if (node) { Box3 box; box.Init(); box += boneData[i]->localBounds.pmin * boneData[i]->currentBoneObjectTM * itm * mirrorTM; box += boneData[i]->localBounds.pmax * boneData[i]->currentBoneObjectTM * itm * mirrorTM; Point3 min, max; min = box.pmin;// * boneData[i]->currentBoneObjectTM * itm * mirrorTM; max = box.pmax;// * boneData[i]->currentBoneObjectTM * itm * mirrorTM; float dist = Length(mirrorMin - min) + Length(mirrorMax - max); if ((closestBone == -1) || (dist < closestDist)) { closestBone = i; closestDist = dist; } } } return closestBone; }
void SimpleParticle::GetLocalBoundBox(TimeValue t, INode *inode,ViewExp* /*vpt*/, Box3& box ) { Matrix3 mat = inode->GetObjTMBeforeWSM(t); Box3 pbox; Update(t,inode); box = mesh.getBoundingBox(); pbox = parts.BoundBox(); if (!pbox.IsEmpty()) box += pbox * Inverse(mat); }
/****************************************************************************** * Returns the bounding box that includes all selected nodes. ******************************************************************************/ Box3 SelectionSet::boundingBox(TimePoint time) const { Box3 bb; for(SceneNode* node : nodes()) { // Get node's world bounding box // and add it to global box. bb.addBox(node->worldBoundingBox(time)); } return bb; }
void SimpleParticle::GetWorldBoundBox(TimeValue t, INode *inode, ViewExp* vpt, Box3& box ) { Box3 pbox; Matrix3 mat = inode->GetObjTMBeforeWSM(t); UpdateMesh(t); box = mesh.getBoundingBox(); box = box * mat; pbox = parts.BoundBox(); if (!pbox.IsEmpty()) box += pbox; }
void bhkProxyObject::BuildColBox() { Box3 box; box.Init(); for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) { INode *tnode = NULL; pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i); if (tnode) { ObjectState os = tnode->EvalWorldState(0); Matrix3 wm = tnode->GetNodeTM(0); TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0)); if (tri) { Box3 box2; box2.Init(); Mesh& mesh = tri->GetMesh(); CalcAxisAlignedBox(mesh, box2, &wm); box += box2; } } } BuildBox(proxyMesh, box.Max().y-box.Min().y, box.Max().x-box.Min().x, box.Max().z-box.Min().z); MNMesh mn(proxyMesh); Matrix3 tm(true); tm.SetTranslate(box.Center()); mn.Transform(tm); mn.OutToTri(proxyMesh); //proxyPos = box.Center(); proxyPos = Point3::Origin; forceRedraw = true; }
/****************************************************************************** * 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; }
bool Box3::containsBox( const Box3& box ) const { if ( ( mMin.x() <= box.min().x() ) && ( box.max().x() <= mMax.x() ) && ( mMin.y() <= box.min().y() ) && ( box.max().y() <= mMax.y() ) && ( mMin.z() <= box.min().z() ) && ( box.max().z() <= mMax.z() ) ) { return true; } return false; }
bool Wml::InBox (const Vector3<Real>& rkPoint, const Box3<Real>& rkBox, Real fEpsilon) { Vector3<Real> kDiff = rkPoint - rkBox.Center(); for (int i = 0; i < 3; i++) { Real fCoeff = kDiff.Dot(rkBox.Axis(i)); if ( Math<Real>::FAbs(fCoeff) > rkBox.Extent(i) + fEpsilon ) return false; } return true; }
void UniformGrid::ClosestPoint(Point3 p, float radius, int &pindex, float &d) { xHitList.ClearAll(); yHitList.ClearAll(); zHitList.ClearAll(); hitList.SetCount(0); //find the cell in the XGrid TagCells(p,radius, 0); //find the cell in the YGrid TagCells(p,radius, 1); //find the cell in the ZGrid TagCells(p,radius, 2); BitArray usedList; usedList.SetSize(pointBase.Count()); usedList.ClearAll(); int closest = -1; d = 0.0f; Box3 localBounds; localBounds.Init(); localBounds += p; localBounds.EnlargeBy(radius); for (int i = 0; i < hitList.Count(); i++) { int index = hitList[i]; if (!usedList[index]) //check to see if we have processed this one or not { if (xHitList[index] && yHitList[index] && zHitList[index]) { usedList.Set(index); Point3 source = pointBase[index]; if (localBounds.Contains(source)) { float dist = LengthSquared(source-p); if ((dist < d) || (closest == -1)) { d = dist; closest = index; } } } } } pindex = closest; d = sqrt(d); }