/* ----------------------------------------------------------------------------- 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 ----------------------------------------------------------------------------- */ // time value to prevent too quick lost / found var iBounceTime = 300;; struct ArMarkerStr = [ ARM_inst : PInstance, ARM_father : SO3_OBJECT, ARM_refObj : SO3_OBJECT, ARM_marker : ObjArMarker, ARM_warpedBuffer : ObjBitmap, ARM_material : SO3_MATERIAL, ARM_Tex : SO3_TEXTURE, ARM_OldTex : SO3_TEXTURE, ARM_iFatherMode : I, ARM_iRefSpace : I, ARM_initpos : [[F F F] [F F F F]], ARM_lastpos : [[F F F] [F F F]], ARM_fsize : F, ARM_iId : I, ARM_bVisible : I, ARM_bState : I, ARM_bTrackState : I, ARM_bFeatured : I, ARM_bInvertAxis : I, ARM_iBounceTimeCount : I, ARM_bETranslation : I, ARM_bEMoved : I, ARM_bERotated : I, ARM_bEData : I, ARM_bEPos : I, ARM_bEPixelPos : I, ARM_bEOrient : I, ARM_bEYaw : I, ARM_bEPitch : I, ARM_bERoll : I, ARM_bBlitTexture : I, ARM_iMatIndex : I ] mkArMarkerStr;; fun deleteOb(inst, objpstr)= /*if (objpstr.ARM_timerBounce == nil) then nil else ( _deltimer objpstr.ARM_timerBounce; set objpstr.ARM_timerBounce = nil; );*/ setPluginInstanceCbScenePreRenderPhysic inst nil; setPluginInstanceCbCameraChange inst nil; _DSarMarker objpstr.ARM_marker; set objpstr.ARM_marker = nil; let objpstr.ARM_initpos -> [pos quat] in ( SO3ObjectSetPosition objpstr.ARM_father pos; SO3ObjectSetOrientation objpstr.ARM_father quat; ); if (objpstr.ARM_Tex == nil) then nil else ( SO3MaterialSetTexture objpstr.ARM_material objpstr.ARM_OldTex 0 0 0; SO3TextureDestroy objpstr.ARM_Tex; _DSbitmap objpstr.ARM_warpedBuffer; ); 0;; /* fun cbBounceLost(trm, objpstr)= _deltimer objpstr.ARM_timerBounce; set objpstr.ARM_timerBounce = nil; SendPluginEvent objpstr.ARM_inst "Lost" itoa objpstr.ARM_iId nil; 0;; */ fun usePhysic(objpstr)= let SO3SceneNodeGetBody objpstr.ARM_father -> body in let SO3BodyGetMassMatrix body -> [mass _] in if ((objpstr.ARM_iFatherMode != 0) || (body == nil) || (SO3BodyGetFluid body) || !(V3DphysGetState c3dXsession) || (mass <=. 0.0)) then 0 else 1;; fun cbControlPreRender(inst, sessionstr, etime, objpstr)= let if etime < 1000 then 1000 else etime -> etime in let _ISarMarkerVisible objpstr.ARM_marker -> visible in let if (usePhysic objpstr) then SO3SceneNodeGetBody objpstr.ARM_father else nil -> body in ( if ((!objpstr.ARM_bState) || !visible || !objpstr.ARM_bTrackState) then nil else ( let _GETarMarkerPosition objpstr.ARM_marker -> pos in let _GETarMarkerPixelPosition objpstr.ARM_marker -> pixelpos in let _GETarMarkerOrientation objpstr.ARM_marker -> quat in //rotate Y 90 for legacy compatibility //let SO3MathsQuatAdd quat [0.0 (-.sqrt(0.5)) 0.0 sqrt(0.5)] -> quat in ( //force world pos if this is a camera if ((objpstr.ARM_iRefSpace != 2) || ((!objpstr.ARM_iFatherMode) && ((SO3ObjectGetType objpstr.ARM_father) != SO3_TYPE_CAMERA) && ((SO3ObjectGetType (hd SO3ObjectGetChildren objpstr.ARM_father)) != SO3_TYPE_CAMERA))) then nil else set objpstr.ARM_iRefSpace = 1; let V3DgetSessionView sessionstr -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in let pos -> [x y z] in let pixelpos -> [pixx pixy pixz] in let V3DgetViewportSize viewstr viewportstr -> [_ _ w h] in let c3dxCameraSize -> [cw ch] in let ftoi ((itof pixx) *. (itof w) /. (itof cw)) -> pixx in let if c3dxCameraFlip then w - pixx else pixx -> pixx in let ftoi ((itof pixy) *. (itof h) /. (itof ch)) -> pixy in let if (objpstr.ARM_iRefSpace == 1) then SO3ObjectGetParent objpstr.ARM_father else if (objpstr.ARM_iRefSpace == 2) then SO3ViewportGetCamera viewportstr.V3D_viewport else if (objpstr.ARM_iRefSpace == 3) then objpstr.ARM_refObj else nil -> refobj in let if (refobj == nil) then [0.0 0.0 0.0] else SO3ObjectGetGlobalPosition refobj -> cpos in let if (refobj == nil) then [0.0 0.0 0.0 1.0] else SO3ObjectGetGlobalOrientation refobj -> cquat in let SO3MathsQuatGetDirection cquat [x (-.y) z] -> dpos in let if objpstr.ARM_bInvertAxis then SO3MathsQuatAdd quat SO3MathsQuatAdd [0.0 0.5 0.0 0.5] [(-.0.5) 0.0 0.0 0.5] else quat -> quat in let addVectorF dpos cpos -> mpos in let SO3MathsQuatAdd cquat quat -> mquat in ( if (!objpstr.ARM_bVisible && (body != nil)) then //teleport object ( SO3BodySetVelocity body [0.0 0.0 0.0]; SO3BodySetOmega body [0.0 0.0 0.0]; SO3ObjectSetGlobalPosition objpstr.ARM_father mpos; SO3ObjectSetGlobalOrientation objpstr.ARM_father mquat; ) else if (body == nil) then ( SO3ObjectSetGlobalPosition objpstr.ARM_father mpos; SO3ObjectSetGlobalOrientation objpstr.ARM_father mquat; ) else ( SO3BodyMoveTo body mpos 0.5; SO3BodyRotateTo body mquat 0.5; ); let SO3MathsQuatToEulerDegreePYR quat -> [lpitch lyaw lroll] in ( if (objpstr.ARM_lastpos == nil) then nil else let objpstr.ARM_lastpos -> [opos orot] in let subVectorF pos opos -> [nx ny nz] in let subVectorF [lpitch lyaw lroll] orot -> [npitch nyaw nroll] in let if npitch >. 180.0 then npitch -. 360.0 else if npitch <. (-.180.0) then npitch +. 360.0 else npitch -> npitch in let if nyaw >. 180.0 then nyaw -. 360.0 else if nyaw <. (-.180.0) then nyaw +. 360.0 else nyaw -> nyaw in let if nroll >. 180.0 then nroll -. 360.0 else if nroll <. (-.180.0) then nroll +. 360.0 else nroll -> nroll in ( if (!objpstr.ARM_bETranslation) then nil else SendPluginEvent inst "Translation" (strcatnSep (ftoa nx)::(ftoa ny)::(ftoa nz)::nil " ") nil; if (!objpstr.ARM_bEMoved) then nil else if (((absf nx) <=. objpstr.ARM_fsize /. 20.0) && ((absf ny) <=. objpstr.ARM_fsize /. 20.0) && ((absf nz) <=. objpstr.ARM_fsize /. 20.0)) then nil else ( SendPluginEvent inst "Moved" (strcatnSep (ftoa nx)::(ftoa ny)::(ftoa nz)::nil " ") nil; ); if (!objpstr.ARM_bERotated) then nil else if ((absf npitch) <=. 0.01 && (absf nyaw) <=. 0.01 && (absf nroll) <=. 0.01) then nil else ( SendPluginEvent inst "Rotated" (strcatnSep (ftoa npitch)::(ftoa nyaw)::(ftoa nroll)::nil " ") nil; ); ); set objpstr.ARM_lastpos = [pos [lpitch lyaw lroll]]; ); let (addVectorF dpos cpos) -> [px py pz] in let SO3MathsQuatToEulerPYR SO3MathsQuatAdd cquat quat -> [ax ay az] in let SO3MathsQuatGetDegreeYaw quat 0 -> yaw in let SO3MathsQuatGetDegreePitch quat 0 -> pitch in let SO3MathsQuatGetDegreeRoll quat 0 -> roll in ( if (!objpstr.ARM_bEData) then nil else SendPluginEvent inst "Data changed" strcatn (strcatnSep (ftoa px)::(ftoa py)::(ftoa pz)::nil " ")::"\n"::(strcatnSep (ftoa (SO3MathsRadianToDegree ay))::(ftoa (SO3MathsRadianToDegree ax))::(ftoa (SO3MathsRadianToDegree az))::nil " ")::nil nil; if (!objpstr.ARM_bEPos) then nil else SendPluginEvent inst "Position" strcatnSep (ftoa px)::(ftoa py)::(ftoa pz)::nil " " nil; if (!objpstr.ARM_bEPixelPos) then nil else SendPluginEvent inst "Pixel position" strcatnSep (itoa pixx)::(itoa pixy)::(itoa pixz)::nil " " nil; if (!objpstr.ARM_bEOrient) then nil else SendPluginEvent inst "Orientation" strcatnSep (ftoa (SO3MathsRadianToDegree ax))::(ftoa (SO3MathsRadianToDegree ay))::(ftoa (SO3MathsRadianToDegree az))::nil " " nil; if (!objpstr.ARM_bEYaw) then nil else SendPluginEvent inst "Yaw" ftoa yaw nil; if (!objpstr.ARM_bEPitch) then nil else SendPluginEvent inst "Pitch" ftoa pitch nil; if (!objpstr.ARM_bERoll) then nil else SendPluginEvent inst "Roll" ftoa roll nil; ); ); ); ); if (!objpstr.ARM_bState) then nil else ( if (visible == 1) then ( if (objpstr.ARM_bVisible != 0) then nil else ( set objpstr.ARM_bVisible = 1; if (objpstr.ARM_iBounceTimeCount != nil) then ( set objpstr.ARM_iBounceTimeCount = nil; 0; ) else ( if (objpstr.ARM_Tex == nil) then nil else ( //addLogMessage "set marker texture"; SO3MaterialSetTexture objpstr.ARM_material objpstr.ARM_Tex 0 0 0; _GETarMarkerWarpedBitmap objpstr.ARM_marker objpstr.ARM_warpedBuffer; SO3TextureBlit objpstr.ARM_Tex objpstr.ARM_warpedBuffer; ); SendPluginEvent inst "Found" itoa objpstr.ARM_iId nil; 0; ); ); ) else ( if (objpstr.ARM_bVisible == 0) then nil else ( set objpstr.ARM_iBounceTimeCount = if (objpstr.ARM_iBounceTimeCount != nil) then objpstr.ARM_iBounceTimeCount + (etime / 1000) else 0; if (body == nil) then nil else ( SO3BodySetVelocity body [0.0 0.0 0.0]; SO3BodySetOmega body [0.0 0.0 0.0]; ); if (objpstr.ARM_iBounceTimeCount < iBounceTime) then nil else ( set objpstr.ARM_iBounceTimeCount = nil; set objpstr.ARM_bVisible = 0; set objpstr.ARM_lastpos = nil; /*if (objpstr.ARM_Tex == nil) then nil else ( //addLogMessage "restore marker texture"; SO3MaterialSetTexture objpstr.ARM_material objpstr.ARM_OldTex 0 0 0; );*/ SendPluginEvent inst "Lost" itoa objpstr.ARM_iId nil; ); 0; ); ); //if (!objpstr.ARM_bVisible || (objpstr.ARM_Tex == nil)) then nil else //( // _GETarMarkerWarpedBitmap objpstr.ARM_marker objpstr.ARM_warpedBuffer; // SO3TextureBlit objpstr.ARM_Tex objpstr.ARM_warpedBuffer; //); ); ); 0;; fun cbChangeCamera(inst, viewstr, sessionstr, camera, objpstr)= let V3DgetCameraByType sessionstr camera objpstr.ARM_iFatherMode -> nfather in let SO3ObjectGetPosition nfather -> cpos in let SO3ObjectGetOrientation nfather -> cquat in ( let objpstr.ARM_initpos -> [pos quat] in ( SO3ObjectSetPosition objpstr.ARM_father pos; SO3ObjectSetOrientation objpstr.ARM_father quat; ); set objpstr.ARM_father = nfather; set objpstr.ARM_initpos = [cpos cquat]; ); 0;; fun cbEnableMarker(inst, from, action, param, reply, objpstr)= set objpstr.ARM_bState = 1; 0;; fun cbDisableMarker(inst, from, action, param, reply, objpstr)= set objpstr.ARM_bState = 0; set objpstr.ARM_bVisible = 0; set objpstr.ARM_iBounceTimeCount = nil; 0;; fun cbEnableMarkerTracking(inst, from, action, param, reply, objpstr)= set objpstr.ARM_bTrackState = 1; 0;; fun cbDisableMarkerTracking(inst, from, action, param, reply, objpstr)= set objpstr.ARM_bTrackState = 0; 0;; fun cbSetMarkerSize(inst, from, action, param, reply, objpstr)= if ((atof param) == nil) then nil else let atof param -> fparam in ( _SETarMarkerSize objpstr.ARM_marker fparam; set objpstr.ARM_fsize = fparam; ); 0;; fun cbRestoreTexture(inst, from, action, param, reply, objpstr)= if (objpstr.ARM_Tex == nil) then nil else SO3MaterialSetTexture objpstr.ARM_material objpstr.ARM_OldTex 0 0 0; 0;; fun cbRegisterFrame(inst, from, action, param, reply, objpstr)= let c3dxCameraSize -> [cx cy] in let strextr param -> lp in let (nth_list (hd lp) 0) -> sx in let if sx == nil then 0 else atoi sx -> x in let (nth_list (hd lp) 1) -> sy in let if sy == nil then 0 else atoi sy -> y in let (nth_list (hd lp) 2) -> sw in let if sw == nil then cx else atoi sw -> w in let (nth_list (hd lp) 3) -> sh in let if sh == nil then cy else atoi sh -> h in _SETarMarkerFromPictureZone objpstr.ARM_marker x y w h; 0;; fun cbGetMarkerData(inst, from, action, param, reply, objpstr)= if (objpstr.ARM_warpedBuffer == nil) then nil else ( let if param == nil then [256 256] else let strextr param -> lp in let if (atoi (nth_list (hd lp) 0)) == nil then 256 else (atoi (nth_list (hd lp) 0)) -> ww in let if (atoi (nth_list (hd lp) 1)) == nil then 256 else (atoi (nth_list (hd lp) 1)) -> hh in [ww hh] -> [bw bh] in let G2DstrechBitmap _channel objpstr.ARM_warpedBuffer bw bh 0 -> bmp in let _BTCompBitmap bmp 80 -> sbmp in ( //crash ?! //_DSbitmap bmp; let strcatn "Z"::"_"::(itoa bw)::"_"::(itoa bh)::"_"::(zip sbmp)::nil -> data in SendPluginEvent inst "Marker bitmap data" data nil; ); ); 0;; fun getMatFromObj(node, index)= if node == nil then nil else let nil -> tmat in let SO3EntityGetMaterialByIndex node index -> mat in ( if (SO3MaterialGetTexture mat 0 0 0) != nil then ( //addLogMessage strcat "Marker mat found : " SO3MaterialGetName mat; mat; ) else ( let SO3ObjectGetChildren node -> lchild in ( while (lchild != nil) && (tmat == nil) do ( set tmat = getMatFromObj hd lchild index; set lchild = tl lchild; ); ); tmat; ); );; fun newOb(inst)= let (getPluginInstanceParam inst "object") -> objname in let (getPluginInstanceParam inst "path") -> path in let (getPluginInstanceParam inst "pathfset") -> pathfset in let (getPluginInstanceParam inst "pathfset3") -> pathfset3 in let (getPluginInstanceParam inst "pathfiset") -> pathfiset in let atof (getPluginInstanceParam inst "msize") -> msize in let if (msize == nil) then 0.08 else msize -> msize in let atoi(getPluginInstanceParam inst "imode") -> imode in let if imode == nil then 2 else imode -> imode in let (getPluginInstanceParam inst "objRef") -> objref in let V3DgetObjectByName c3dXsession objref -> refobj in let atoi (getPluginInstanceParam inst "maxfeatures") -> maxfeatures in let if maxfeatures == nil then 400 else maxfeatures -> maxfeatures in let atoi (getPluginInstanceParam inst "id") -> id in let atoi (getPluginInstanceParam inst "enable") -> enable in let if enable == nil then 1 else enable -> enable in let atoi (getPluginInstanceParam inst "track") -> track in let if track == nil then 1 else track -> track in let atoi (getPluginInstanceParam inst "invertaxis") -> invertaxis in let if invertaxis == nil then 0 else invertaxis -> invertaxis in let atoi (getPluginInstanceParam inst "blittexture") -> blittexture in let if blittexture == nil then 0 else blittexture -> blittexture in let atoi (getPluginInstanceParam inst "matindex") -> matindex in let if matindex == nil then 0 else matindex -> matindex in let V3DgetObjectByName c3dXsession objname -> father in let V3DgetObjectTypeByName objname -> iobjmode in let SO3ObjectGetPosition father -> cpos in let SO3ObjectGetOrientation father -> cquat in let if (path != nil) && (strlen path) then ( let if (((_checkpack pathfset) != nil) && ((_checkpack pathfset3) != nil) && ((_checkpack pathfiset) != nil)) then pathfset else path -> npath in _CRarMarkerFromFileEx _channel (_checkpack npath) msize maxfeatures; ) else _CRarMarker _channel id msize -> marker in let if (path != nil) && (strlen path) then 1 else 0 -> featured in let (IsInEditor inst) || IsEventLinked inst "Translation" -> btranslation in let (IsInEditor inst) || IsEventLinked inst "Moved" -> bemoved in let (IsInEditor inst) || IsEventLinked inst "Rotated" -> berot in let (IsInEditor inst) || IsEventLinked inst "Data changed" -> bedata in let (IsInEditor inst) || IsEventLinked inst "Position" -> bepos in let (IsInEditor inst) || IsEventLinked inst "Pixel position" -> bepixelpos in let (IsInEditor inst) || IsEventLinked inst "Orientation" -> beorient in let (IsInEditor inst) || IsEventLinked inst "Yaw" -> beyaw in let (IsInEditor inst) || IsEventLinked inst "Pitch" -> bepitch in let (IsInEditor inst) || IsEventLinked inst "Roll" -> beroll in let getMatFromObj father matindex -> mat in let SO3MaterialGetTexture mat 0 0 0 -> otex in let if (!blittexture || !featured || otex == nil) then nil else SO3TextureCreate (V3DgetSession c3dXsession) strcat (getPluginInstanceName inst) ".marker" nil (getPluginInstanceGroupName inst) 512 512 -> ntex in let if (!blittexture || !featured || otex == nil) then nil else _FILLbitmap _CRbitmap _channel 512 512 0xffffff -> buffer in let mkArMarkerStr [inst father refobj marker buffer mat ntex otex iobjmode imode [cpos cquat] nil msize id 0 enable track featured invertaxis nil btranslation bemoved berot bedata bepos bepixelpos beorient beyaw bepitch beroll blittexture matindex] -> objpstr in ( if !iobjmode then nil else setPluginInstanceCbCameraChange inst mkfun5 @cbChangeCamera objpstr; PluginRegisterAction inst "Set scale" mkfun6 @cbSetMarkerSize objpstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnableMarker objpstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisableMarker objpstr; PluginRegisterAction inst "Enable tracking" mkfun6 @cbEnableMarkerTracking objpstr; PluginRegisterAction inst "Disable tracking" mkfun6 @cbDisableMarkerTracking objpstr; PluginRegisterAction inst "Register current frame" mkfun6 @cbRegisterFrame objpstr; PluginRegisterAction inst "Get last marker bitmap"mkfun6 @cbGetMarkerData objpstr; PluginRegisterAction inst "Restore object texture"mkfun6 @cbRestoreTexture objpstr; setPluginInstanceCbScenePreRenderPhysic inst mkfun4 @cbControlPreRender objpstr; setPluginInstanceCbDel inst mkfun2 @deleteOb objpstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditorInstanceCb @dynamicinit @dynamicdelete @dynamicstart @dynamicstop; setPluginEditor @dynamicedit; 0;;