/* ----------------------------------------------------------------------------- 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 ----------------------------------------------------------------------------- */ /************************************************** OpenSpace 3D Editor Navigation Author: Bastien BOURINEAU / I-maginer Last update: 11.16.2010 **************************************************/ /* ********************************************************************************************* / Navigation mode / ********************************************************************************************* */ typeof tCameraPosition = [[F F F] [F F F F] F];; struct AvNavigation = [ AV_shell : SO3_OBJECT, AV_camera : SO3_OBJECT, AV_oldCameraPos : [[F F F] [F F F F]], AV_pos : [[F F F] [F F F F] [F F F F]], AV_move : [[F F F] [F F F]], AV_fSpeed : F, AV_fCamHeight : F, AV_lPressedKeys : [[I I] r1] ]mkAvNavigation;; typeof avNavStr = AvNavigation;; fun cbAvNavKeyDown(viewstr, key, ascode, bnavstr)= let _keybdstate -> ctrlstate in let bnavstr.AV_move -> [vec ang] in let 1.0 -> v in let (SO3MathsDegreeToRadian 45.0) -> a in if (switch bnavstr.AV_lPressedKeys key) != nil then nil else ( let if key == 328 then // UP if ctrlstate & 1 then -.a else -.v else if key == 336 then // DOWN if ctrlstate & 1 then a else v else nil -> z in let if key == 331 then // LEFT if ctrlstate & 2 then v else a else if key == 333 then // RIGHT if ctrlstate & 2 then -.v else -.a else nil -> yaw in ( if z == nil then nil else if ctrlstate & 2 then mutate vec <- [_ (-.z) _] else if ctrlstate & 1 then mutate ang <- [(-.z) _ _] else mutate vec <- [_ _ z]; if yaw == nil then nil else if ctrlstate & 2 then mutate vec <- [-.yaw _ _] else mutate ang <- [_ yaw _]; ); set bnavstr.AV_lPressedKeys = [key (if ctrlstate == nil then 0 else ctrlstate)]::bnavstr.AV_lPressedKeys; ); 0;; fun cbAvNavKeyUp(viewstr, key, bnavstr)= let bnavstr.AV_move -> [vec ang] in let switch bnavstr.AV_lPressedKeys key -> ctrlstate in ( set bnavstr.AV_lPressedKeys = (remove_idx_from_list bnavstr.AV_lPressedKeys key); // UP & DOWN if (key != 328) && (key != 336) then nil else if ctrlstate & 1 then mutate ang <- [0.0 _ _] else if ctrlstate & 2 then mutate vec <- [_ 0.0 _] else mutate vec <- [_ _ 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 cbAvNavPreRender(sessionstr, bnavstr, etime)= let if (etime == 0) then 1 else etime -> etime in let (itof etime) /. 1000.0 -> ftime in //milliseconds let ftime /. 1000.0 -> nbsec in let bnavstr.AV_move -> [vec [pitch yaw roll]] in let sessionstr.V3D_sessionView -> viewstr in let (bnavstr.AV_fSpeed *. (itof iGlobalUnit)) *. nbsec -> speed in ( SO3ObjectTranslate bnavstr.AV_shell multiplyVectorF vec [speed speed speed] SO3_LOCAL_TS; SO3ObjectRotateYaw bnavstr.AV_shell yaw *. nbsec SO3_LOCAL_TS; SO3ObjectRotatePitch bnavstr.AV_camera pitch *. nbsec SO3_LOCAL_TS; let V3DgetCursorTrans viewstr -> curstrans in if curstrans == nil then nil else let curstrans -> [dx dy] in let (1.0 /. ((itof viewstr.V3D_iWinW) /. 2.0) *. (itof dx)) -> dxnorm in let (1.0 /. ((itof viewstr.V3D_iWinH) /. 2.0) *. -.(itof dy)) -> dynorm in let if dxnorm >. 1.0 then 1.0 else if dxnorm <. -.1.0 then -.1.0 else dxnorm -> dxone in let if dynorm >. 1.0 then 1.0 else if dynorm <. -.1.0 then -.1.0 else dynorm -> dyone in let speed *. dxnorm -> fvdx in let -.speed *. dynorm -> fvdy in ( if !((V3DisMoveClicked viewstr) & V3DCLICK_SHIFT) then nil else SO3ObjectRotatePitch bnavstr.AV_camera (SO3MathsDegreeToRadian dynorm *. nbsec *. 45.0) SO3_LOCAL_TS; if ((V3DisMoveClicked viewstr) & V3DCLICK_CTRL) then nil else SO3ObjectRotateYaw bnavstr.AV_shell (-.(SO3MathsDegreeToRadian dxnorm *. nbsec *. 45.0)) SO3_LOCAL_TS; let if ((V3DisMoveClicked viewstr) & V3DCLICK_SHIFT) then [0.0 0.0 0.0] else if ((V3DisMoveClicked viewstr) & V3DCLICK_CTRL) then [fvdx fvdy 0.0] else [0.0 0.0 (-.fvdy)] -> vec in SO3ObjectTranslate bnavstr.AV_shell vec SO3_LOCAL_TS; set bnavstr.AV_pos = [(SO3ObjectGetPosition bnavstr.AV_shell) (SO3ObjectGetOrientation bnavstr.AV_shell) (SO3ObjectGetOrientation bnavstr.AV_camera)]; ); ); 0;; fun startAvNavMode(viewstr, pos, ang, cang, speed, cameraheight)= if avNavStr != nil then nil else let V3DgetDefaultSession viewstr -> sessionstr in let V3DgetDefaultCamera sessionstr -> cam in let V3DaddShell sessionstr "AVNav_dummy" nil nil pos ang -> shell in let SO3ObjectGetPosition cam -> opos in let SO3ObjectGetOrientation cam -> oang in let mkAvNavigation [shell cam [opos oang] [pos ang cang] [[0.0 0.0 0.0] [0.0 0.0 0.0]] speed cameraheight nil] -> bnavstr in ( V3DenableNavigate sessionstr 0; SO3ObjectLink cam shell; SO3ObjectSetPosition cam [0.0 (cameraheight *. (itof iGlobalUnit)) 0.0]; SO3ObjectSetOrientation cam cang; set avNavStr = bnavstr; ); 0;; fun stopAvNavMode(viewstr)= if avNavStr == nil then nil else let V3DgetDefaultSession viewstr -> sessionstr in let avNavStr.AV_oldCameraPos -> [opos oang] in ( V3DenableNavigate sessionstr 1; SO3ObjectLink avNavStr.AV_camera sessionstr.V3D_shellNavigate; SO3ObjectSetOrientation avNavStr.AV_camera oang; SO3ObjectSetPosition avNavStr.AV_camera opos; SO3ObjectDestroy avNavStr.AV_shell; set avNavStr = nil; ); 0;;