Recreating the Range Mapper

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 08/12/2009 at 12:29, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   11 
Platform:   Windows  ; Mac  ;  
Language(s) :     C++  ;

---------
Hey all,

I'm having trouble trying to figure out how to recreate the functionality of the Range Mapper xpresso node.  I was relying on it's use in xpresso originally, however now I have to do some position/rotation handling within the plugin, which effectively moves the need for range mapping to the plugin.  What's confusing the hell out of me is the Spline field.  How would you incorporate the SplineData.  I scoured the sdk and examples looking for something that would show an example, but all the examples that make use of a splinecontrol gui element get it from an effector and I can't find where the code to implement its data is.  I have the gui's in place, it's just using the data it generates is puzzling me.

thanks,
kvb

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/12/2009 at 02:04, xxxxxxxx wrote:

It's actually rather easy. You simply get the SplineData with GetCustomDataType() from the object's/tag's container. Then you can use the SplineData class methods to read out the spline data.

Here a simple example:

  
LONG LookAtCamera::Execute(PluginTag *tag, BaseDocument *doc, BaseObject *op, BaseThread *bt, LONG priority, LONG flags)  
{  
 BaseContainer *data = NULL;  
 data = tag->GetDataInstance();  
 if (!data) return FALSE;  
  
 SplineData *spline = NULL;  
 spline = (SplineData* )data->GetCustomDataType(MY_SPLINE, CUSTOMDATATYPE_SPLINE);  
 if (!spline) return FALSE;  
  
 CustomSplineKnot *knot = NULL;  
 knot = spline->GetKnots();  
 if (!knot) return FALSE;  
  
 LONG knotcnt = spline->GetKnotCount();  
  
 GePrint(LongToString(knotcnt));  
  
 for (LONG i=0; i<knotcnt; i++)  
 {  
     //knot[i].vPos is the knot position;  
  
     GePrint(RealToString(knot[i].vPos.x)+" "+RealToString(knot[i].vPos.y)+" "+RealToString(knot[i].vPos.z));  
 }  
  
 return EXECUTION_RESULT_OK;  
}  

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/12/2009 at 12:03, xxxxxxxx wrote:

Thanks Matthias, that example will hep me out a lot (that z value for the knots seems kind of weird for a 2d graph but oh well lol).  What's still confusing me is I can't figure out how to use those knot positions to remap my value ranges.  For instance, the x range will be a fixed set of values, say from -100 to 100, the y range will be user input, lets say the user chooses -5 to 5.  The plugin will then receive input along the x range and map it to the y value based on the spline curve.

So, basically how can I find the y value of the spline at a given x value?

Is this a matter of clever math, or just understanding and using the functions correctly?  I was (possibly incorrectly) under the impression that the splinecustomgui was it's own little specialized calculator: give it some ranges, feed it an input along one of those ranges and it would use it's internal spline data to determine what that input would equal along the other range.  It's starting to appear like I was dead wrong on that.

If it's math... I'm in trouble... math was never my strong point (read: I suck at math), but I'm prepared to study and learn anything I need to accomplish this task.

Thanks,
kvb

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/12/2009 at 13:43, xxxxxxxx wrote:

Well, you won´t get around a bit of math but it´s so simple you won´t even bother. 😉

You get the y position by using GetPoint() which returns an according vector, so you take the y-component of hte result. Now if you want to map this to -5 and 5, the simplest way is to use a lerp operation. Fortunately the sdk provides you with that function, it´s called Mix. You can use it also for the x-range.

In code this looks sth like this:

  
//Input X Range  
Real x_min = -100;  
Real x_max = 100;  
Real x_delta = x_max - x_min;  
  
//Calculate Relative position of input x value inbetween the Input X Range (additionally clamp it between 0 and 1)  
Real x_pos = Clamp(0,1, (x_input_value - x_min)/x_delta);  
//Get the darn y position with GetPoint  
Real y_pos = splinegraphdata->GetPoint(x_pos).y; //x between 0...1  
  
//Output Y Range  
Real y_range_min = -5;  
Real y_range_max = 5;  
//Simple Lerp operation with y_pos (which is always between 0...1)  
return Mix(y_range_min,y_range_max,y_pos);

You see, not very hard at all. And it´s worth making a template inline function out of it.

Have fun. 😉

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/12/2009 at 14:24, xxxxxxxx wrote:

Wow Katachi... you just blew my frakkin' mind:D  I just wanna give ya a big ol' man hug:D

First thing I checked out was GetPoint .  After reading it... I was just more confused than before; because I was misreading it's explanation:D  Seeing it in context makes me want to go find my dunce cap... I think I deserve to have to wear it today.  I knew it was going to be something stupid like sentence structure clogging up my thought process... you have no idea how far down the wrong road I was going:D

And apologies if my questions seem stupid (not that it was implied, but I'm always so embarrassed when I post here).  I know I must seem like the guy who doesn't know how to make his cube shiny;)  But I'm trying my best to keep my incompetence off the boards as much as possible;)  These examples give me a great amount of clarity, thank you all for them (the board is full of gems from over the years, so those included).  The plugin I'm writing is meant to be a community freeby, so it's all for a good cause:)

Thank you again, I'm off to digest all this,
kvb

P.S.  I got the recording working beautifully btw, so thanks for re-adjusting my perception on that too;)