Ejemplo n.º 1
0
// Seed random number generator		
void BerconGradient::seedRandomGen(ShadeContext& sc) {
	int seed = 1;
	if (previewMatIDMode) {
		seed = sc.mtlNum;
	} else {
		if (p_randMat) { 		
			seed += sc.mtlNum;
		}
		if (p_randObj) {
			int hand = (int)sc.Node()->GetHandle();
			seed += hand*(hand*hand*15731 + 789221);
		}
		if (p_randPar) {
			Object *ob = sc.GetEvalObject();		
			if (ob && ob->IsParticleSystem()) {
				ParticleObject *obj = (ParticleObject*)ob;
				IChkMtlAPI* chkMtlAPI = static_cast<IChkMtlAPI*>(obj->GetInterface(I_NEWMTLINTERFACE));
				if ((chkMtlAPI && chkMtlAPI->SupportsParticleIDbyFace())) {
					int id = chkMtlAPI->GetParticleFromFace(sc.FaceNumber());
					seed += id*(id*id*571 + 789221);
				}			
			}
		}
		if (p_randTile) {
			seed += (int)(sc.UVW(99).z);
		}
	}

	seed *= p_seed;
	srand(seed*(seed*seed*15731 + 789221));	
}
Ejemplo n.º 2
0
/******************************************************************************
 *! dump particles if desired 
 *****************************************************************************/
void ParticleTracer::notifyOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename, double simtime) {
	debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"obj:"<<this->getName()<<" frame:"<<frameNrStr<<" dumpp"<<mDumpParts<<" t"<<simtime, 10); // DEBUG

	if(
			(dumptype==DUMP_FULLGEOMETRY)&&
			(mDumpParts>0)) {
		// dump to binary file
		std::ostringstream boutfilename("");
		boutfilename << outfilename <<"_particles_" << frameNrStr;
		if(glob_mpactive) {
			if(glob_mpindex>0) { boutfilename << "mp"<<glob_mpindex; }
		}
		boutfilename << ".gz";
		debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"B-Dumping: "<< this->getName() <<", particles:"<<mParts.size()<<" "<< " to "<<boutfilename.str()<<" #"<<frameNr , 7);
		//debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"B-Dumping: partgeodeb sim:"<<mSimStart<<","<<mSimEnd<<" geosize:"<<mStart<<","<<mEnd,2 );

		// output to zipped file
		gzFile gzf;
		gzf = gzopen(boutfilename.str().c_str(), "wb1");
		if(gzf) {
			int numParts;
			if(sizeof(numParts)!=4) { errMsg("ParticleTracer::notifyOfDump","Invalid int size"); return; }
			// only dump active particles
			numParts = 0;
			for(size_t i=0; i<mParts.size(); i++) {
				if(!mParts[i].getActive()) continue;
				numParts++;
			}
			gzwrite(gzf, &numParts, sizeof(numParts));
			for(size_t i=0; i<mParts.size(); i++) {
				if(!mParts[i].getActive()) { continue; }
				ParticleObject *p = &mParts[i];
				//int type = p->getType();  // export whole type info
				int type = p->getFlags(); // debug export whole type & status info
				ntlVec3Gfx pos = p->getPos();
				float size = p->getSize();

				if(type&PART_FLOAT) { // WARNING same handling for dump!
					// add one gridcell offset
					//pos[2] += 1.0; 
				} 
				// display as drop for now externally
				//else if(type&PART_TRACER) { type |= PART_DROP; }

				pos = (*mpTrafo) * pos;

				ntlVec3Gfx v = p->getVel();
				v[0] *= mpTrafo->value[0][0];
				v[1] *= mpTrafo->value[1][1];
				v[2] *= mpTrafo->value[2][2];
				// FIXME check: pos = (*mpTrafo) * pos;
				gzwrite(gzf, &type, sizeof(type)); 
				gzwrite(gzf, &size, sizeof(size)); 
				for(int j=0; j<3; j++) { gzwrite(gzf, &pos[j], sizeof(float)); }
				for(int j=0; j<3; j++) { gzwrite(gzf, &v[j], sizeof(float)); }
			}
			gzclose( gzf );
		}
	} // dump?
}
Ejemplo n.º 3
0
void gkParticleNode::update(Real tick)
{
	if (GET_SOCKET_VALUE(CREATE))
	{
		gkParticleObject* p = m_scene->createParticleObject(gkUtils::getUniqueName("gkParticleNode"));

		p->getParticleProperties().m_settings = GET_SOCKET_VALUE(PARTICLE_SYSTEM_NAME);
		p->createInstance();
		p->setOrientation(GET_SOCKET_VALUE(ORIENTATION));
		p->setPosition(GET_SOCKET_VALUE(POSITION));

		m_particles.push_back(new ParticleObject(p));
	}
	else
	{
		ParticleObjectIterator iter(m_particles);

		while (iter.hasMoreElements())
		{
			ParticleObject* p = iter.getNext();
			if (p->isExpired())
			{
				m_particles.erase(p);
				m_scene->destroyObject(p->m_parObj);
				delete p;
				//TODO: check iterator validation at erase.
			}
		}
	}
}
Ejemplo n.º 4
0
void PinMod::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{	ParticleObject *obj = GetParticleInterface(os->obj);
	if (obj)
	{	force.obj=(PinObject*)GetWSMObject(t);
		force.node=nodeRef;
		force.tmValid.SetEmpty();
		force.fValid.SetEmpty();
		force.dt=GetTicksPerFrame();
		force.dtsq=force.dt*force.dt;
		obj->ApplyForceField(&force); //ok
	}
}
Ejemplo n.º 5
0
void SceneBase::InitParticles(int numParticles)
{
	m_gravity.Set(0.0f, -9.8f, 0.0f);

	ParticleObject* po;

	for (int i = 0; i < numParticles; ++i)
	{
		po = new ParticleObject;
		po->SetActive(false);
		po->SetMass(1.0f);

		m_particleList.push_back(po);
	}
}
Ejemplo n.º 6
0
void WindMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{
	ParticleObject *obj = GetParticleInterface(os->obj);
	if (obj) 
	{
		force.obj  = (WindObject*)GetWSMObject(t);
		force.node = nodeRef;
		force.tmValid.SetEmpty();
		force.fValid.SetEmpty();
		if (force.obj != NULL)
			force.obj->pblock2->GetValue(PB_TYPE,t,force.type,FOREVER);
		obj->ApplyForceField(&force);
	}
}
Ejemplo n.º 7
0
ParticleObject * SceneBase::SpawnParticle(float mass, Vector3 vel)
{
	for (vector<ParticleObject*>::iterator it = m_particleList.begin(); it != m_particleList.end(); ++it)
	{
		ParticleObject* po = *it;

		if (!po->IsActive())
		{
			po->Activate(mass, vel);

			return po;
		}
	}

	return NULL;
}
Ejemplo n.º 8
0
void PBombMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
	{
	ParticleObject *obj = GetParticleInterface(os->obj);
	if (obj) {
/*		if (!mc.localdata)
		{ mc.localdata=seed; seed+=5;}	  */
		force.obj  = (PBombObject*)GetWSMObject(t);
		force.node = nodeRef;
		force.tmValid.SetEmpty();
		force.fValid.SetEmpty();
		force.dt=GetTicksPerFrame();
		force.dtsq=force.dt*force.dt;
		obj->ApplyForceField(&force);
		}
	}
Ejemplo n.º 9
0
void EntityDataChannels::addEntity(const ParticleObject &entity) {
  entityType->setSlice(_index, entity.entityType());
  alive->setSlice(_index, entity.alive());
  age->setSlice(_index, entity.age().get());
  position->setSlice(_index, entity.position());
  color->setSlice(_index, entity.color());
  size->setSlice(_index, entity.size());
  _index++;
}
Ejemplo n.º 10
0
/******************************************************************************
 * Get triangles for rendering
 *****************************************************************************/
void ParticleTracer::getTriangles(double time, vector<ntlTriangle> *triangles, 
													 vector<ntlVec3Gfx> *vertices, 
													 vector<ntlVec3Gfx> *normals, int objectId )
{
#ifdef ELBEEM_PLUGIN
	// suppress warnings...
	vertices = NULL; triangles = NULL;
	normals = NULL; objectId = 0;
	time = 0.;
#else // ELBEEM_PLUGIN
	int pcnt = 0;
	// currently not used in blender
	objectId = 0; // remove, deprecated
	if(mDumpParts>1) { 
		return; // only dump, no tri-gen
	}

	const bool debugParts = false;
	int tris = 0;
	int segments = mPartSegments;
	ntlVec3Gfx scale = ntlVec3Gfx( (mEnd[0]-mStart[0])/(mSimEnd[0]-mSimStart[0]), (mEnd[1]-mStart[1])/(mSimEnd[1]-mSimStart[1]), (mEnd[2]-mStart[2])/(mSimEnd[2]-mSimStart[2]));
	ntlVec3Gfx trans = mStart;
	time = 0.; // doesnt matter

	for(size_t t=0; t<mPrevs.size()+1; t++) {
		vector<ParticleObject> *dparts;
		if(t==0) {
			dparts = &mParts;
		} else {
			dparts = &mPrevs[t-1];
		}
		//errMsg("TRAILT","prevs"<<t<<"/"<<mPrevs.size()<<" parts:"<<dparts->size() );

	gfxReal partscale = mPartScale;
	if(t>1) { 
		partscale *= (gfxReal)(mPrevs.size()+1-t) / (gfxReal)(mPrevs.size()+1); 
	}
	gfxReal partNormSize = 0.01 * partscale;
	//for(size_t i=0; i<mParts.size(); i++) {
	for(size_t i=0; i<dparts->size(); i++) {
		ParticleObject *p = &( (*dparts)[i] ); //  mParts[i];

		if(mShowOnly!=10) {
			// 10=show only deleted
			if( p->getActive()==false ) continue;
		} else {
			if( p->getActive()==true ) continue;
		}
		int type = p->getType();
		if(mShowOnly>0) {
			switch(mShowOnly) {
			case 1: if(!(type&PART_BUBBLE)) continue; break;
			case 2: if(!(type&PART_DROP))   continue; break;
			case 3: if(!(type&PART_INTER))  continue; break;
			case 4: if(!(type&PART_FLOAT))  continue; break;
			case 5: if(!(type&PART_TRACER))  continue; break;
			}
		} else {
			// by default dont display inter
			if(type&PART_INTER) continue;
		}

		pcnt++;
		ntlVec3Gfx pnew = p->getPos();
		if(type&PART_FLOAT) { // WARNING same handling for dump!
			if(p->getStatus()&PART_IN) { pnew[2] += 0.8; } // offset for display
			// add one gridcell offset
			//pnew[2] += 1.0; 
		}
#if LBMDIM==2
		pnew[2] += 0.001; // DEBUG
		pnew[2] += 0.009; // DEBUG
#endif 

		ntlVec3Gfx pdir = p->getVel();
		gfxReal plen = normalize( pdir );
		if( plen < 1e-05) pdir = ntlVec3Gfx(-1.0 ,0.0 ,0.0);
		ntlVec3Gfx pos = (*mpTrafo) * pnew;
		gfxReal partsize = 0.0;
		if(debugParts) errMsg("DebugParts"," i"<<i<<" new"<<pnew<<" vel"<<pdir<<"   pos="<<pos );
		//if(i==0 &&(debugParts)) errMsg("DebugParts"," i"<<i<<" new"<<pnew[0]<<" pos="<<pos[0]<<" scale="<<scale[0]<<"  t="<<trans[0] );
		
		// value length scaling?
		if(mValueScale==1) {
			partsize = partscale * plen;
		} else if(mValueScale==2) {
			// cut off scaling
			if(plen > mValueCutoffTop) continue;
			if(plen < mValueCutoffBottom) continue;
			partsize = partscale * plen;
		} else {
			partsize = partscale; // no length scaling
		}
		//if(type&(PART_DROP|PART_BUBBLE)) 
		partsize *= p->getSize()/5.0;

		ntlVec3Gfx pstart( mPartHeadDist *partsize, 0.0, 0.0 );
		ntlVec3Gfx pend  ( mPartTailDist *partsize, 0.0, 0.0 );
		gfxReal phi = 0.0;
		gfxReal phiD = 2.0*M_PI / (gfxReal)segments;

		ntlMat4Gfx cvmat; 
		cvmat.initId();
		pdir *= -1.0;
		ntlVec3Gfx cv1 = pdir;
		ntlVec3Gfx cv2 = ntlVec3Gfx(pdir[1], -pdir[0], 0.0);
		ntlVec3Gfx cv3 = cross( cv1, cv2);
		//? for(int l=0; l<3; l++) { cvmat.value[l][0] = cv1[l]; cvmat.value[l][1] = cv2[l]; cvmat.value[l][2] = cv3[l]; }
		pstart = (cvmat * pstart);
		pend = (cvmat * pend);

		for(int s=0; s<segments; s++) {
			ntlVec3Gfx p1( 0.0 );
			ntlVec3Gfx p2( 0.0 );

			gfxReal radscale = partNormSize;
			radscale = (partsize+partNormSize)*0.5;
			p1[1] += cos(phi) * radscale;
			p1[2] += sin(phi) * radscale;
			p2[1] += cos(phi + phiD) * radscale;
			p2[2] += sin(phi + phiD) * radscale;
			ntlVec3Gfx n1 = ntlVec3Gfx( 0.0, cos(phi), sin(phi) );
			ntlVec3Gfx n2 = ntlVec3Gfx( 0.0, cos(phi + phiD), sin(phi + phiD) );
			ntlVec3Gfx ns = n1*0.5 + n2*0.5;

			p1 = (cvmat * p1);
			p2 = (cvmat * p2);

			sceneAddTriangle( pos+pstart, pos+p1, pos+p2, 
					ns,n1,n2, ntlVec3Gfx(0.0), 1, triangles,vertices,normals ); 
			sceneAddTriangle( pos+pend  , pos+p2, pos+p1, 
					ns,n2,n1, ntlVec3Gfx(0.0), 1, triangles,vertices,normals ); 

			phi += phiD;
			tris += 2;
		}
	}

	} // t

	debMsgStd("ParticleTracer::getTriangles",DM_MSG,"Dumped "<<pcnt<<"/"<<mParts.size()<<" parts, tris:"<<tris<<", showonly:"<<mShowOnly,10);
	return; // DEBUG

#endif // ELBEEM_PLUGIN
}
Ejemplo n.º 11
0
void ParticleTracer::checkDumpTextPositions(double simtime) {
	// dfor partial & full dump
	if(mDumpTextInterval>0.) {
		debMsgStd("ParticleTracer::checkDumpTextPositions",DM_MSG,"t="<<simtime<<" last:"<<mDumpTextLastTime<<" inter:"<<mDumpTextInterval,7);
	}

	if((mDumpTextInterval>0.) && (simtime>mDumpTextLastTime+mDumpTextInterval)) {
		// dump to binary file
		std::ostringstream boutfilename("");
		if(mDumpTextFile.length()>1) {   
			boutfilename << mDumpTextFile <<  ".cpart2"; 
		} else {                           
			boutfilename << "_particles" <<  ".cpart2"; 
		}
		debMsgStd("ParticleTracer::checkDumpTextPositions",DM_MSG,"T-Dumping: "<< this->getName() <<", particles:"<<mParts.size()<<" "<< " to "<<boutfilename.str()<<" " , 7);

		int numParts = 0;
		// only dump bubble particles
		for(size_t i=0; i<mParts.size(); i++) {
			//if(!mParts[i].getActive()) continue;
			//if(!(mParts[i].getType()&PART_BUBBLE)) continue;
			numParts++;
		}

		// output to text file
		//gzFile gzf;
		FILE *stf;
		if(mDumpTextCount==0) {
			//gzf = gzopen(boutfilename.str().c_str(), "w0");
			stf = fopen(boutfilename.str().c_str(), "w");

			fprintf( stf, "\n\n# cparts generated by elbeem \n# no. of parts \nN %d \n\n",numParts);
			// fixed time scale for now
			fprintf( stf, "T %f \n\n", 1.0);
		} else {
			//gzf = gzopen(boutfilename.str().c_str(), "a+0");
			stf = fopen(boutfilename.str().c_str(), "a+");
		}

		// add current set
		if(stf) {
			fprintf( stf, "\n\n# new set at frame %d,t%f,p%d --------------------------------- \n\n", mDumpTextCount, simtime, numParts );
			fprintf( stf, "S %f \n\n", simtime );
			
			for(size_t i=0; i<mParts.size(); i++) {
				ParticleObject *p = &mParts[i];
				ntlVec3Gfx pos = p->getPos();
				float size = p->getSize();
				float infl = 1.;
				//if(!mParts[i].getActive()) { size=0.; } // switch "off"
				if(!mParts[i].getActive()) { infl=0.; } // switch "off"
				if(!mParts[i].getInFluid()) { infl=0.; } // switch "off"
				if(mParts[i].getLifeTime()<0.) { infl=0.; } // not yet active...

				pos = (*mpTrafo) * pos;
				ntlVec3Gfx v = p->getVel();
				v[0] *= mpTrafo->value[0][0];
				v[1] *= mpTrafo->value[1][1];
				v[2] *= mpTrafo->value[2][2];
				
				fprintf( stf, "P %f %f %f \n", pos[0],pos[1],pos[2] );
				if(size!=1.0) fprintf( stf, "s %f \n", size );
				if(infl!=1.0) fprintf( stf, "i %f \n", infl );
				fprintf( stf, "\n" );
			}

			fprintf( stf, "# %d end  ", mDumpTextCount );
			//gzclose( gzf );
			fclose( stf );

			mDumpTextCount++;
		}

		mDumpTextLastTime += mDumpTextInterval;
	}

}
Ejemplo n.º 12
0
	// 工厂对象的创建方法
	ISceneObject *ParticleObjectFactory::create(const String &name , IScene *scene , const NameValuePairList* params)
	{
		ParticleObject *obj = new ParticleObject(name);
		obj->create(scene , params);
		return obj;
	}
Ejemplo n.º 13
0
// Calculates 0..1 value which is given to the gradient
float BerconGradient::getGradientValue(ShadeContext& sc) {
	switch (p_type) {
		case 0: { // UVW
			break; // Handled in main evaluation
		}
		case 1: { // Normal
			switch (p_normalFunction) {
				case 0: { // Perpendicular / Parallel
					return fabs(getGradientValueNormal(sc));
				}
				case 1: { // Towards / Away
					return (getGradientValueNormal(sc) + 1.f) / 2.f;	
				}
				case 2: { // Fresnel
					// NOTE: Should this get IOR from sc.GetIOR()?
					//		 I think not since its just a map, not material.
					//		 You get more predictable behaviour with constant 1.f.
					static float n1 = 1.0f;								
					float cti = fabs(getGradientValueNormal(sc));					
					float stt = (n1 / p_ior) * sqrt(1 - cti * cti);
					float ctt = sqrt(1 - stt * stt);
					float rs = (p_ior * ctt - n1 * cti ) / (p_ior * ctt + n1 * cti);
					rs = rs * rs;
					float rp = (n1 * ctt - p_ior * cti ) / (n1 * ctt + p_ior * cti);
					rp = rp * rp;
					return 1.f - 0.5f * (rs + rp);				
				}
			}
		}
		case 2: { // Distance
			return getGradientValueDist(sc);		
		}
		case 3: { // Light
			return Intens(sc.DiffuseIllum());
		}
		case 4: { // Map			
			return p_maptex?p_maptex->EvalMono(sc):0.f; // TODO: Evaluate submaps color, bump is tougher DELTA shift with BerconSC?
		}
		case 5: { // Random
			seedRandomGen(sc);
			return (float)sfrand();		
			break;
		}
		case 6: { // Particle age
			Object *ob = sc.GetEvalObject();		
			if (ob && ob->IsParticleSystem()) {				
				ParticleObject *obj = (ParticleObject*)ob;
				TimeValue t = sc.CurTime();
				TimeValue age  = obj->ParticleAge(t,sc.mtlNum);
				TimeValue life = obj->ParticleLife(t,sc.mtlNum);
				if (age>=0 && life>=0) 
					return float(age)/float(life);
			}
			break;
		}
		case 7: { // Particle speed
			Object *ob = sc.GetEvalObject();		
			if (ob && ob->IsParticleSystem()) {
				ParticleObject *obj = (ParticleObject*)ob; 
				/*IChkMtlAPI* chkMtlAPI = static_cast<IChkMtlAPI*>(obj->GetInterface(I_NEWMTLINTERFACE));
				if ((chkMtlAPI&&chkMtlAPI->SupportsParticleIDbyFace()))
					return (Length(obj->ParticleVelocity(sc.CurTime(),chkMtlAPI->GetParticleFromFace(sc.FaceNumber()))) - p_rangeMin) / (p_rangeMax - p_rangeMin);
				else*/
					return Length(obj->ParticleVelocity(sc.CurTime(),sc.mtlNum));
			}									
			break;
		}
		case 8: { // Particle size
			Object *ob = sc.GetEvalObject();		
			if (ob && ob->IsParticleSystem()) {
				ParticleObject *obj = (ParticleObject*)ob;
				return obj->ParticleSize(sc.CurTime(),sc.mtlNum);
			}									
			break;
		}
		default:
			break;
	}
	return 0.f;
}