/* ----------------------------------------------------------------------------- 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 ObjPRadarStr = [ PRADAR_object1 : SO3_OBJECT, PRADAR_object2 : SO3_OBJECT, PRADAR_iMode1 : I, PRADAR_iMode2 : I, PRADAR_fDist : F, PRADAR_fxAng : F, PRADAR_fyAng : F, PRADAR_fPrecision : F, PRADAR_iDebounce : I, PRADAR_iInterval : I, PRADAR_bState : I ]mkObjPRadarStr;; fun deleteOb(inst)= setPluginInstanceCbScenePreRender2 inst nil; 0;; // ignore avatar bodies and disabled bodies fun getValidRay(lray, obj1)= let nil -> body in let 0.0 -> dist in let [0.0 1.0 0.0] -> normal in ( while ((lray != nil) && (body == nil)) do ( let hd lray -> [tbody tdist tnormal] in if (((obj1 != nil) && (SO3BodyGetSceneNode tbody) == obj1) || (SO3BodyGetIgnoreCollision tbody) || (SO3BodyGetFluid tbody)) then nil else ( set body = tbody; set dist = tdist; set normal = tnormal; ); set lray = tl lray; ); [body dist normal] );; fun cbGetDistance(inst, sessionstr, etime, obstr)= let if (obstr.PRADAR_iMode1 != 0) then ( let V3DgetDefaultCamera sessionstr -> curcamera in V3DgetCameraByType sessionstr curcamera obstr.PRADAR_iMode1; ) else obstr.PRADAR_object1 -> object1 in let if (obstr.PRADAR_iMode2 != 0) then ( let V3DgetDefaultCamera sessionstr -> curcamera in V3DgetCameraByType sessionstr curcamera obstr.PRADAR_iMode2; ) else obstr.PRADAR_object2 -> object2 in if (object1 == nil) then nil else let SO3ObjectGetGlobalPosition object1 -> pos in let SO3ObjectGetGlobalOrientation object1 -> quat in let 0 -> hit in ( let obstr.PRADAR_fDist -> dist in let obstr.PRADAR_fxAng -> ang in let 10.0 -> angstep in let (ang /. angstep) *. obstr.PRADAR_fPrecision -> nbpoints in let maxf ((obstr.PRADAR_fxAng /. angstep) *. obstr.PRADAR_fPrecision) ((obstr.PRADAR_fyAng /. angstep) *. obstr.PRADAR_fPrecision) -> nbpoints in let dist *. (tan (SO3MathsDegreeToRadian obstr.PRADAR_fxAng /. 2.0)) -> rx in let dist *. (tan (SO3MathsDegreeToRadian obstr.PRADAR_fyAng /. 2.0)) -> ry in let ftoi nbpoints -> nb in let 1 -> n in while (n <= nb && !hit) do ( let rx *. (itof n) /. (itof nb) -> nrx in let ry *. (itof n) /. (itof nb) -> nry in let (2.0 *. PIf) /. (nbpoints *. (itof n)) -> nstep in let nstep -> pv in while (pv <=. (2.0 *. PIf) && !hit) do ( let [(nrx *. cos(pv)) (nry *. sin(pv)) dist] -> pt in let addVectorF (SO3MathsQuatGetDirection quat pt) pos -> pt in let getValidRay SO3PhysicsRayCastExt (V3DgetSession sessionstr) pos (subVectorF pt pos) (getVectorDistanceF pos pt) object1 -> result in let result -> [body cdist normal] in if ((SO3BodyGetSceneNode body) == object2) then ( if (obstr.PRADAR_bState) then nil else ( set obstr.PRADAR_bState = 1; SendPluginEvent inst "In" ftoa cdist nil; cbPlugGeneric 16 SO3ObjectGetName object2 ftoa cdist; ); set obstr.PRADAR_iInterval = _tickcount; set hit = 1; ) else nil; set pv = pv +. nstep; ); set n = n + 1; ); if (!hit && obstr.PRADAR_bState && ((obstr.PRADAR_iInterval == nil) || (_tickcount - obstr.PRADAR_iInterval >= obstr.PRADAR_iDebounce))) then ( set obstr.PRADAR_bState = 0; SendPluginEvent inst "Out" nil nil; cbPlugGeneric 17 SO3ObjectGetName object2 nil; ) else nil; ); 0;; fun cbEnable(inst, from, action, param, rep, obstr)= setPluginInstanceCbScenePreRender2 inst mkfun4 @cbGetDistance obstr; 0;; fun cbDisable(inst, from, action, param, rep, obstr)= setPluginInstanceCbScenePreRender2 inst nil; 0;; fun cbSetFirstObject(inst, from, action, param, reply, obstr)= let V3DgetObjectByName c3dXsession param -> obj in let V3DgetObjectTypeByName param -> iobjmode in if (obj == nil) then nil else ( set obstr.PRADAR_object1 = obj; set obstr.PRADAR_iMode1 = iobjmode; ); 0;; fun cbSetSecondObject(inst, from, action, param, reply, obstr)= let V3DgetObjectByName c3dXsession param -> obj in let V3DgetObjectTypeByName param -> iobjmode in if (obj == nil) then nil else ( set obstr.PRADAR_object2 = obj; set obstr.PRADAR_iMode2 = iobjmode; ); 0;; fun newOb(inst)= let (getPluginInstanceParam inst "object") -> objname1 in let (getPluginInstanceParam inst "object2") -> objname2 in let atof (getPluginInstanceParam inst "distance") -> dist in let if dist == nil then 1.0 else dist -> dist in let atof (getPluginInstanceParam inst "xang") -> xang in let if xang == nil then 45.0 else xang -> xang in let atof (getPluginInstanceParam inst "yang") -> yang in let if yang == nil then 45.0 else yang -> yang in let atof (getPluginInstanceParam inst "precision") -> precision in let if precision == nil then 0.5 else precision -> precision in let atoi (getPluginInstanceParam inst "debounce") -> debounce in let if debounce == nil then 0 else debounce -> debounce in let atoi (getPluginInstanceParam inst "init") -> init in let if init == nil then 1 else init -> init in let V3DgetObjectByName c3dXsession objname1 -> object1 in let V3DgetObjectTypeByName objname1 -> iobj1mode in let V3DgetObjectByName c3dXsession objname2 -> object2 in let V3DgetObjectTypeByName objname2 -> iobj2mode in let mkObjPRadarStr [object1 object2 iobj1mode iobj2mode dist xang yang precision debounce nil 0] -> obstr in ( if !init then nil else setPluginInstanceCbScenePreRender2 inst mkfun4 @cbGetDistance obstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable obstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable obstr; PluginRegisterAction inst "Set first object" mkfun6 @cbSetFirstObject obstr; PluginRegisterAction inst "Set second object" mkfun6 @cbSetSecondObject obstr; setPluginInstanceCbDel inst @deleteOb; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;