Curve Creation

Curve geometry can be used for simulating hair, fur or even grass objects.

Curves are created in “batches” in that multiple pieces of curve geometry are created with one call to rprContextCreateCurve(). The tricky part of creating curves is that they are specified to RPR in segments of 4 points. Thus, a curve of 7 points long would be specified as:

point 1, point 2, point 3, point 4 (segment 1), point 4, point 5, point 6, point 7 (segment 2)

Note the doubling of point 4. Otherwise, there would be a gap between the segments. Segments MUST be 4 points. If there are less than 4 points left for a segment, the last point can simply be repeated.

// It's BCurve model of 4 point
// It works with StartPoint CtrlPoint CtrlPoint EndPoint
rpr_curve newCurve = 0;

int nPoints = 0;
const int n = 12;
std::vector<float> cps;
std::vector<rpr_uint> indices;
std::vector<float> radius;
std::vector<rpr_int> segsPerCurve;
std::vector<float> uvs;
for(int j=0; j<n; j++) for(int i=0; i<n; i++)
{
	const float width = 5.f;
	float x = (i/(float)n - 0.5f)*width;
	float z = (j/(float)n - 0.5f)*width;

	const float length = 0.1f;
	int nSegs = 8;
	float x0 = x + (draw()-0.5f)*width/n/2;
	float z0 = z + (draw()-0.5f)*width/n/2;
	for(int l=0; l<nSegs; l++)
	{
		for(int k=0; k<4; k++)
		{
			if( k!=0 )
			{
				x0 = x + (draw()-0.5f)*width/n/2;
				z0 = z + (draw()-0.5f)*width/n/2;
			}
			cps.push_back( x0 );
			cps.push_back( (3*l + k) * length );
			cps.push_back( z0 );

			indices.push_back( indices.size() );
			nPoints++;
		}
	}
	radius.push_back( 0.01f );
	segsPerCurve.push_back( nSegs );
	uvs.push_back( i/(float)n );
	uvs.push_back( j/(float)n );
}

CHECK(rprContextCreateCurve(
	context,
	&newCurve,
	nPoints, // number of 3d points
	cps.data(), // list of 3d points
	3 * sizeof(float), // stride of 3d points
	indices.size(), // number of indices
	segsPerCurve.size(),	// this  rpr_curve has N curves	
	indices.data(), // indices pointing to controPoint
	radius.data(), // list of radius (float) for each curve
	uvs.data(),     // list of uv (float2) for each curve
	segsPerCurve.data(), // number of segment ( rpr_int ) for each curve
	0
));

CHECK(rprObjectSetName(newCurve, "myCurve0"));

rpr_material_node newDiffuse_red = NULL;
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_DIFFUSE, &newDiffuse_red));
CHECK(rprMaterialNodeSetInputFByKey(newDiffuse_red, RPR_MATERIAL_INPUT_COLOR, 1.0f, 0.5f, 0.5f, 1.f));
CHECK(rprCurveSetMaterial(newCurve, newDiffuse_red));

CHECK(rprSceneAttachCurve(scene, newCurve));

See full code