Exemplo n.º 1
0
std::tuple<vector<shared_ptr<Node>>,vector<shared_ptr<Particle>>> SphereClumpGeom::makeParticles(const shared_ptr<Material>& mat, const Vector3r& clumpPos, const Quaternionr& clumpOri, int mask, Real scale){
	ensureOk();
	assert(centers.size()==radii.size());
	const auto N=centers.size();
	if(N==1){ // fast path for a single sphere (do not clump at all)
		auto s=DemFuncs::makeSphere(radii[0]*scale,mat);
		s->mask=mask;
		s->shape->nodes[0]->pos=(isnan(clumpPos.maxCoeff())?centers[0]:clumpPos); // natural or forced position
		return std::make_tuple(vector<shared_ptr<Node>>({s->shape->nodes[0]}),vector<shared_ptr<Particle>>({s}));
	}
	vector<shared_ptr<Particle>> par(N);
	auto n=make_shared<Node>();
	auto cd=make_shared<ClumpData>();
	n->setData<DemData>(cd);
	n->pos=(isnan(clumpPos.maxCoeff())?pos:clumpPos);
	n->ori=clumpOri;
	cd->nodes.resize(N);
	cd->relPos.resize(N);
	cd->relOri.resize(N);
	for(size_t i=0; i<N; i++){
		par[i]=DemFuncs::makeSphere(radii[i]*scale,mat);
		par[i]->mask=mask;
		cd->nodes[i]=par[i]->shape->nodes[0];
		cd->nodes[i]->getData<DemData>().setClumped(n); // sets flag and assigned master node
		cd->relPos[i]=(centers[i]-pos)*scale;
		cd->relOri[i]=ori.conjugate(); // nice to set, but not really important
	}
	// sets particles in global space based on relPos, relOri
	ClumpData::applyToMembers(n);
	// set clump properties
	assert(!isnan(volume));
	cd->setClump(); assert(cd->isClump());
	// scale = length scale (but not density scale)
	cd->mass=mat->density*volume*pow(scale,3);
	cd->inertia=mat->density*inertia*pow(scale,5);
	cd->equivRad=equivRad;
	return std::make_tuple(vector<shared_ptr<Node>>({n}),par);
}
Exemplo n.º 2
0
void ActReactGlRep::renderDoubleArrow(const Vector3r& pos, const Vector3r& arr, bool posStart, const Vector3r& offset, const Vector3r& color){
	if(isnan(color.maxCoeff())) return;
	if(posStart){ GLUtils::GLDrawArrow(pos+offset,pos+offset+arr,color); GLUtils::GLDrawArrow(pos-offset,pos-offset-arr,color); }
	else        { GLUtils::GLDrawArrow(pos+offset-arr,pos+offset,color); GLUtils::GLDrawArrow(pos-offset+arr,pos-offset,color); }
}
Exemplo n.º 3
0
void TraceVisRep::render(const shared_ptr<Node>& n, const GLViewInfo* glInfo){
	if(isHidden() || !tracer) return;
	if(!tracer->glSmooth) glDisable(GL_LINE_SMOOTH);
	else glEnable(GL_LINE_SMOOTH);
	glDisable(GL_LIGHTING);
	bool scale=(glInfo->renderer->dispScale!=Vector3r::Ones() && glInfo->renderer->scaleOn && n->hasData<GlData>());
	glLineWidth(tracer->glWidth);
	const bool periodic=glInfo->scene->isPeriodic;
	Vector3i prevPeriod=Vector3i::Zero(); // silence gcc warning maybe-uninitialized
	int nSeg=0; // number of connected vertices (used when trace is interruped by NaN)
	glBegin(GL_LINE_STRIP);
		for(size_t i=0; i<pts.size(); i++){
			size_t ix;
			// FIXME: use getPointData here (copied code)
			// compressed start from the very beginning, till they reach the write position
			if(flags&FLAG_COMPRESS){
				ix=i;
				if(ix>=writeIx) break;
			// cycle through the array
			} else {
				ix=(writeIx+i)%pts.size();
			}
			if(!isnan(pts[ix][0])){
				Vector3r color;
				if(isnan(scalars[ix])){
					// if there is no scalar and no scalar should be saved, color by history position
					if(tracer->scalar==Tracer::SCALAR_NONE) color=tracer->lineColor->color((flags&FLAG_COMPRESS ? i*1./writeIx : i*1./pts.size()));
					// if other scalars are saved, use noneColor to not destroy tracer->lineColor range by auto-adjusting to bogus
					else color=tracer->noneColor;
				}
				else color=tracer->lineColor->color(scalars[ix]);
				if(isnan(color.maxCoeff())){
					if(nSeg>0){ glEnd(); glBegin(GL_LINE_STRIP); nSeg=0; } // break line, if there was something already
					continue; // point skipped completely
				}
				glColor3v(color);
				Vector3r pt(pts[ix]);
				if(periodic){
					// canonicalize the point, store the period
					Vector3i currPeriod;
					pt=glInfo->scene->cell->canonicalizePt(pt,currPeriod);
					// if the period changes between these two points, split the line (and don't render the segment in-between for simplicity)
					if(i>0 && currPeriod!=prevPeriod){
						if(nSeg>0){ glEnd(); glBegin(GL_LINE_STRIP); nSeg=0; } // only if there was sth already
						// point not skipped, only line interruped, so keep going
					}
					prevPeriod=currPeriod;
				}
				if(!scale) glVertex3v(pt);
				else{
					const auto& gl=n->getData<GlData>();
					// don't scale if refpos is invalid
					if(isnan(gl.refPos.maxCoeff())) glVertex3v(pt); 
					// x+(s-1)*(x-x0)
					else glVertex3v((pt+((glInfo->renderer->dispScale-Vector3r::Ones()).array()*(pt-gl.refPos).array()).matrix()).eval());
				}
				nSeg++;
			}
		}
	glEnd();
}