/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct ObjManStr = [ PMAN_instance : PInstance, PMAN_obj : SO3_OBJECT, PMAN_shell : SO3_OBJECT, PMAN_rotateshell : SO3_OBJECT, PMAN_fScale : F, PMAN_tInitRot : [F F F], PMAN_tRot : [F F F], PMAN_tInitOff : [F F F], PMAN_tInitState : [SO3_OBJECT [F F F] [F F F F] [F F F]], PMAN_lControls : [[S [[F F F] [F F F] F I]] r1], PMAN_move : [[F F F] [F F F]], PMAN_fInertia : F, PMAN_fInertiaValues : [F F F], PMAN_bLastNavState : I, PMAN_lPressedKeys : [[I I] r1], PMAN_tLastTrans : [I I], PMAN_bRotateMode : I, PMAN_bState : I, PMAN_sGroupName : S, PMAN_plane : SO3_OBJECT, PMAN_material : SO3_MATERIAL, PMAN_texture : SO3_TEXTURE, PMAN_fLastFovY : F ]mkObjManStr;; fun restoreObject(objpstr)= if (!objpstr.PMAN_bState) then nil else let objpstr.PMAN_tInitState -> [parent pos quat scale] in ( SO3ObjectLink objpstr.PMAN_obj parent; SO3ObjectSetPosition objpstr.PMAN_obj pos; SO3ObjectSetOrientation objpstr.PMAN_obj quat; SO3ObjectSetScale objpstr.PMAN_obj scale; ); 0;; fun deleteOb(inst, objpstr)= setPluginInstanceCbScenePreRender inst nil; setPluginInstanceCbCameraChange inst nil; restoreObject objpstr; SO3ObjectDestroy objpstr.PMAN_plane; set objpstr.PMAN_plane = nil; SO3MaterialDestroy objpstr.PMAN_material; set objpstr.PMAN_material = nil; SO3TextureDestroy objpstr.PMAN_texture; set objpstr.PMAN_texture = nil; SO3ObjectDestroy objpstr.PMAN_rotateshell; set objpstr.PMAN_rotateshell = nil; SO3ObjectDestroy objpstr.PMAN_shell; set objpstr.PMAN_shell = nil; V3DenableNavigate c3dXsession objpstr.PMAN_bLastNavState; SO3GroupDelete (V3DgetSession c3dXsession) objpstr.PMAN_sGroupName; set objpstr.PMAN_lControls = nil; 0;; fun computeControls(objpstr, ftime, fspeed)= let ftime /. 1000.0 -> nbsec in let [fspeed fspeed fspeed] -> vspeed in let if nbsec == 0.0 then 0.0001 else nbsec -> nbsec in let [nbsec nbsec nbsec] -> vnbsec in // analogic data let [0.0 0.0 0.0] -> avec in let [0.0 0.0 0.0] -> aang in // real data let [0.0 0.0 0.0] -> vec in let [0.0 0.0 0.0] -> ang in let 0.0 -> ycam in ( let sizelist objpstr.PMAN_lControls -> size in let 0 -> i in while i < size do ( let nth_list objpstr.PMAN_lControls i -> [_ tcontrol] in let tcontrol -> [nvec nang nycam mode] in ( if (!mode) then ( set avec = addVectorF avec nvec; set aang = addVectorF aang nang; 0; ) else ( set vec = addVectorF vec nvec; set ang = addVectorF ang nang; set ycam = ycam +. nycam; //reset control mutate tcontrol <- [[0.0 0.0 0.0] [0.0 0.0 0.0] 0.0 mode]; 0; ); ); set i = i + 1; ); let objpstr.PMAN_move -> [kvec kang] in ( set avec = multiplyVectorF (addVectorF avec kvec) vnbsec; set aang = multiplyVectorF multiplyVectorF (addVectorF aang kang) vnbsec [45.0 45.0 45.0]; //45 degree per second ? set avec = multiplyVectorF avec vspeed; let aang -> [pitch yaw roll] in set aang = [(SO3MathsDegreeToRadian -.pitch) (SO3MathsDegreeToRadian -.yaw) (SO3MathsDegreeToRadian -.roll)]; ); let ang -> [ax ay az] in set ang = [(SO3MathsDegreeToRadian ax) (SO3MathsDegreeToRadian ay) (SO3MathsDegreeToRadian az)]; [(addVectorF avec vec) (addVectorF aang ang) ycam]; );; fun cbVnavKeyDown(inst, viewstr, key, ascode, objpstr)= let _keybdstate -> ctrlstate in let objpstr.PMAN_move -> [vec ang] in let 1.0 -> v in let 1.0 -> a in if (switch objpstr.PMAN_lPressedKeys key) != nil then nil else ( let if key == 328 then // UP a else if key == 336 then // DOWN -.a else nil -> pitch in let if key == 331 then // LEFT a else if key == 333 then // RIGHT -.a else nil -> yaw in ( if pitch == nil then nil else mutate ang <- [pitch _ _]; if yaw == nil then nil else mutate ang <- [_ yaw _]; ); set objpstr.PMAN_lPressedKeys = [key (if ctrlstate == nil then 0 else ctrlstate)]::objpstr.PMAN_lPressedKeys; ); 0;; fun cbVnavKeyUp(inst, viewstr, key, objpstr)= let objpstr.PMAN_move -> [vec ang] in let switch objpstr.PMAN_lPressedKeys key -> ctrlstate in ( set objpstr.PMAN_lPressedKeys = (remove_idx_from_list objpstr.PMAN_lPressedKeys key); // UP & DOWN if (key != 328) && (key != 336) then nil else if ctrlstate & 2 then mutate vec <- [_ 0.0 _] else mutate ang <- [0.0 _ _]; // LEFT & RIGHT if (key != 331) && (key != 333) then nil else if ctrlstate & 2 then mutate vec <- [0.0 _ _] else mutate ang <- [_ 0.0 _]; ); 0;; fun cbVnavWheel(inst, viewstr, x, y, delta, btn, objpstr)= let SO3ObjectGetScale objpstr.PMAN_shell -> [_ _ z] in ( let ((itof delta) *. (objpstr.PMAN_fScale /. 10.0)) -> zm in if zm <. 0.0 && z <=. 0.0 then nil else let (z +. zm) -> dist in let [objpstr.PMAN_fScale (objpstr.PMAN_fScale *. 2.0)] -> [mindist maxdist] in let if (dist <. mindist) then mindist else if (dist >. maxdist) then maxdist else dist -> dist in ( SO3ObjectSetScale objpstr.PMAN_shell [dist dist dist]; ); ); 0;; fun cbScale(inst, from, action, param, reply, objpstr)= let strextr param -> lp in let atof hd (hd lp) -> ps in let SO3ObjectGetScale objpstr.PMAN_shell -> [_ _ z] in ( let (ps *. (objpstr.PMAN_fScale /. 10.0)) -> zm in if zm <. 0.0 && z <=. 0.0 then nil else let (z +. zm) -> dist in let [objpstr.PMAN_fScale (objpstr.PMAN_fScale *. 2.0)] -> [mindist maxdist] in let if (dist <. mindist) then mindist else if (dist >. maxdist) then maxdist else dist -> dist in ( SO3ObjectSetScale objpstr.PMAN_shell [dist dist dist]; ); ); 0;; fun getObjectDim(objpstr)= restoreObject objpstr; SO3ObjectSetPosition objpstr.PMAN_obj [0.0 0.0 0.0]; SO3ObjectSetOrientation objpstr.PMAN_obj [0.0 0.0 0.0 1.0]; SO3ObjectSetScale objpstr.PMAN_obj [1.0 1.0 1.0]; let SO3ObjectGetBoundingBoxInfo objpstr.PMAN_obj 1 -> [box center _] in let box -> [bx by bz] in [box [(bx /. 2.0) (-.by /. 2.0) (bz /. 2.0)]];; fun updateCamera(camera, objpstr)= let SO3CameraGetNearClipDistance camera -> nclip in let SO3CameraGetFOVy camera -> fovy in let getObjectDim objpstr -> [size [px py pz]] in let size -> [sx sy sz] in let if sx >. sy then sx else sy -> radius in let if radius >. sz then radius else sz -> radius in let if size == nil then 1.0 else radius -> radius in let ((nclip +. (radius /. 4.0)) /. atan fovy) -> scale in let nclip /. scale -> scale in let [0.0 (py *. scale) (-.(nclip +. ((radius /. 2.0) *. (scale *. 2.1))))] -> [nx ny nz] in ( SO3ObjectLink objpstr.PMAN_shell camera; SO3ObjectLink objpstr.PMAN_rotateshell objpstr.PMAN_shell; SO3ObjectLink objpstr.PMAN_obj objpstr.PMAN_rotateshell; SO3ObjectLink objpstr.PMAN_plane camera; SO3ObjectSetPosition objpstr.PMAN_obj (multiplyVectorF objpstr.PMAN_tInitOff [(-.1.0) (-.1.0) (-.1.0)]); // [nx ny 0.0]; SO3ObjectSetOrientation objpstr.PMAN_obj [0.0 0.0 0.0 1.0]; SO3ObjectSetScale objpstr.PMAN_obj [1.0 1.0 1.0]; //SO3ObjectSetPosition objpstr.PMAN_rotateshell objpstr.PMAN_tInitOff; SO3ObjectSetOrientation objpstr.PMAN_rotateshell [0.0 0.0 0.0 1.0]; SO3ObjectSetScale objpstr.PMAN_rotateshell [1.0 1.0 1.0]; SO3ObjectSetPosition objpstr.PMAN_shell [0.0 0.0 nz]; SO3ObjectSetOrientation objpstr.PMAN_shell [0.0 0.0 0.0 1.0]; SO3ObjectSetScale objpstr.PMAN_shell [scale scale scale]; let SO3CameraGetFocalLength camera -> cameraFocalLength in ( SO3ObjectSetPosition objpstr.PMAN_plane [0.0 0.0 (cameraFocalLength *. (-.1.0))]; SO3ObjectSetOrientation objpstr.PMAN_plane SO3MathsEulerXYZToQuat [(SO3MathsDegreeToRadian (-.180.0)) (SO3MathsDegreeToRadian 90.0) 0.0]; let ((atan (fovy /. 2.0)) *. cameraFocalLength) /. 0.5 -> planeScale in // Plane size is 1.0, so the corresponding size for the half rendering surface is 0.5 let planeScale *. 0.95 -> planeScale in // 0.95 factor for circle marging, if you change this, then change the corresponding factor in mouse position computation. SO3ObjectSetScale objpstr.PMAN_plane [planeScale planeScale planeScale]; ); SO3ObjectSetVisible objpstr.PMAN_plane 0 1; set objpstr.PMAN_fLastFovY = fovy; set objpstr.PMAN_fScale = scale; ); 0;; fun cbControlPreRender(inst, sessionstr, etime, objpstr)= let if etime <= 1000 then 1 else etime / 1000 -> etime in if (!objpstr.PMAN_bState) then nil else let sessionstr.V3D_sessionView -> viewstr in let computeControls objpstr itof etime 1.0 -> [vec [pitch yaw roll] ycam] in ( //update position from camera FOV let V3DgetDefaultCamera sessionstr -> camera in let SO3CameraGetFOVy camera -> fovy in if (objpstr.PMAN_fLastFovY == fovy) then nil else ( updateCamera camera objpstr; ); if ((pitch == 0.0) && (yaw == 0.0) && (roll == 0.0)) then nil else set objpstr.PMAN_tRot = [0.0 0.0 0.0]; let objpstr.PMAN_fInertiaValues -> [xib yib zib] in let [(if xib == 0.0 || xib == nil || objpstr.PMAN_fInertia == 0.0 then 0.0 else xib -. (xib /. objpstr.PMAN_fInertia)) (if yib == 0.0 || yib == nil || objpstr.PMAN_fInertia == 0.0 then 0.0 else yib -. (yib /. objpstr.PMAN_fInertia)) (if zib == 0.0 || zib == nil || objpstr.PMAN_fInertia == 0.0 then 0.0 else zib -. (zib /. objpstr.PMAN_fInertia))] -> [iax iay iaz] in let [(if pitch != 0.0 then pitch else (pitch +. iax)) (if yaw != 0.0 then yaw else (yaw +. iay)) (if roll != 0.0 then roll else (roll +. iaz))] -> [nix niy niz] in ( if (iax == 0.0 && iay == 0.0 && iaz == 0.0) then nil else let objpstr.PMAN_tInitRot -> [irx iry irz] in ( if (nix >. iry) then nil else mutate objpstr.PMAN_tRot <- [_ iry _]; if (niy >. irx) then nil else mutate objpstr.PMAN_tRot <- [irx _ _]; if (niz >. irz) then nil else mutate objpstr.PMAN_tRot <- [_ _ irz]; ); set objpstr.PMAN_fInertiaValues = [nix niy niz]; SO3ObjectRotatePitch objpstr.PMAN_rotateshell nix SO3_PARENT_TS; SO3ObjectRotateYaw objpstr.PMAN_rotateshell niy SO3_PARENT_TS; SO3ObjectRotateRoll objpstr.PMAN_rotateshell niz SO3_PARENT_TS; ); let vec -> [_ _ vz] in let SO3ObjectGetScale objpstr.PMAN_shell -> [_ _ sz] in ( let ((-.vz /. 10.0) *. (objpstr.PMAN_fScale /. 10.0)) -> zm in if zm <. 0.0 && sz <=. 0.0 then nil else let (sz +. zm) -> dist in let [objpstr.PMAN_fScale (objpstr.PMAN_fScale *. 2.0)] -> [mindist maxdist] in let if (dist <. mindist) then mindist else if (dist >. maxdist) then maxdist else dist -> dist in ( SO3ObjectSetScale objpstr.PMAN_shell [dist dist dist]; ); ); // Compute circle center let V3DgetViewSize viewstr -> [iWinW iWinH] in let [((itof iWinW) /. 2.0) ((itof iWinH) /. 2.0)] -> [centerx centery] in let V3DgetLastMouseMove viewstr 0 -> [mx my] in let (itof mx) -. centerx -> xdist in let (itof my) -. centery -> ydist in // Compute circle center & mouse distance from center let (centery *. 0.95) *. (centery *. 0.95) -> circleSquareRadius in let xdist *. xdist +. ydist *. ydist -> mouseSquareDist in let V3DgetCursorTrans viewstr -> curstrans in if curstrans == nil then ( set objpstr.PMAN_tLastTrans = [0 0]; set objpstr.PMAN_bRotateMode = nil; if mouseSquareDist <=. circleSquareRadius then SO3ObjectSetVisible objpstr.PMAN_plane 0 1 else SO3ObjectSetVisible objpstr.PMAN_plane 1 1; 0; ) else ( let V3DgetViewSize viewstr -> [iWinW iWinH] in let curstrans -> [dx dy] in let objpstr.PMAN_tLastTrans -> [lx ly] in let [(dx-lx) (dy-ly)] -> [nx ny] in let 180.0 /. (itof iWinW) *. (itof nx) -> fdx in let 180.0 /. (itof iWinH) *. (itof ny) -> fdy in ( set objpstr.PMAN_tLastTrans = [dx dy]; set objpstr.PMAN_tRot = [0.0 0.0 0.0]; set objpstr.PMAN_fInertiaValues = [0.0 0.0 0.0]; // Test inside of the 'third axe' circle. ( if (objpstr.PMAN_bRotateMode == nil) then if mouseSquareDist <=. circleSquareRadius then set objpstr.PMAN_bRotateMode = 0 else set objpstr.PMAN_bRotateMode = 1 else nil; if objpstr.PMAN_bRotateMode == 0 then ( // Inside circle let if fdx >. 0.0 then 1.0 else if fdx <. 0.0 then -.1.0 else 0.0 -> xAxis in let if fdy >. 0.0 then -.1.0 else if fdy <. 0.0 then 1.0 else 0.0 -> yAxis in let [yAxis xAxis 0.0] -> axis in // Diagonal? let 1.0 -> seuil in let if ((absf fdx) >. seuil) && ((absf fdy) >. seuil) && (((absf fdx) -. (absf fdy)) >=. (seuil *. -.1.0)) && (((absf fdx) -. (absf fdy)) <=. seuil) then 2 else if ((absf fdx) >. (absf fdy)) then 1 else 0 -> onxAxis in let if onxAxis == 2 then axis else if onxAxis == 1 then [0.0 xAxis 0.0] else [yAxis 0.0 0.0] -> axis in let (rootn (fdx *. fdx +. fdy *. fdy) 2.0) -> disp in ( SO3ObjectRotate objpstr.PMAN_rotateshell (SO3MathsDegreeToRadian disp) axis SO3_PARENT_TS; if onxAxis == 0 then mutate objpstr.PMAN_fInertiaValues <- [(SO3MathsDegreeToRadian disp *. yAxis) _ _] else if onxAxis == 1 then mutate objpstr.PMAN_fInertiaValues <- [_ (SO3MathsDegreeToRadian disp *. xAxis) _] else mutate objpstr.PMAN_fInertiaValues <- [SO3MathsDegreeToRadian -.fdy SO3MathsDegreeToRadian fdx _] ); ) else ( // Outside circle, rotate on z axis. Check mouse quadran. let if ((absf fdx) >. (absf fdy)) then 1 else 0 -> onxAxis in let if ((xdist <. 0.0) && (ydist <. 0.0)) then // Top left corner ( if onxAxis == 1 then if (fdx >. 0.0) then [0.0 0.0 (-.1.0)] else [0.0 0.0 1.0] else if (fdy >. 0.0) then [0.0 0.0 (-.1.0)] else [0.0 0.0 1.0] ) else ( if ((xdist >. 0.0) && (ydist <. 0.0)) then // Top right corner ( if onxAxis == 1 then if (fdx >. 0.0) then [0.0 0.0 (-.1.0)] else [0.0 0.0 1.0] else if (fdy >. 0.0) then [0.0 0.0 1.0] else [0.0 0.0 (-.1.0)] ) else ( if ((xdist >. 0.0) && (ydist >. 0.0)) then // Bottom right corner ( if onxAxis == 1 then if (fdx >. 0.0) then [0.0 0.0 1.0] else [0.0 0.0 (-.1.0)] else if (fdy >. 0.0) then [0.0 0.0 1.0] else [0.0 0.0 (-.1.0)] ) else ( if ((xdist <. 0.0) && (ydist >. 0.0)) then // Bottom left corner ( if onxAxis == 1 then if (fdx >. 0.0) then [0.0 0.0 1.0] else [0.0 0.0 (-.1.0)] else if(fdy >. 0.0) then [0.0 0.0 (-.1.0)] else [0.0 0.0 1.0] ) else ( [0.0 0.0 0.0] // Not possible but makes compiler happy ) ) ) ) -> axis in // Rotate on Z axis relative to Camera (which is the parent node of PMAN_shell). let (rootn (fdx *. fdx +. fdy *. fdy) 2.0) -> disp in let axis -> [xAxis yAxis zAxis] in ( SO3ObjectSetVisible objpstr.PMAN_plane 1 1; SO3ObjectRotate objpstr.PMAN_rotateshell (SO3MathsDegreeToRadian disp) axis SO3_PARENT_TS; mutate objpstr.PMAN_fInertiaValues <- [_ _ SO3MathsDegreeToRadian (disp *. zAxis)]; ); ); ); ); 0; ); let objpstr.PMAN_tRot -> [ax ay az] in let ax *. ((itof etime) /. 1000.0) -> ax in let ay *. ((itof etime) /. 1000.0) -> ay in let az *. ((itof etime) /. 1000.0) -> az in ( SO3ObjectRotatePitch objpstr.PMAN_rotateshell ax SO3_PARENT_TS; SO3ObjectRotateYaw objpstr.PMAN_rotateshell ay SO3_PARENT_TS; SO3ObjectRotateRoll objpstr.PMAN_rotateshell az SO3_PARENT_TS; ); ); 0;; fun cbChangeCamera(inst, viewstr, sessionstr, camera, objpstr)= if (camera != V3DgetDefaultCamera c3dXsession) then nil else if(!objpstr.PMAN_bState) then nil else ( updateCamera camera objpstr; ); 0;; fun cbControl(inst, from, action, param, reply, objpstr)= if (!objpstr.PMAN_bState) then nil else let if reply == nil then "control" else reply -> reply in //get the input control from the link let switchstr objpstr.PMAN_lControls reply -> icontrol in ( // if not already int the list we add it if (icontrol != nil) then nil else ( set objpstr.PMAN_lControls = [reply [[0.0 0.0 0.0] [0.0 0.0 0.0] 0.0 0]]::objpstr.PMAN_lControls; set icontrol = switchstr objpstr.PMAN_lControls reply; //addLogMessage strcat "add control " reply; ); let strextr param -> l in let hd l -> sv in let hd tl l -> sa in let hd (hd tl tl l) -> mode in let icontrol -> [ovec oang ycam _] in let ovec -> [ovx ovy ovz] in let oang -> [oax oay oaz] in let if mode == nil then 0 else atoi mode -> imode in let [(nth_list sv 0) (nth_list sv 1) (nth_list sv 2)] -> [svx svy svz] in let [(if (!strcmp "_" svx) || (svx == nil) then ovx else (atof svx)) (if (!strcmp "_" svy) || (svy == nil) then ovy else (atof svy)) (if (!strcmp "_" svz) || (svz == nil) then ovz else (atof svz))] -> [vx vy vz] in let [(nth_list sa 0) (nth_list sa 1) (nth_list sa 2)] -> [sax say saz] in let [(if (!strcmp "_" sax) || (sax == nil) then oax else (atof sax)) (if (!strcmp "_" say) || (say == nil) then oay else (atof say)) (if (!strcmp "_" saz) || (saz == nil) then oaz else (atof saz))] -> [ax ay az] in ( if !imode then mutate icontrol <- [[vx vy vz] [ax ay az] 0.0 imode] else // accumulator mutate icontrol <- [(addVectorF ovec [vx vy vz]) (addVectorF oang [ax ay az]) ycam imode]; ); ); 0;; fun cbRotate(inst, from, action, param, reply, objpstr)= if (!objpstr.PMAN_bState) then nil else let strextr param -> l in let hd l -> sa in let [atof(nth_list sa 0) atof(nth_list sa 1) atof(nth_list sa 2)] -> [ax ay az] in let (2.0 *. PIf) /. 360.0 -> a in ( SO3ObjectRotatePitch objpstr.PMAN_rotateshell (ax *. a) SO3_PARENT_TS; SO3ObjectRotateYaw objpstr.PMAN_rotateshell (ay *. a) SO3_PARENT_TS; SO3ObjectRotateRoll objpstr.PMAN_rotateshell (az *. a) SO3_PARENT_TS; ); 0;; fun cbEnable(inst, from, action, param, rep, objpstr)= if(objpstr.PMAN_bState) then nil else ( set objpstr.PMAN_tLastTrans = [0 0]; set objpstr.PMAN_bRotateMode = nil; set objpstr.PMAN_tRot = objpstr.PMAN_tInitRot; let c3dXsession -> sessionstr in set objpstr.PMAN_bLastNavState = sessionstr.V3D_bNavigate; V3DenableNavigate c3dXsession 0; let SO3ObjectGetParent objpstr.PMAN_obj -> cparent in let SO3ObjectGetPosition objpstr.PMAN_obj -> cpos in let SO3ObjectGetOrientation objpstr.PMAN_obj -> cquat in let SO3ObjectGetScale objpstr.PMAN_obj -> cscale in set objpstr.PMAN_tInitState = [cparent cpos cquat cscale]; set objpstr.PMAN_shell = V3DaddShell c3dXsession strcat (getPluginInstanceName inst) "_Manipulate_dummy" nil nil nil nil; set objpstr.PMAN_rotateshell = V3DaddShell c3dXsession strcat (getPluginInstanceName inst) "_Manipulate_rotate_dummy" nil nil nil nil; // Plane for circle texture let strcat (getPluginInstanceName objpstr.PMAN_instance) ".plane" -> name in let SO3MaterialCreate (V3DgetSession c3dXsession) (strcat name ".material") objpstr.PMAN_sGroupName -> mat in let SO3TextureCreate (V3DgetSession c3dXsession) (strcat name ".texture") nil objpstr.PMAN_sGroupName 512 512 -> tex in let SO3PlaneCreate (V3DgetSession c3dXsession) objpstr.PMAN_sGroupName name [1.0 1.0] nil nil -> plane in let V3DgetDefaultCamera c3dXsession -> camera in ( set objpstr.PMAN_plane = plane; set objpstr.PMAN_material = mat; set objpstr.PMAN_texture = tex; let strcatn (getPluginDirectory (getInstancePlugin inst))::"/"::"circle.png"::nil -> path in let G2DloadAlphaBmp _channel path -> abmp in SO3TextureBlitAlpha tex abmp; SO3MaterialSetTexture mat tex 0 0 0; SO3EntitySetMaterial plane mat 0; SO3MaterialIsLighting mat 0; SO3MaterialSetPassAlphaRejection mat 0 0 SO3_COMPARE_FUNCTION_GREATER_EQUAL 128 1; updateCamera camera objpstr; set objpstr.PMAN_bState = 1; setPluginInstanceCbKeyDown inst mkfun5 @cbVnavKeyDown objpstr; setPluginInstanceCbKeyUp inst mkfun4 @cbVnavKeyUp objpstr; setPluginInstanceCbWheel inst mkfun7 @cbVnavWheel objpstr; setPluginInstanceCbScenePreRender inst mkfun4 @cbControlPreRender objpstr; ) ); 0;; fun cbDisable(inst, from, action, param, rep, objpstr)= if(!objpstr.PMAN_bState) then nil else ( setPluginInstanceCbScenePreRender inst nil; restoreObject objpstr; SO3ObjectDestroy objpstr.PMAN_plane; set objpstr.PMAN_plane = nil; SO3MaterialDestroy objpstr.PMAN_material; set objpstr.PMAN_material = nil; SO3TextureDestroy objpstr.PMAN_texture; set objpstr.PMAN_texture = nil; SO3ObjectDestroy objpstr.PMAN_rotateshell; set objpstr.PMAN_rotateshell = nil; SO3ObjectDestroy objpstr.PMAN_shell; set objpstr.PMAN_shell = nil; V3DenableNavigate c3dXsession objpstr.PMAN_bLastNavState; setPluginInstanceCbKeyDown inst nil; setPluginInstanceCbKeyUp inst nil; setPluginInstanceCbWheel inst nil; set objpstr.PMAN_bState = 0; ); 0;; fun newOb(inst)= let (getPluginInstanceParam inst "object") -> objname in let SO3MathsDegreeToRadian atof (getPluginInstanceParam inst "rotx") -> ax in let SO3MathsDegreeToRadian atof (getPluginInstanceParam inst "roty") -> ay in let SO3MathsDegreeToRadian atof (getPluginInstanceParam inst "rotz") -> az in let atof (getPluginInstanceParam inst "offsetx") -> ox in let atof (getPluginInstanceParam inst "offsety") -> oy in let atof (getPluginInstanceParam inst "offsetz") -> oz in let if (!strcmpi "Current camera shell" objname) then nil else SO3SceneGetObject (V3DgetSession c3dXsession) objname -> father in let atoi (getPluginInstanceParam inst "init") -> init in let if (init == nil) then 1 else init -> init in let atof (getPluginInstanceParam inst "inertia") -> inertia in let if inertia == nil then 1.0 else inertia -> inertia in let SO3ObjectGetParent father -> cparent in let SO3ObjectGetPosition father -> cpos in let SO3ObjectGetOrientation father -> cquat in let SO3ObjectGetScale father -> cscale in let c3dXsession -> sessionstr in let mkObjManStr [inst father nil nil 1.0 [ax ay az] [ax ay az] [ox oy oz] [cparent cpos cquat cscale] nil [[0.0 0.0 0.0] [0.0 0.0 0.0]] inertia nil sessionstr.V3D_bNavigate nil [0 0] 0 0 nil nil nil nil 0.0] -> objpstr in ( set objpstr.PMAN_sGroupName = strcat (getPluginInstanceName inst) "_Group"; SO3GroupCreate (V3DgetSession c3dXsession) objpstr.PMAN_sGroupName; setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera objpstr; setPluginInstanceCbDel inst mkfun2 @deleteOb objpstr; PluginRegisterAction inst "Control" mkfun6 @cbControl objpstr; PluginRegisterAction inst "Rotate" mkfun6 @cbRotate objpstr; PluginRegisterAction inst "Scale" mkfun6 @cbScale objpstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable objpstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable objpstr; if(!init) then nil else cbEnable inst nil nil nil nil objpstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;