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.
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
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
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
thx arkeon....I will set up a test scene and see how it works out.
-h
Offline
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
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
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
OK...Thx arkeon I think I can see how this can be done.
Offline
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
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
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
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