Scolring - Forum

Entraides et échanges autour de la technologie Scol - Informations and exchanges on the Scol technology

Vous pouvez changer la langue de l'interface une fois inscrit - You can change the language once registered

You are not logged in.

#1 24-Dec-2013 15:20:12

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

psuedo code for linear interpolation between two transforms

Colleagues:

I think I am ready to tackle interpolation, but I have no idea of how to do it. I want to be doing it with my multiplayer code, but perhaps it would be best for me to start off with a simple example.

Step 1: Moving one object
So let's say that I have a scene node, contained in the variable Ball. 
1. Ball has a position of 5.0 5.0 5.0 and a rotation of .4 .5 .7 .2  I want to move it to 0 0 0 and to a rotation of 0.0 0.0 0.0 0.0, over a period of 40 frames.


the next thing I'd like to do is the same thing with two balls
Step 2: Moving two objects, each of which starts to move at a different time.  The first object starts moving before the seond one. For a short time they may be both moving...the first object completes its move before the second object completes its move.  This is closer to what I want to do in my multiplayer script.

1. 500ms after the scene is loaded, Ball does the movement I described above.
2. 750ms after the scene loads, Ball2 moves from 4.0 4.0 4.0 and a rotation of .4 .5 .7 .2 to 10.0 0.0 0.0 and to a rotation of 0.0 0.0 0.0 0.0, over a period of 40 frames.



I've looked at the moveto and goto plugits but I cannot understand them. 

merry xmas, eid, hannukah, solstice, time-off-from-work.

thx for your help, I think I know enough scol and scol debugging messages to work from psuedo code.

-h

Offline

#2 24-Dec-2013 15:45:48

arkeon
Admin. / Scol language & OpenSpace3D developer
From: Nantes
Registered: 30-Mar-2009
Posts: 5,161
Website

Re: psuedo code for linear interpolation between two transforms

Hi !

First you should use time note framerate, since the frame rate depend of the pc performances.

Offline

#3 24-Dec-2013 16:16:32

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

arkeon wrote:

Hi !

First you should use time note framerate, since the frame rate depend of the pc performances.

thx arkeon, that's fine....what would the psuedo code look like?

Offline

#4 24-Dec-2013 16:20:13

arkeon
Admin. / Scol language & OpenSpace3D developer
From: Nantes
Registered: 30-Mar-2009
Posts: 5,161
Website

Re: psuedo code for linear interpolation between two transforms

here a sample code to interpolate an object position for 1 second (not tested)

struct STInterpolate = [
                    OINT_inst       : PInstance,
                    OINT_obj        : SO3_OBJECT,
                    OINT_srcpos     : [[F F F] [F F F F]],
                    OINT_dstpos     : [[F F F] [F F F F]],
                    OINT_fCoef      : F
                    
                  ] mkSTInterpolate;;


fun vecLerp (v1, v2, coef)=
  let multiplyVectorF v1 [coef coef coef] -> v1t in
  let multiplyVectorF v2 [(1.0 -. coef) (1.0 -. coef) (1.0 -. coef)] -> v2t in
    addVectorF v1t + v2t;
  0;;


fun cbMoveObj(inst, sessionstr, etime, strobj)=
  let (itof etime) /. 1000.0 -> fsec in //time since last frame in second
  let strobj.OINT_srcpos -> [srcvec srcang] in
  let strobj.OINT_dstpos -> [dstvec dstang] in
  (
    // 1.0 second to complete the mouvement  
    let fsec -> nstep in
    // increment the move step
      set strobj.OINT_fCoef = if (strobj.OINT_fCoef +. nstep) >. 1.0 then 1.0 else strobj.OINT_fCoef +. nstep;
    
    // movement complete or time out, we set the destination pos
    if (strobj.OINT_fCoef ==. 1.0) then
    (
      //force last frame
      SO3ObjectSetPosition strobj.OINT_obj dstvec;
      SO3ObjectSetOrientation strobj.OINT_obj dstang;
      0;
    )
    else
    (
      // interpolate positions
      let vecLerp srcvec dstvec strobj.OINT_fCoef -> npos in
      // interpolate quaternion with shortest angle
      let SO3MathsQuatInterpolate srcang dstang strobj.OINT_fCoef 1 -> nang in
      (
        SO3ObjectSetPosition strobj.OINT_obj npos;
        SO3ObjectSetOrientation strobj.OINT_obj nang;
        0;
      );
    );
  );
  0;;


fun newOb(inst)=
  let (getPluginInstanceParam inst "obj") -> objname in
  let V3DgetObjectByName c3dXsession sourcename -> obj in
  let mkTobjGoto [inst obj nil nil nil] -> strobj in
  (
    set strobj.OINT_srcpos = [(SO3ObjectGetPosition obj) (SO3ObjectGetOrientation obj)];
    set strobj.OINT_dstpos = [[0.0 0.0 0.0] [0.0 0.0 0.0 1.0]];
    set strobj.OINT_fCoef = 0.0;
    
    setPluginInstanceCbScenePostRender inst mkfun4 @cbMoveObj strobj;
  );
  0;;


fun IniPlug(file)=
  PlugRegister @newOb nil;
  setPluginEditor @dynamicedit;
  0;;

Offline

#5 24-Dec-2013 16:44:14

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

thx arkeon....I will set up a test scene and see how it works out.

-h

Offline

#6 24-Dec-2013 17:35:34

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

Arkeon is it possible to trigger multiple instances of an interpolated moveto  function in the code of a single plugit....or am I limited to only one function triggered before a frame and one function after a frame?

Last edited by hebdemnobad (24-Dec-2013 17:35:58)

Offline

#7 24-Dec-2013 18:37:53

arkeon
Admin. / Scol language & OpenSpace3D developer
From: Nantes
Registered: 30-Mar-2009
Posts: 5,161
Website

Re: psuedo code for linear interpolation between two transforms

You mean one callback by client ?
Actually you can only set a render callback per plugit instance

You should apply the interpolation on your clients list ine the callback

Offline

#8 24-Dec-2013 18:49:11

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

I see....so I would do something like make the moveto struct a component of a Remote_not struct, and the pre or post render callback would get and set each Remote_bot's position depending on each Remote_bot's position, rotation, and time elapsed between the beginning of its movement and end of its movement.

Last edited by hebdemnobad (24-Dec-2013 18:50:01)

Offline

#9 24-Dec-2013 19:16:26

arkeon
Admin. / Scol language & OpenSpace3D developer
From: Nantes
Registered: 30-Mar-2009
Posts: 5,161
Website

Re: psuedo code for linear interpolation between two transforms

yes something like that smile

Offline

#10 24-Dec-2013 19:37:23

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

OK...Thx arkeon I think I can see how this can be done.

Offline

#11 25-Dec-2013 00:58:02

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

akreon I have some general questions about callbacks that don't have to do with this code in particular, but I'm trying to understand it:

setPluginInstanceCbScenePostRender inst mkfun4 @cbMoveObj strobj;

1. I assume mkfun4 means that the cbMoveObj function has four parameters? Is that right?

fun cbMoveObj(inst, sessionstr, etime, strobj)

2. I assume that the 'inst' and 'strobj' parameters are passed to the cbMOveObj function from setPluginInstanceCbScenePostRender inst mkfun4 @cbMoveObj strobj.   where do the 'etime' and 'sessionstr' paramaters come from. are they properties of any plugin instance?

Offline

#12 25-Dec-2013 11:39:34

arkeon
Admin. / Scol language & OpenSpace3D developer
From: Nantes
Registered: 30-Mar-2009
Posts: 5,161
Website

Re: psuedo code for linear interpolation between two transforms

callbacks have defined params.
here the setPluginInstanceCbScenePostRender call a function with 3 params [callback instance, 3d session, time from the last render]
mkfun4 says that we want to add a user parameter to the function to pass it from 3 parameters to 4.
so the 4th parameter is the strobj.

the callback is called like this : execch inst.INST_plugin.PLUG_channel inst.INST_cbScenePostRender [inst sessionstr etime];
in os3dlib/os3dpluginscb.pkg

Offline

#13 25-Dec-2013 14:28:12

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

arkeon wrote:

callbacks have defined params.
here the setPluginInstanceCbScenePostRender call a function with 3 params [callback instance, 3d session, time from the last render]
mkfun4 says that we want to add a user parameter to the function to pass it from 3 parameters to 4.
so the 4th parameter is the strobj.

the callback is called like this : execch inst.INST_plugin.PLUG_channel inst.INST_cbScenePostRender [inst sessionstr etime];
in os3dlib/os3dpluginscb.pkg


Thx I see and will be using this with a global list variable.

Offline

#14 27-Dec-2013 17:14:23

iri
Admin. / Scol language & Scol apps developer
From: France
Registered: 22-Feb-2009
Posts: 2,024
Website

Re: psuedo code for linear interpolation between two transforms

Hello !
People work the 25 december ... wink

Offline

#15 28-Dec-2013 18:08:36

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,541
Website

Re: psuedo code for linear interpolation between two transforms

I've got the interpolation code to work, thx arkeon....here it is fwiw. I've excerpted it from my multiplayer script. Arkeon you did a few errors but it wasn't too much to fix. I called the struct and Interpolation_node

struct Interpoloation_node = [
                    OINT_inst       : PInstance,
                    OINT_obj        : SO3_OBJECT,
                    OINT_srcpos     : [[F F F] [F F F F]],
                    OINT_dstpos     : [[F F F] [F F F F]],
                    OINT_fCoef      : F
                    
                  ] mkInterpoloation_node;;

callback setup and initializing of an interpolation node object:

fun newOb(inst)=

  let mkPlugChat [inst netcomOS3D] -> constr in

  (

    set global_chat_instance_variable=inst;

	set plugchatvariable = constr;

    setPluginInstanceCbDel inst mkfun2 @deleteOb plugchatvariable;	

    PluginRegisterAction inst "Show" mkfun6 @cbShow plugchatvariable;

    setPluginInstanceCbNetUserMessage inst mkfun7 @cbReceivedMessage plugchatvariable;

	setPluginInstanceCbNetNewUser inst mkfun4 @cbAddUser plugchatvariable;

	setPluginInstanceCbNetDelUser inst mkfun4 @cbDelUser plugchatvariable;

	//register the prerender callback, the callback will be called before rendering each frame

	//setPluginInstanceCbScenePreRender inst mkfun4 @cbVnavPreRender plugchatvariable;
	//get the node created in the os3d editor
	let SO3SceneGetNode (V3DgetSession c3dXsession) "8.danremappedlowpoly25"-> nodetoget in
	let mkInterpoloation_node [inst nodetoget nil nil nil] -> interpolationnode in
	//open let brace
	(
	 set interpolationnode.OINT_srcpos = [(SO3ObjectGetPosition nodetoget) (SO3ObjectGetOrientation nodetoget)];
    set interpolationnode.OINT_dstpos = [[0.0 (-.3.0) 0.0] [1.0 0.0 0.0 1.0]];
    set interpolationnode.OINT_fCoef = 0.0;
	 setPluginInstanceCbScenePostRender inst mkfun4 @cbMoveObj interpolationnode;
	//return 0 and close let brace
	0;
	);
//close let brace

  );

  0;;

position interpolation function:

//position interpoloation function
fun vecLerp (v1, v2, coef)=
  let multiplyVectorF v1 [coef coef coef] -> v1t in
  let multiplyVectorF v2 [(1.0 -. coef) (1.0 -. coef) (1.0 -. coef)] -> v2t in
  addVectorF v1t v2t;;

function that moves the node, in this case a node created in the editor:

fun cbMoveObj(inst, viewstr, elpased_time, object_to_move)=
    //_ADDcompText ongoing_chat_textfield "rerendercallback called" hacker_font [0x00FFFF 0 0 0xFFFF00] CT_END;

	//_PAINTcontainer hacker_window_object_container;
  //0;;
  let (itof elpased_time) /. 4000.0 -> fsec in //time since last frame in second
  let object_to_move.OINT_srcpos -> [srcvec srcang] in
  let object_to_move.OINT_dstpos -> [dstvec dstang] in
  	(
    			// 1.0 second to complete the mouvement  
   			 let fsec -> nstep in
    			//open let brace
    			(
    			// increment the move step
   			 set object_to_move.OINT_fCoef = if (object_to_move.OINT_fCoef +. nstep) >. 1.0 then 1.0 else object_to_move.OINT_fCoef +. nstep;
    			// movement complete or time out, we set the destination pos
    			if (object_to_move.OINT_fCoef == 1.0) then
    					(
     						 //force last frame
     						SO3ObjectSetPosition object_to_move.OINT_obj dstvec;
      					SO3ObjectSetOrientation object_to_move.OINT_obj dstang;
      					0;
   					 )
    			else
    					(
      					// interpolate positions
      					let vecLerp srcvec dstvec object_to_move.OINT_fCoef -> npos in
      					// interpolate quaternion (rotation) with shortest angle
      					let SO3MathsQuatInterpolate srcang dstang object_to_move.OINT_fCoef  1 -> nang in
      							(
        									SO3ObjectSetPosition object_to_move.OINT_obj npos;
        									SO3ObjectSetOrientation object_to_move.OINT_obj nang;
       									//return 0 and close let brace
        									0;
      							);
						//return 0 and close else brace
						0;
    					);
   				//return 0 and close let brace
  					0;
  					);
  	//return 0 and close let brace
  	0;
  	);
  0;;

thanks!

Offline

Board footer

Powered by FluxBB