예제 #1
0
void SOP_FlexSolver::copySourceParticles()
{
    if (mySource)
    {
        for (GA_Offset srcptoff = 0; srcptoff < maxParticles; ++srcptoff)
        {
            const UT_Vector3 pos = mySource->getPos3(srcptoff);
            UT_Vector3 vel;
            if (mySourceVel.isValid())
                vel = mySourceVel.get(srcptoff);
            else
                vel = UT_Vector3(0,0,0);
            uint index = static_cast<int>(srcptoff);
            uint p = index * 4;
            uint v = index * 3;
            particles[p]    = pos.x();
            particles[p+1]  = pos.y();
            particles[p+2]  = pos.z();
            particles[p+3]  = 1.0;
            velocities[v]   = vel.x();
            velocities[v+1] = vel.y();
            velocities[v+2] = vel.z();

            gdp->insertPointCopy(srcptoff);
            gdp->setPos3(srcptoff, pos);
        }
    }

}
예제 #2
0
void
SOP_FlexSolver::timeStep(fpreal now)
{
    UT_Vector3 force(FX(now), FY(now), FZ(now));
    // int nbirth = BIRTH(now);

    if (error() >= UT_ERROR_ABORT)
        return;

   for (GA_Offset srcptoff = 0; srcptoff < maxParticles; ++srcptoff)
    {
        UT_Vector3 vel;
        if (mySourceVel.isValid())
            vel = mySourceVel.get(srcptoff);
        else
            vel = UT_Vector3(0,0,0);

        vel += force;
        uint index = static_cast<int>(srcptoff);
        uint v = index * 3;
        velocities[v]   = vel.x();
        velocities[v+1] = vel.y();
        velocities[v+2] = vel.z();
    }

    InitFlexParams(*myParms, now);
    flexSetParams(mySolver, myParms);
    flexSetVelocities(mySolver, &velocities[0], maxParticles, eFlexMemoryHost);

     const float dt = 1.0 / 24.0;
     const int substeps = 1;

    // tick solver
    flexUpdateSolver(mySolver, dt, substeps, myTimer);
    // update GPU data asynchronously
  
    flexGetParticles(mySolver, (float*)&particles[0], maxParticles, eFlexMemoryHost);

    for (GA_Offset srcptoff = 0; srcptoff < maxParticles; ++srcptoff)
    {
       uint p = static_cast<int>(srcptoff) * 4;
       const UT_Vector3 pos = UT_Vector3(particles[p], particles[p+1], particles[p+2]);
       gdp->setPos3(srcptoff, pos);
    }
}
예제 #3
0
static void exportParticlesDetail( const GU_Detail* gdp,
                                  const std::string& filePath,
                                  const std::map<std::string,
                                  channel_type>& desiredChannels )
{
	prt_ofstream ostream;

	static std::map<std::string, std::string> s_reservedChannels;
	if( s_reservedChannels.empty() ) {
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_NORMAL ) ] = "Normal";
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_TEXTURE ) ] = "TextureCoord";
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_VELOCITY ) ] = "Velocity";
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_DIFFUSE ) ] = "Color";
		//s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_ALPHA ) ] = "Density";
		//s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_MASS ) ] = "Density";
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_LIFE ) ] = "";
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_ID ) ] = "ID";
		s_reservedChannels[ gdp->getStdAttributeName( GEO_ATTRIBUTE_PSCALE ) ] = "Scale";
		s_reservedChannels[ "accel" ] = "Acceleration";
	}

	float posVal[3];
	float lifeVal[2];
	
	ostream.bind( "Position", posVal, 3 );

	//We handle the life channel in a special manner
	GA_ROAttributeRef lifeAttrib = gdp->findPointAttribute( gdp->getStdAttributeName( GEO_ATTRIBUTE_LIFE ) );
	if( lifeAttrib.isValid() ){
		std::map<std::string,channel_type>::const_iterator it;
		
		it = desiredChannels.find( "Age" );
		if( it != desiredChannels.end() && it->second.second == 1 )
			ostream.bind( "Age", &lifeVal[0], 1, it->second.first );
		else if( desiredChannels.empty() )
			ostream.bind( "Age", &lifeVal[0], 1, prtio::data_types::type_float16 );

		it = desiredChannels.find( "LifeSpan" );
		if( it != desiredChannels.end() && it->second.second == 1 )
			ostream.bind( "LifeSpan", &lifeVal[1], 1, it->second.first );
		else if( desiredChannels.empty() )
			ostream.bind( "LifeSpan", &lifeVal[1], 1, prtio::data_types::type_float16 );
	}
	
	//Using a deque to prevent the memory from moving around after adding the bound_attribute to the container.
	std::deque< bound_attribute<int> > m_intAttrs;
	std::deque< bound_attribute<float> > m_floatAttrs;
	std::deque< bound_attribute<float> > m_vectorAttrs;
	
	for ( GA_AttributeDict::iterator it = gdp->getAttributes().getDict(GA_ATTRIB_POINT).begin(GA_SCOPE_PUBLIC); !it.atEnd(); ++it) {
		
		GA_Attribute *node = it.attrib();

		std::string channelName = node->getName();

		//Translate special names
		std::map<std::string,std::string>::const_iterator itResChannel = s_reservedChannels.find( channelName );
		if( itResChannel != s_reservedChannels.end() ){
			//If its empty, that means we reserve some sort of special handling.
			if( itResChannel->second.empty() )
				continue;
			channelName = itResChannel->second;
		}
		
		//Skip channels that aren't on the list.
		std::map<std::string,channel_type>::const_iterator itChannel = desiredChannels.find( channelName );
		bool channelIsDesired = ( itChannel != desiredChannels.end() );
		
		if( !desiredChannels.empty() && !channelIsDesired )
			continue;
			
		prtio::data_types::enum_t type;
		
		//Only add valid channel names
		if( detail::is_valid_channel_name( channelName.c_str() ) ) {
			//I add the new item to the deque, THEN initialize it since a deque will not move the object around and this allows
			//me to allocate the float array and not have to worry about the object getting deleted too early.
			switch( node->getStorageClass() ){
			case GA_STORECLASS_FLOAT:
				if( node->getTupleSize()==3 ){
					m_vectorAttrs.push_back( bound_attribute<float>() );
					m_vectorAttrs.back().attr =	gdp->findPointAttribute(node->getName());
					m_vectorAttrs.back().count = node->getTupleSize();
					m_vectorAttrs.back().data = new float[m_vectorAttrs.back().count];

					type = prtio::data_types::type_float16;
					if( channelIsDesired ){
						type = itChannel->second.first;
						if( itChannel->second.second != m_vectorAttrs.back().count )
							continue;
					}

					ostream.bind( channelName, m_vectorAttrs.back().data, m_vectorAttrs.back().count, type );

				} else {
					m_floatAttrs.push_back( bound_attribute<float>() );
					m_floatAttrs.back().attr =	gdp->findPointAttribute( node->getName() );
					m_floatAttrs.back().count = node->getTupleSize();
					m_floatAttrs.back().data = new float[m_floatAttrs.back().count];

					type = prtio::data_types::type_float16;
					if( channelIsDesired ){
						type = itChannel->second.first;
						if( itChannel->second.second != m_floatAttrs.back().count )
							continue;
					}

					ostream.bind( channelName, m_floatAttrs.back().data, m_floatAttrs.back().count, type );
				}
				break;
			case GA_STORECLASS_INT:
				m_intAttrs.push_back( bound_attribute<int>() );
				m_intAttrs.back().attr = gdp->findPointAttribute( node->getName() );
				m_intAttrs.back().count = node->getTupleSize();
				m_intAttrs.back().data = new int[m_intAttrs.back().count];

				type = prtio::data_types::type_int32;
				if( channelIsDesired ){
					type = itChannel->second.first;
					if( itChannel->second.second != m_intAttrs.back().count )
						continue;
				}
			
				ostream.bind( channelName, m_intAttrs.back().data, m_intAttrs.back().count, type );
				break;
			default:
				break;
			}
		}
	}

	try{
		ostream.open( filePath );
	} catch( const std::ios::failure& e ) {
		std::cerr << e.what() << std::endl;
		throw HOM_OperationFailed( "Failed to open the file" );
	}
		
	GA_IndexMap map = gdp->getPointMap();
	UT_Vector3 p;
	GEO_Point* pt;
	GA_Index indexSize = map.indexSize();
	GA_Offset offset;

	for( int i = 0 ; i < indexSize; i++ ) {
		offset = map.offsetFromIndex( i );
		p = gdp->getPos3( offset );
		posVal[0] = p.x();
		posVal[1] = p.y();
		posVal[2] = -1 * p.z();
		
		//TODO: Remove the GEO_Point object that is now deprecated. 
		pt = ( GEO_Point* )gdp->getGBPoint( offset );
		
		//TODO: Convert this into appropriate time values. Is it seconds or frames or what?!
		if( lifeAttrib.isValid() ) 
			pt->get( lifeAttrib, lifeVal, 2 );

		for( std::deque< bound_attribute<float> >::iterator it = m_floatAttrs.begin(), itEnd = m_floatAttrs.end(); it != itEnd; ++it )
			pt->get( it->attr, it->data, it->count );

		for( std::deque< bound_attribute<float> >::iterator it = m_vectorAttrs.begin(), itEnd = m_vectorAttrs.end(); it != itEnd; ++it ) {
			pt->get( it->attr, it->data, it->count );
				
			//TODO: Optionally transform into some consistent world space for PRT files.
		}

		for( std::deque< bound_attribute<int> >::iterator it = m_intAttrs.begin(), itEnd = m_intAttrs.end(); it != itEnd; ++it )
			pt->get( it->attr, it->data, it->count );

		ostream.write_next_particle();
	}
	
	ostream.close();
}
예제 #4
0
void GR_rmanPtc::renderWire( GU_Detail *gdp,
    RE_Render &ren,
    const GR_AttribOffset &ptinfo,
    const GR_DisplayOption *dopt,
    float lod,
    const GU_PrimGroupClosure *hidden_geometry
    )
{
    int			 i, nprim;
    GEO_Primitive 	*prim;
    UT_Vector3		 v3;

    rmanPtcSop::rmanPtcDetail *detail = dynamic_cast<rmanPtcSop::rmanPtcDetail*>(gdp);
    if ( !detail )
        return;

    // rebuild our display list
    if ( detail->redraw )
    {
        srand(0);

        GEO_PointList &points = detail->points();
        int display_channel = detail->display_channel;
        // render as points
        GEO_Point *pt = 0;
        UT_Vector4 pos;
        float col[3] = {1.0,1.0,1.0};

        if ( !detail->use_disk )
        {
            ren.pushPointSize(detail->point_size);
            ren.beginPoint();
        }

        for ( unsigned int i=0; i<points.entries(); ++i )
        {
            if ( rand()/(float)RAND_MAX<=detail->display_probability )
            {
                // point position
                pt = points[i];
                pos = pt->getPos();

                // display colour
                
                float *ptr = NULL;
                if (detail->attributes.size() >0) {
                    ptr = pt->castAttribData<float>(
                            detail->attributes[display_channel] );
                    if (ptr) {
                        if ( detail->attribute_size[display_channel]==1)
                            col[0] = col[1] = col[2] = ptr[0];
                        else
                        {
                            col[0] = ptr[0];
                            col[1] = ptr[1];
                            col[2] = ptr[2];
                        }
                    }
                }
                // draw point
                if ( !detail->use_cull_bbox ||
                        detail->cull_bbox.isInside( pos ) )
                {
                    if ( !detail->use_disk )
                    {
                        // render as points
                        ren.setColor( col[0], col[1], col[2], 1 );
                        ren.vertex3DW( pos.x(), pos.y(), pos.z() );
                    }
                    else
                    {
                        // render as disks
                        UT_Vector3 n = *pt->castAttribData<UT_Vector3>(detail->N_attrib);
                        float r = *pt->castAttribData<float>(detail->R_attrib);
                        n.normalize();
                        UT_Vector3 ref(1,0,0);
                        UT_Vector3 up = ref;
                        up.cross(n);
                        up.normalize();
                        UT_Vector3 right = up;
                        right.cross(n);
                        right.normalize();
                        UT_DMatrix4 mat(
                                right.x(), right.y(), right.z(), 0,
                                up.x(), up.y(), up.z(), 0,
                                n.x(), n.y(), n.z(), 0,
                                pos.x(), pos.y(), pos.z(), 1 );
                        ren.pushMatrix();
                        ren.multiplyMatrix(mat);
                        ren.pushColor( UT_Color( UT_RGB, col[0], col[1], col[2] ) );
                        ren.circlefW( 0, 0, detail->point_size * r, 8 );
                        ren.popColor();
                        ren.popMatrix();
                    }
                }
            }
        }

        if ( !detail->use_disk )
        {
            ren.endPoint();
        }
    }
}