/* 3d Window by J.DUMAY May 2000*/ /******************************************* Manager de Vues 3d **************************************/ struct View3dManager=[ MV3dChannel:Chn, MV3dWin:ObjWin, MV3dSize:[I I], MV3dFlags:I, MV3dTimer:Timer, MV3dListV3d:[View3d r1], MV3dPaint:fun[View3dManager] I, MV3dPreRender:fun[View3dManager] I, MV3dEnd:fun [] I ]mkView3dManager;; var MV3D_RESIZE =1;; var MV3D_INTERF =2;; var MV3D_CONT =4;; var MV3D_CHILD =8;; /******************************************* Vue 3d **************************************************/ struct View3d=[ V3dmanager :View3dManager, V3dchannel :Chn, V3dwin :ObjWin, V3drenderType :I, V3dsession :S3d, V3dcamera :H3d, V3dcursorDef :ObjCursor, V3dbuf :ObjSurface, V3dsize :[I I], V3dk :[I I], V3dfond :I, V3dvector :[I I I], V3dangular :[I I I], V3dClickedCoord :[I I], V3doldpos :[I I], V3dcursor :[I I], V3dlast :H3d, V3dlastm :HMat3d, /* les callbacks utilisateurs */ V3dcbResize :fun [View3d I I] I, /* resize */ V3dcbFocus :fun [View3d] I, /* focus */ V3dcbKeyUp :fun [I] I, /* key up */ V3dcbKeyDown :fun [I I] I, /* key down */ V3dcbCursorMoveCoords :fun [I I] I, /* cursor move */ V3dcbClick :fun [I I I H3d HMat3d] I, /* click */ V3dcbDClick :fun [I I I H3d HMat3d] I, /* double click */ V3dcbUnClick :fun [I I I H3d HMat3d] I, /* unclick */ V3dcbTimer :fun [] I, /* timer */ V3dcbMoveObject :fun [[I I I] [I I I]] I, /* deplacement object */ V3dcbCursorMoveObject :fun [View3d H3d HMat3d I I] I, /* cursor move sur un objet */ V3dcbClickObject :fun [H3d HMat3d I] I, /* click sur un object */ V3dcbDClickObject :fun [H3d HMat3d I] I, /* doucle click sur objet */ V3dcbPostRender :fun [ObjSurface [I I]] I, /* postrender */ V3dcbPreRender :fun [] I, /* postrender */ V3dcbEnd :fun [View3d] I ]mkView3d;; var WIRE =1;; var TEXTURED =2;; var D3DErrorDialog = 0;; /* Error Dialog not created yet */ fun D3DErrorDialogOK(b,u)= set D3DErrorDialog = 0; 0;; /******************************************* Vue 3d **************************************************/ fun destroyView3d(win,dev)= exec dev.V3dcbEnd with [dev];; fun focusView3d(win,dev)= exec dev.V3dcbFocus with [dev];; fun paintView3d(win,dev)= let dev.V3dsize ->[w h] in _BLTsurface dev.V3dwin 0 0 dev.V3dbuf 0 0 w h;; fun cbresizeView3d(win,dev,w,h)= set dev.V3dsize=[w h]; let dev.V3dsize->[w h] in { _DSsurface dev.V3dbuf; set dev.V3dbuf=_CRsurface dev.V3dchannel w h; if (dev.V3dbuf == nil && !D3DErrorDialog && w>5 && h>5) then let _GETscreenSize -> [wscr hscr] in let _CRwindow _channel dev.V3dwin (wscr-250)/2 (hscr-100)/2 250 100 WN_DIALOG loc "DIRECT3DERROR" -> popup in let _CRtext _channel popup 10 10 230 40 ET_ALIGN_CENTER loc "DIRECT3D_NOMEMORY"-> text in let _CRbutton _channel popup 85 60 80 20 ET_ALIGN_CENTER loc "OK"-> button in { set D3DErrorDialog = 1; _CBbutton button @D3DErrorDialogOK nil } else nil; _FILLsurface dev.V3dbuf 0; if dev.V3dcamera==nil || dev.V3dsession==nil then nil else let M3getCamera dev.V3dsession dev.V3dcamera -> [[d _] [x _] z] in M3setCamera dev.V3dsession dev.V3dcamera [[d*(w>>1)/x d*(w>>1)/x] [w>>1 h>>1] z]; 0 };; fun myM3getInfo(dev,x,y)= let dev.V3dsize->[w h] in if dev.V3drenderType&WIRE then MX3wireOrtho dev.V3dsession dev.V3dbuf dev.V3dcamera x-(w>>1) (h>>1)-y dev.V3dfond else let MX3renderInfo dev.V3dsession dev.V3dcamera x-(w>>1) (h>>1)-y ->[o m _ _ _] in [o m];; fun clickView3d(win,dev,x,y,btn)= _SETfocus dev.V3dwin; let myM3getInfo dev x y->[o m] in if (exec dev.V3dcbClick with [x y btn o m]) then set dev.V3dClickedCoord = [x y] else nil; if btn == 1 then set dev.V3doldpos =[x y] else nil ;; fun dclickView3d(win,dev,x,y,btn)= let myM3getInfo dev x y->[o m] in exec dev.V3dcbDClick with [x y btn o m] ;; fun unclickView3d(win,dev,x,y,btn)= set dev.V3dvector=[0 0 0]; set dev.V3dangular=[0 0 0]; let myM3getInfo dev x y->[o m] in ( exec dev.V3dcbUnClick with [x y btn o m]; set dev.V3dClickedCoord=nil; set dev.V3doldpos=nil; ) ;; var lastkbdstate=0;; typeof keycodes=tab I;; fun setkeycode(code,val)= if keycodes==nil then set keycodes=mktab 4 0 else nil; let val-0xff51 ->i in if i<0 || i >=4 then nil else set keycodes.i=code;; fun keydownView3d (win,dev,code,val)= set lastkbdstate=_keybdstate; setkeycode code val; exec dev.V3dcbKeyDown with [code val]; let dev.V3dk ->[lv la] in let [lv*128 la*128] -> [kv ka] in (let dev.V3dvector-> v in if lastkbdstate&2 then if val==0xff51 then mutate v<-[(-kv) _ _] else if val==0xff53 then mutate v<-[kv _ _] else if val==0xff52 then mutate v<-[_ kv _] else if val==0xff54 then mutate v<-[_ (-kv) _] else nil else if lastkbdstate&1 then nil else if val==0xff52 then mutate v<-[_ _ kv] else if val==0xff54 then mutate v<-[_ _ (-kv)] else nil; let dev.V3dangular-> a in if lastkbdstate&2 then nil else if lastkbdstate&1 then if val==0xff52 then mutate a<-[_ ka _] else if val==0xff54 then mutate a<-[_ (-ka) _] else nil else if val==0xff51 then mutate a<-[ka _ 0] else if val==0xff53 then mutate a<-[-ka _ 0] else nil; );; fun keyupView3d (win,dev,code)= exec dev.V3dcbKeyUp with [code]; let dev.V3dvector ->v in let dev.V3dangular ->a in if lastkbdstate&2 then if (code==keycodes.0)||(code==keycodes.2) then mutate v<-[0 _ _] else if (code==keycodes.1)||(code==keycodes.3) then mutate v<-[_ 0 _] else nil else if lastkbdstate&1 then if (code==keycodes.1)||(code==keycodes.3) then mutate a<-[_ 0 _] else nil else if (code==keycodes.0)||(code==keycodes.2) then mutate a<-[0 _ _] else if (code==keycodes.1)||(code==keycodes.3) then mutate v<-[_ _ 0] else nil;; fun cursorView3d(win,dev,x,y,btn)= /* gestion du mouvement de la souris pour les modifications sur les objets */ if dev.V3doldpos!=nil then ( let dev.V3dk ->[kv ka] in let dev.V3doldpos ->[oldx oldy] in exec dev.V3dcbCursorMoveCoords with [(x-oldx)*kv (y-oldy)*kv]; set dev.V3doldpos=[x y] ) else nil; /* gestion du mouvement de la souris pour le curseur souris */ let dev.V3dsize->[w h] in set dev.V3dcursor=[x-(w>>1) (h>>1)-y]; /* gestion du mouvement de la souris pour déplacer la camera */ if dev.V3dClickedCoord==nil then nil else let dev.V3dk ->[kv ka] in let dev.V3dClickedCoord ->[xr yr] in ( set x=x-xr; set y=yr-y; set dev.V3dvector=(if _keybdstate&2 then [x*kv y*kv 0] else if _keybdstate&1 then [0 0 0] else [0 0 y*kv]); set dev.V3dangular=(if _keybdstate&2 then [0 0 0] else if _keybdstate&1 then [0 y*ka 0] else [(-x*ka) 0 0]); ) ;; fun iniView3d(m3dv,typerender,pos,wh,fond)= let pos->[x y] in let wh -> [w h] in let _CRwindow m3dv.MV3dChannel m3dv.MV3dWin x y w h WN_CHILDINSIDE|WN_NOCAPTION|WN_NOBORDER "" -> win in let _CRsurface m3dv.MV3dChannel w h ->buf in { if buf == nil && !D3DErrorDialog then let _GETscreenSize -> [wscr hscr] in let _CRwindow _channel win (wscr-250)/2 (hscr-100)/2 250 100 WN_DIALOG loc "DIRECT3D_ERROR" -> popup in let _CRtext _channel popup 10 10 230 40 ET_ALIGN_CENTER loc "DIRECT3D_NOMEMORY"-> text in let _CRbutton _channel popup 85 60 80 20 ET_ALIGN_CENTER loc "OK"-> button in { set D3DErrorDialog = 1; _CBbutton button @D3DErrorDialogOK nil } else nil; let mkView3d[ m3dv m3dv.MV3dChannel win typerender nil nil _GETcursorWin win buf wh [1 20] fond [0 0 0] [0 0 0] nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ] -> dev in { /* on ajoute la vue 3d au manager */ set m3dv.MV3dListV3d=dev::m3dv.MV3dListV3d; /* remplissage du buffer de la couleur de fond */ _FILLsurface dev.V3dbuf fond; /* definition des reflexes de la fenetre */ _CBwinDestroy win @destroyView3d dev; _CBwinFocus win @focusView3d dev; _CBwinPaint win @paintView3d dev; _CBwinSize win @cbresizeView3d dev; _CBwinClick win @clickView3d dev; _CBwinDClick win @dclickView3d dev; _CBwinUnclick win @unclickView3d dev; _CBwinKeydown win @keydownView3d dev; _CBwinKeyup win @keyupView3d dev; _CBcursorMove win @cursorView3d dev; dev } };; fun dsView3d(dev)= /* destruction des elements de la vue 3d */ set dev.V3dsession=nil; _DSwindow dev.V3dwin; _DSsurface dev.V3dbuf; /* on supprime la vue 3d dans le manager de vues */ set dev.V3dmanager.MV3dListV3d=remove_from_list dev.V3dmanager.MV3dListV3d dev; 0;; /* fonction de rendu d'une vue 3d */ fun renderView3d(dev)= let dev.V3dwin -> b in if dev.V3dsession==nil || dev.V3dcamera==nil then nil else { exec dev.V3dcbTimer with []; let exec dev.V3dcbMoveObject with [dev.V3dvector dev.V3dangular] -> changed in { exec dev.V3dcbPreRender with []; let dev.V3dcursor->[x y] in let (if dev.V3drenderType&WIRE then MX3wireOrtho dev.V3dsession dev.V3dbuf dev.V3dcamera x y dev.V3dfond else MX3renderm dev.V3dsession dev.V3dbuf dev.V3dcamera x y dev.V3dfond) -> [h m] in if dev.V3dClickedCoord!=nil || (h==dev.V3dlast && m==dev.V3dlastm) then nil else { set dev.V3dlast=h; set dev.V3dlastm=m; exec dev.V3dcbCursorMoveObject with [dev h m x y] }; exec dev.V3dcbPostRender with [dev.V3dbuf dev.V3dsize]; let dev.V3dsize ->[w h] in _BLTsurface dev.V3dwin 0 0 dev.V3dbuf 0 0 w h; } };; /* fonction de redimensionnement de la vue 3d */ fun resizeView3d(dev,x,y,w,h)= _POSITIONwindow dev.V3dwin x y w h; dev;; /* focntion qui met au premier plan une vue 3d */ fun topView3d(dev)= _TOPwindow dev.V3dwin;; fun setCursorView3d(dev,curs)= _SETwinCursor dev.V3dwin curs;0;; fun resetCursorView3d(dev)= _SETwinCursor dev.V3dwin dev.V3dcursorDef;0;; /* fonctions d'affection d'une sessionet d'une camera à une vue 3d */ fun setView3dCameraSession(dev,s,c)= set dev.V3dsession=s; set dev.V3dcamera=c; let dev.V3dsize->[w h] in { if dev.V3dcamera==nil || dev.V3dsession==nil then nil else let M3getCamera dev.V3dsession dev.V3dcamera -> [[d _] [x _] z] in M3setCamera dev.V3dsession dev.V3dcamera [[d*(w>>1)/x d*(w>>1)/x] [w>>1 h>>1] z]; dev };; /* fonctions d'affectation des callbacks utilisateurs */ fun setView3dcbFocus(dev,f)= set dev.V3dcbFocus=f; dev;; fun setView3dcbReflexesObject(dev,fclick,fdclick,fmoveObj,fcursObj)= set dev.V3dcbClickObject=fclick; set dev.V3dcbDClickObject=fdclick; set dev.V3dcbMoveObject=fmoveObj; set dev.V3dcbCursorMoveObject=fcursObj; dev;; fun setView3dcbClick(dev,f)= set dev.V3dcbClick=f; 0;; fun setView3dcbDClick(dev,f)= set dev.V3dcbDClick=f; 0;; fun setView3dcbUnClick(dev,f)= set dev.V3dcbUnClick=f; 0;; fun setView3dcbTimer(dev,f)= set dev.V3dcbTimer=f; dev;; fun setView3dcbPostRender(dev,f)= set dev.V3dcbPostRender=f; dev;; fun setView3dcbPreRender(dev,f)= set dev.V3dcbPreRender=f; dev;; fun setView3dcbKeyEvent(dev,fdown,fup)= set dev.V3dcbKeyUp=fup; set dev.V3dcbKeyDown=fdown; dev;; fun setView3dcbCursorMoveCoords(dev,f)= set dev.V3dcbCursorMoveCoords=f; dev;; fun setView3dcbResize(dev,f)= set dev.V3dcbResize=f; dev;; fun setView3dcbEnd(dev,f)= set dev.V3dcbEnd=f; dev;; /******************************************* Manager de Vues 3d **************************************/ /* fonctions reflexes du manager de vues 3d */ fun execResizeV3d(v3d,wh)= let wh -> [w h] in if v3d==nil then nil else exec v3d.V3dcbResize with [v3d w h];; fun cbResizeView3dManager(win,m3dv,w,h)= set m3dv.MV3dSize=[w h]; apply_on_list m3dv.MV3dListV3d @execResizeV3d [w h];; fun cbPaintView3dManager(win,m3dv)= exec m3dv.MV3dPaint with [m3dv];; fun rdsView3d(v3d,blurp)= if v3d==nil then nil else dsView3d v3d;; fun cbDestroyView3dManager(win,m3dv)= apply_on_list m3dv.MV3dListV3d @rdsView3d nil; exec m3dv.MV3dEnd with [];; fun execRenderV3d(v3d,m3dv)= if v3d==nil then nil else renderView3d v3d;; fun cbTimerView3dManager(t,m3dv)= exec m3dv.MV3dPreRender with [m3dv]; apply_on_list m3dv.MV3dListV3d @execRenderV3d m3dv;; /* fonction d'initialisation du manager de vues 3d */ fun iniView3dManager(channel,father,pos,wh,flags,title,end)= let pos->[x y] in let wh -> [w h] in let _CRwindow channel father x y w h WN_HIDDEN+(if flags&MV3D_CHILD then WN_CHILDINSIDE|WN_NOCAPTION|WN_NOBORDER else WN_MENU+WN_MINBOX)+ (if flags&MV3D_RESIZE then WN_SIZEBOX else 0) title -> win in let mkView3dManager[channel win wh flags nil nil nil nil end] -> m3dv in { _CBwinDestroy win @cbDestroyView3dManager m3dv; _CBwinPaint win @cbPaintView3dManager m3dv; _CBwinSize win @cbResizeView3dManager m3dv; m3dv };; /* fonction de destruction du manager de vues 3d */ fun dsView3dManager(m3dv)= _deltimer m3dv.MV3dTimer; /* MAC ICI !!!!!!! */ set m3dv.MV3dTimer=nil; _DSwindow m3dv.MV3dWin; set m3dv.MV3dWin=nil;; /* remarque execution des reflexes dans la callback de destruction de la fenetre */ /* fonction d'initialisation du reflexe de paint du manager de vues 3d */ fun setView3dManagerPaint(mv3d,f)= set mv3d.MV3dPaint=f;; fun setView3dManagerPreRender(mv3d,f)= set mv3d.MV3dPreRender=f;; /* fonction de redimmensionnement du manager de vue3d */ fun resizeView3dManager(mv3d,x,y,w,h)= _SIZEwindow mv3d.MV3dWin w h x y;; /* lancement du timer du manager de vue3d */ fun startView3dManager(mv3d)= _SHOWwindow mv3d.MV3dWin WINDOW_UNHIDDEN; if mv3d.MV3dTimer==nil then set mv3d.MV3dTimer = _rfltimer _starttimer mv3d.MV3dChannel 15 @cbTimerView3dManager mv3d else nil;;