On 14/11/2013 at 09:17, xxxxxxxx wrote:
I've only briefly explored the spline classes myself. So I'm not sure if any of this code will help or not.
This is the code from a tag plugin I wrote that moves an object along a spline :
//This tag plugin works similar to the Align-to-Spline tag in C4D
//Except my tag gets put on a spline object. And the object traveling along it gets dropped into the tag's linkfield
EXECUTIONRESULT MyTag::Execute(BaseTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, EXECUTIONFLAGS flags)
{
BaseContainer *tagdata = tag->GetDataInstance(); //Get the data in the tag and assign it to a variable
BaseObject *obj = tag->GetObject(); //Get the object the tag is on
if (!obj) return EXECUTIONRESULT_USERBREAK;
//Only work if the object the tag is on is a spline type (all types of splines)
if(!obj->GetInfo()&OBJECT_ISSPLINE) return EXECUTIONRESULT_USERBREAK;
//I used a linkfield gizmo to store the object that will move along the spline
BaseObject *target = tagdata->GetObjectLink(MY_LINK,doc);
if(target) //If the linkfield is not empty
{
//Gets the position of the object in the link field
Vector position = target->GetRelPos();
//Convert the object the tag is on to a spline type
SplineObject *myspline = ToSpline(obj);
SplineLengthData *sld = SplineLengthData::Alloc();
sld->Init(myspline, 0, NULL);
if (!sld) return EXECUTIONRESULT_USERBREAK;
SplineHelp *sh = SplineHelp::Alloc();
if (!sh) return EXECUTIONRESULT_USERBREAK;
sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);
LONG segment = 0; //NOTE:If the spline is a Primitive...only segment 0 works
Real PosOnSpline = tag->GetData().GetReal(MYNUMERIC); //The position the object is along the spline's segment
Vector splinepos = sh->GetPosition(PosOnSpline, segment, TRUE);
sh->FreeSpline();
target->SetRelPos(Vector(splinepos.x,splinepos.y,splinepos.z)); //Moves the object along the spline
target->Message(MSG_UPDATE);
}
return EXECUTIONRESULT_OK;
}
These are a few examples that I've created in my notes about how to use some of the various spline functions in the SDK:
//This code gets the global position of a spline's point + an offset value
BaseObject *obj = doc->GetActiveObject();
if (!obj) return FALSE;
SplineObject *myspline = ToSpline(obj);
SplineLengthData *sld = SplineLengthData::Alloc();
sld->Init(myspline,0,NULL);
if (!sld) return FALSE;
SplineHelp *sh = SplineHelp::Alloc();
if (!sh) return FALSE;
sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);
Real offsetValue = 10.5;
Real offset = sh->GetOffsetFromUnit(offsetValue, 0);
//Real offset = sh->GetOffsetFromReal(offsetValue, 0);
//Get the global position of the first spline point + the offset
Vector p0 = sh->GetPosition(offset,0,TRUE,TRUE);
//Vector p0 = sh->GetPosition(sld->UniformToNatural(offset), 0, TRUE, TRUE);
GePrint(RealToString(p0.x));
//This code gets the offset, and segment values for the points in a selected spline object
//It calculates the distance the "offset" variable is from the first spline point
//NOTE: The offset values never change no matter where the points are placed(results are local..not global)
// Example: offset = 0.5; is always the middle of the spline. No matter how the spline looks
BaseObject *obj = doc->GetActiveObject(); //The active object should be a spline object
if (!obj) return FALSE;
SplineObject *myspline = ToSpline(obj); //Convert the type to a spline type so we can work on it
//Create the SplineHelp class for the spline so we can use it's methods
SplineHelp *sh = SplineHelp::Alloc();
if (!sh) return FALSE;
sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);
Real offset = 0.5; //The position along the spline. The range is: 0.0 - 1.0
//The values for these 2 variables are filled in by the GlobalToLocal() function
Real off; //This value will match the value set with the "offset" variable above
LONG segment;
sh->GlobalToLocal(offset, &off, &segment, FALSE);
GePrint("offset: " + RealToString(off) + " " + "segment: " + LongToString(segment));
//This code gets the index, offset, and segment values for the points in a selected spline object
//The code calculates results based upon how many points in the spline. In relation to how long the spline length is
//It calculates the offset distance each point is from the first spline point
//NOTE: The offset values never change no matter where the points are placed(results are local..not global)
BaseObject *obj = doc->GetActiveObject(); //The active object should be a spline object
if (!obj) return FALSE;
SplineObject *myspline = ToSpline(obj); //Convert the type to a spline type so we can work on it
//Create the SplineHelp class for the spline so we can use it's methods
SplineHelp *sh = SplineHelp::Alloc();
if (!sh) return FALSE;
sh->InitSpline(myspline, 0.0, FALSE, TRUE, FALSE, FALSE);
LONG count = myspline->GetPointCount();
for(LONG i=0; i<count; i++)
{
LONG index = i; //Check each of the spline's index points
//The values for these 3 variables are filled in by the GetSplinePointSegment() function
LONG ind;
Real offset;
LONG segment;
sh->GetSplinePointSegment(index, &offset, &ind, &segment);
GePrint("index: " + LongToString(ind) + " " + "offset: " + RealToString(offset) + " " + "segment: " + LongToString(segment));
}
Maybe the code in these examples will help you.
-ScottA