RIFXc4MV93imapKp:mmap/ RIFX imap CPmmap,$KEY*free CASt]"CASt%CASt%*free CAStB zfree free CAStd.CASt xCAStCAStACAStCAStfGCASt6e,CASt3Bfree CAStCAStCASt7!CASt CASt CASt CASt CAStz PCASt CASt!CASt<"^CASt0CAStd1lCASt3CAStIOCAStbCASte\CAStRgCASt1pk@CASt mCASt.CAStfree CAStCASt XCASt7~CAStgtCAStCAStCAStCAStDCAStCAStsCASt /0free +free 7free 8free 9free :free ;free free ?free @free Afree Bfree Cfree Dfree Efree FCAStBCASt|CASthfree Gfree Kfree Lfree Mfree Nfree Ofree Pfree Qfree Rfree Sfree Tfree Ufree Vfree Wfree Xfree Yfree Zfree [free \free ]free ^free _free `free afree bfree cfree dfree efree ffree gfree hfree ifree jfree kfree lfree mfree nfree ofree pfree qfree rfree sfree tfree ufree vfree wfree xfree yfree zfree {free |free }free ~free free free free free free free free free free free free free free free free free free free free free free free free free free free free CAStRDRCFTfree CAS*LctX4FmapjunkCinf~VERS,Lnam!LscrLscrxLscrLscr4 Lscr\$LscrR&tLscr5Lscr^;rLscrSLscrcLscr\rfLscrLscr(LscrLscr LscrLscr >LscrLscrhLscr>LscrLscrIJLscrHLscrLscrNpLscrfree free STXTfree free free free free free free free free free BITDfree BITD3ThumRSTXTUfree free BITD3V0ThumelBITD-gVThumvSTXTYxrfree BITD xThumfree BITD ]PThum\BITD Thum|free BITDALFAhThumXMEDfree free free XMEDPThumXMEDThumfree free free BITDThumfree Thumfree free XMED `Thum}Tfree free snd sndHdsndS" Nfree BITDvThumC BITDSlThum9free free Thumd free XMED.vfree free  STXT free KEY* d-STXTBITDThumSTXTBITDThumBITDThumSTXTBITDThumBITDThumBITDThum ALFA BITD Thum!XMED$Thum$XMED%Thum%XMED)BITD)Thum,Thum/Thum/XMED0snd 0sndH0sndS3Thum5XMEDHBITDHThumIBITDIThum JSTXTBITDCAS*CinfDRCFFmapLctXVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSccl DRCFTT::U<C1Cinf~^`BMacintosh HD:Users:richardross:Documents:ManyOne:phase2.1:dswmediaCAS*   !"#$%&'()*,-./0IH123456JCAStB 4--/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- on dummy -- this behaviour creates a space in the behaviour drop down menu. It is not used for anything else. end--|0N,>Fn>richard rossCASt] O--/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- on dummy -- this behaviour creates a comment in the behaviour drop down menu. It is not used for anything else. end*** world manager behaviors(B^,>Fn>richard rossCASt $1READ MEbb>7ۯ>richard rossCASt  -- initiate -- UI cntrl --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| These are private interface handlers --\--------------------------------------------------------------------------- global gUI_control_obj global goWinMgr global goNodeMgr --/--------------------------------------------------------------------------- --| These are private interface handlers that --| This must be called from the main preparemovie handler --\--------------------------------------------------------------------------- on ini_UI_control gUI_control_obj = script("UI control parent").new() end --/--------------------------------------------------------------------------- --| This must be called fomr the main stopmovie handler --\--------------------------------------------------------------------------- on UI_control_stopmovie if objectP(gUI_control_obj) then gUI_control_obj.mDestroy() gUI_control_obj = VOID end if end --/--------------------------------------------------------------------------- --| This services the widgets --\--------------------------------------------------------------------------- --on enterframe -- -- -- run the widgets -- -- CDH_enterframe() -- --end --/--------------------------------------------------------------------------- --| get_prefs_nm --| Work out the movie name tag for writing prefs --\--------------------------------------------------------------------------- on get_prefs_nm sufx nm = the moviename if nm contains "." then nm = char 1 to offset(".", nm) -1 of nm end if if nm.length > 15 then nm = char 1 to 15 of nm put "_"&sufx after nm snm = symbol(nm) return snm end ini_UI_control| 0Xcc,>Fn>richard rossCAStd ddd&d&d&d&d:d:d:d:d:d:dNdNdNdNdNdNdRdVdc--UI --MGR --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- property pUI_inst_list property pMserviceList property pMrelocate_UI property pBottom_UI_element_list property pUI_element_seperation property pUI_btm_elements_rects property p3D_sprite_rect property pBrowser_frame_rect property pUsable_3D_area property p3DArea_maxed property pUI_is_setup property pAuto_pilot property pShowing_widgets property pCsr_fdbk_obj property pUse_alpha property pCsr_fdbk property pScrlback_inst property p3DArea property pUI_height property pMax_b_area property pLights_on property pLights_lst property pCampos global goNodeMgr global goWinMgr global goNetMgr --/--------------------------------------------------------------------------- --| constructor --\--------------------------------------------------------------------------- on new me me.minit() return me end --/--------------------------------------------------------------------------- --| destructor --\--------------------------------------------------------------------------- on mDestroy me -- cleanup objects in lists cnt = pUI_inst_list.count repeat with n = 1 to cnt pUI_inst_list[n] = VOID end repeat pUI_inst_list = VOID cnt = pLights_lst.count repeat with n = 1 to cnt pLights_lst[n] = VOID end repeat pLights_lst = VOID pCampos = VOID cnt = pMserviceList.count repeat with n = 1 to cnt inst = pMserviceList.getPropAt(n) inst = VOID end repeat pMserviceList = VOID cnt = pMrelocate_UI.count repeat with n = 1 to cnt pMrelocate_UI[n] = VOID end repeat pMrelocate_UI = VOID pCsr_fdbk_obj.mDestroy() pCsr_fdbk_obj = VOID end --/--------------------------------------------------------------------------- --| mInit --\--------------------------------------------------------------------------- on mInit me pUI_is_setup = FALSE if (goNetMgr.ilk = #instance) then prf_mn = get_prefs_nm("max_fnd") prefs = goNetMgr.mGetPref(prf_mn) end if if voidP(prefs) then p3DArea_maxed = 0 else p3DArea_maxed = value(prefs) end if pMax_b_area = 0 me.mSet_browser_dims() -- all instances of behaviours attached to UI elelments get registered here pUI_inst_list = [:] -- get any UI elements that have already come alive (obviously gets nothing if this is called from on prepare movie, but ... just incase it's moved) aList = [:] sendAllSprites(#mRegister_UI, aList) sort aList cnt = aList.count repeat with n = 1 to cnt type = aList.getPropAt(n) inst = aList[n] me.mRegister( type, inst ) end repeat sort pUI_inst_list pUI_element_seperation = 15 -- if any new UI elements are added their IDs should be added to this list. -- This also defines the L to R order that the elements will appear in. pBottom_UI_element_list = [] pBottom_UI_element_list.add(#infobtn) pBottom_UI_element_list.add(#helpbtn) pBottom_UI_element_list.add(#btnnav) -- these are the comms lists and will be populated with the groups of objects requiing these specific events pMserviceList = [:] pMrelocate_UI = [] pShowing_widgets = FALSE pAuto_pilot = FALSE pCsr_fdbk_obj = script("cursor feedback object").new() -- work out if the renderer will support an alpha chanel supported_alph_list = getRendererServices().getHardwareInfo().supportedTextureRenderFormats if supported_alph_list.findPos(#rgba8888) then pUse_alpha = 1 else pUse_alpha = 0 end if -- props to store light data for speed testing pLights_on = TRUE pLights_lst = [:] -- register to recieve resize events from the winmgr if (goWinMgr.ilk = #instance) then goWinMgr.mRegSetWH(me) else -- use my resize control --xxxx end if -- add to the actorlist (the actorlist).add(me) end --/--------------------------------------------------------------------------- --| mNewStgWH --| Resize event received from the winMgr --\--------------------------------------------------------------------------- on mNewStgWH me, w, h new_area = integer(w)*integer(h) old_max_area = pMax_b_area -- reset browser dimensions in the UI control object me.mSet_browser_dims(w, h) pUI_is_setup = FALSE if new_area > old_max_area and not p3DArea_maxed then put "doing speed test" go to "speed test" else put "not doing speed test" -- if this new area is less that the -- now we can set up the screen. me.mSetUp_UI () -- just incase we have a scrolling background we should set this up too. me.mSetUp_background() end if end --/--------------------------------------------------------------------------- --| mSet_browser_dims --| Set the stored browser frame dims --\--------------------------------------------------------------------------- on mSet_browser_dims me, browser_frame_width, browser_frame_height if voidP(browser_frame_height) then -- get the browser frame rect if not passed if goWinMgr.ilk = #instance then wh = goWinMgr.mGetWH() -- pt = point(w,h) browser_frame_width = wh[1] browser_frame_height = wh[2] else rct = (the stage).rect browser_frame_width = rct[3] - rct[1] browser_frame_height = rct[4] - rct[2] end if end if pBrowser_frame_rect = rect(0, 0, integer(browser_frame_width), integer(browser_frame_height)) new_b_area = pBrowser_frame_rect[3]*pBrowser_frame_rect[4] if new_b_area > pMax_b_area then pMax_b_area = new_b_area end --/--------------------------------------------------------------------------- --| stepframe --| If there is a service list then service everything that needs --| continuous action. --\--------------------------------------------------------------------------- on stepframe me if not pUI_is_setup then exit -- check for keydown if pShowing_widgets then if me.mCheck_nav_key_down() then me.mHide_widgets() end if end if -- add resize checking here xxx Do it on an interval -- no servicing if the widgets are showing if pShowing_widgets then exit -- service the threads that need servicing cnt = pMserviceList.count tm = the timer repeat with n = 1 to cnt nextTime = pMserviceList[n][1] if tm > nextTime then pMserviceList.getPropAt(n).mService() pMserviceList[n][1] = tm + pMserviceList[n][2] end if end repeat end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me, type, inst pUI_inst_list.addProp(type, inst) end --/--------------------------------------------------------------------------- --| mFind_3D_world_mbr --| passes back the 3D world sprite --\--------------------------------------------------------------------------- on mFind_3D_world_spr me inst = me.mGet_inst(#world) if inst = 0 then alert "lost world behavior mFind_3D_world_spr" end if return inst.spritenum end --/--------------------------------------------------------------------------- --| mGetUI_locations --| works out the areas usable for interface elements --\--------------------------------------------------------------------------- on mGetUI_locations me -- poll the UI elements and find the highest member dimslist = [:] pUI_btm_elements_rects = [:] offset_RHS = 0 min_t = pBrowser_frame_rect[4] -- use the long way round to insure that people who add new UI elements do use the requistite handler repeat with n = pBottom_UI_element_list.count down to 1 type = pBottom_UI_element_list[n] inst = pUI_inst_list.getAProp(type) if not objectP (inst) then nothing alert "lost instance of "&pBottom_UI_element_list[n] end if if not inst.handler(#mGet_dims) then alert "you need a mGet_dims handler in the behaviour for "&&string(pBottom_UI_element_list.getPropAt(n)) else inst.mGet_dims(dimslist) end if -- now work out the placing of these UI elements -- we're are counting elements from r to l -- if an element is not going to be thre there will be no entry in the list (ie it does not return it's dims in the get_dims) dims = dimslist.getAProp(type) if listP(dims) then offset_RHS = offset_RHS + dims[1] + pUI_element_seperation l = pBrowser_frame_rect[3] - offset_RHS t = pBrowser_frame_rect[4] - (pUI_element_seperation + dims[2]) r = l + dims[1] b = pBrowser_frame_rect[4] - pUI_element_seperation pUI_btm_elements_rects.addProp(type, rect(l,t,r,b)) end if end repeat end --/--------------------------------------------------------------------------- --| mFind_usable_area_rect --| works out the areas usable for the 3D world --| and an area below for the UI controls --\--------------------------------------------------------------------------- on mFind_usable_area_rect me if voidP(pUI_height) then -- poll the UI elements and find the highest member dimslist = [:] pUI_btm_elements_rects = [:] offset_RHS = 0 min_t = pBrowser_frame_rect[4] -- find the hightest UI element repeat with n = pBottom_UI_element_list.count down to 1 type = pBottom_UI_element_list[n] inst = pUI_inst_list.getAProp(type) if not objectP (inst) then alert "lost instance of "&pBottom_UI_element_list[n] if not inst.handler(#mGet_dims) then alert "you need a mGet_dims handler in the behaviour for "&&string(pBottom_UI_element_list.getPropAt(n)) else inst.mGet_dims(dimslist) end if end repeat tmaxH = 0 repeat with n = dimslist.count down to 1 dims = dimslist[n] h = dims[2] if h > tmaxH then tmaxH = h end repeat pUI_height = tmaxH + pUI_element_seperation*2 end if pUsable_3D_area = rect(0,0,pBrowser_frame_rect[3], pBrowser_frame_rect[4] - pUI_height) -- tell the window manager what the width of the world control button area is -- so that when the minimise buttons are placed they start stacking on a second (and thrid, etc) -- level when they reach this point if goWinMgr.ilk = #instance then goWinMgr.mSetProp(#worldBtnW, (offset_RHS + pUI_element_seperation)) end if return pUsable_3D_area end --/--------------------------------------------------------------------------- --| mGet_sprite_WH --| This works out the rect of the sprite for a particular area based on the --| uasable area and the aspect ratio --\--------------------------------------------------------------------------- on mGet_sprite_WH me, area -- work out the rect from the aspect ratio bw = pUsable_3D_area[3] bh = pUsable_3D_area[4] -- -- just in case -- if voidP(pAspect_ratio) then -- inst = me.mGet_inst(#world) -- if inst = 0 then -- alert "lost world behavior" -- else -- pAspect_ratio = inst.pAspect_ratio -- end if -- end if -- -- -- if pAspect_ratio = [0,0] then aspectW = bw aspectH = bh -- else -- aspectW = pAspect_ratio[1] -- aspectH = pAspect_ratio[2] -- end if factor = sqrt( float(area)/(aspectW*aspectH) ) w = aspectW*factor h = aspectH*factor -- check that neither is greater than the browser frame w and h -- check w if w > bw then h = bw*aspectH/aspectW -- check we're not making h too big if h > bh then h = bh end if w = h*aspectW/aspectH end if -- check h if h > bh then w = bh*aspectW/aspectH -- check we're not making h too big if w > bw then w = bw end if h = w*aspectH/aspectW end if return [integer(w),integer(h)] end --/--------------------------------------------------------------------------- --| mSet_up_comms --| this checks all the registered behaviours for the presence of various key handlers: --| mService and mRelocate_UI. It makes lists of the instances that want these call. --\--------------------------------------------------------------------------- on mSet_up_comms me repeat with n = pUI_inst_list.count down to 1 inst = pUI_inst_list[n] if inst.handler(#mService) then tm_lst = [] tm_lst.add(0) tm_lst.add(inst.pServIntvl) pMserviceList.addProp(inst, tm_lst) end if if inst.handler(#mRelocate_UI) then pMrelocate_UI.add(inst) end if end repeat -- do we want the cursor feedback inst = me.mGet_inst(#world) if inst = 0 then alert "lost world behavior mSet_up_comms" end if if inst.pShow_tt then pCsr_fdbk = 1 else pCsr_fdbk = 0 end if -- add the cursor feedback obj to the pMserviceList if pCsr_fdbk then tm_lst = [] tm_lst.add(0) tm_lst.add(pCsr_fdbk_obj.pServIntvl) pMserviceList.addProp(pCsr_fdbk_obj, tm_lst) end if -- if there is a button nav object it needs to know about the main nav control obj and vice versa inst = me.mGet_inst(#btnnav) mNav_Inst = me.mGet_inst(#mainNav) if objectP(inst) then mNav_Inst = me.mGet_inst(#mainNav) if objectP(mNav_Inst) then inst.mSet_main_nav_control_obj(mNav_Inst) mNav_Inst.mSet_button_nav_control_obj(inst) else alert "lost main nav object" end if else -- no button nav mNav_Inst.mSet_button_nav_control_obj(0) end if end --/--------------------------------------------------------------------------- --| mAdd_secondary_3D_mems --| After all the 3D media is loaded we must see if there are any secondary 3D media --| attatched with the "additional model" behaviour. If so they must add their models to the world. --| Also check for a background. --\--------------------------------------------------------------------------- on mAdd_secondary_3D_mems me repeat with n = pUI_inst_list.count down to 1 -- look for the add model behavior instances and tell them to add their models to the world if pUI_inst_list.getPropAt(n) = #addModel then inst = pUI_inst_list[n] inst.mImport_models() end if -- look for the model picker behavior instances and tell them to initial their models if pUI_inst_list.getPropAt(n) = #pickedModel then inst = pUI_inst_list[n] inst.mSetup() end if -- look for the add image behavior and create plane with the image mapped onto it if pUI_inst_list.getPropAt(n) = #addImage then inst = pUI_inst_list[n] inst.mAdd_image() end if end repeat -- incase we ghave a scrolling background me.mSetUp_background() end --/--------------------------------------------------------------------------- --| mSetUp_background --| This checks for a scrolling background behaviour and if there is one, the background is set up --\--------------------------------------------------------------------------- on mSetUp_background me -- if there is a scrolling background behavior we must init it repeat with n = pUI_inst_list.count down to 1 -- look for the scrolling background behavior if pUI_inst_list.getPropAt(n) = #scrlback then inst = pUI_inst_list[n] pScrlback_inst = inst inst.mInit() end if end repeat --/--------------------------------------------------------------------------- --| mSetUp_UI --| ( re ) locates all the UI elements according to the new browser window size --| and the new sprite rect --\--------------------------------------------------------------------------- on mSetUp_UI me, tD_area -- dev if pUI_is_setup then exit end if pUI_is_setup = TRUE me.mFind_usable_area_rect() if not voidP(tD_area) then -- if the speed test result is not greater than the last speed test the we'll say we've reached the max -- Flag is so we never have to speed test again. Make sure we are testing with a usable area larger than the test area. -- if not p3DArea_maxed then -- -- possible_area = pUsable_3D_area[3]*pUsable_3D_area[4] -- if tD_area < possible_area then -- -- p3DArea_maxed = TRUE -- -- -- store this in the prefs for next time -- -- prf_mn = get_prefs_nm("max_fnd") -- goNetMgr.mSetPref(prf_mn, "1") -- end if -- end if p3DArea = tD_area end if -- centre the 3D sprite in the usable area p3D_sprite_rect = me.mGet_sprite_rect(p3DArea) me.mGetUI_locations() ---the last param is dev only call(#mRelocate_UI, pMrelocate_UI, p3D_sprite_rect, pUsable_3D_area, pUI_btm_elements_rects, pBrowser_frame_rect) -- if there is a scrolling background behavior we must init it repeat with n = pUI_inst_list.count down to 1 -- look for the scrolling background behavior if pUI_inst_list.getPropAt(n) = #scrlback then inst = pUI_inst_list[n] inst.mInit(p3D_sprite_rect) end if end repeat go to "loop" -- init the cursor feedback object pCsr_fdbk_obj.mInit(me.mFind_3D_world_spr() ) end --/--------------------------------------------------------------------------- --| mGet_sprite_rect --| get the 3D world rect --\--------------------------------------------------------------------------- on mGet_sprite_rect me, tD_area me.mFind_usable_area_rect() browser_frame_area = pUsable_3D_area[3]*pUsable_3D_area[4] if tD_area > browser_frame_area then tD_area = browser_frame_area end if wh_list = me.mGet_sprite_WH(tD_area) threeD_w = wh_list[1] threeD_h = wh_list[2] ua_w = pUsable_3D_area[3] - pUsable_3D_area[1] ua_h = pUsable_3D_area[4] - pUsable_3D_area[2] diff_w = (ua_w - threeD_w)/2 diff_h = (ua_h - threeD_h)/2 sr = rect(pUsable_3D_area[1] + diff_w, pUsable_3D_area[2] + diff_h, pUsable_3D_area[3] - diff_w, pUsable_3D_area[4] - diff_h) return sr end --/--------------------------------------------------------------------------- --| mShow_widgets --| hide the 3D world (show a screen grabbed bitmap) and display the widgets --\--------------------------------------------------------------------------- on mShow_widgets me pShowing_widgets = TRUE me.mHide_world() if goNodeMgr.ilk = #instance then goNodeMgr.mShowItemUIs() end if -- make sure screen button is in hide state inst = me.mGet_inst(#infobtn) if inst = 0 then alert "lost infobtn behaviour" inst.mChange_state("hide info") end --/--------------------------------------------------------------------------- --| mHide_widgets --| Show the 3D world and hide the widgets --\--------------------------------------------------------------------------- on mHide_widgets me pShowing_widgets = FALSE if goNodeMgr.ilk = #instance then goNodeMgr.mHideItemUIs() end if me.mShow_world() -- make sure screen button is in show state inst = me.mGet_inst(#infobtn) if inst = 0 then alert "lost infobtn behaviour" inst.mChange_state("show info") end --/--------------------------------------------------------------------------- --| mHide_world --| For the sake of speed we screengrab the 3D world and put it into the background sprite. --| Then move the world off stage and make sure that no more mServicing is called. --\--------------------------------------------------------------------------- on mHide_world me --xxxx world_inst = me.mGet_inst(#world) if world_inst = 0 then alert "lost world behavior mHide_world" -- make sure the bitmap is off stage sg_inst = me.mGet_inst(#scrngrb) if sg_inst = 0 then alert "lost screen grab behavior" -- screen grab and locate (it can't be DDS to screengrab) wspt = sprite(world_inst.spritenum) wspt.member.directtostage = 0 updatestage sg_inst.mScreen_grab(p3D_sprite_rect, wspt.member) -- hide world world_inst.mHide() --rrt --wspt.member.directtostage = 1 end --/--------------------------------------------------------------------------- --| mShow_world --| Move the world back on stage and start mServicing --\--------------------------------------------------------------------------- on mShow_world me -- show world inst = me.mGet_inst(#world) if inst = 0 then alert "lost world behavior mShow_world" inst.mShow(p3D_sprite_rect) updatestage -- make sure the screengrab is off stage sg_inst = me.mGet_inst(#scrngrb) if sg_inst = 0 then alert "lost screen grab behavior" sg_inst.mHide() end --/--------------------------------------------------------------------------- --| mFly_camera --| This tells the nav behaviour to initiate the interpolation to mdl --\--------------------------------------------------------------------------- on mFly_camera me, mdl_or_trans, pass_cntl_flag, beh_inst inst = me.mGet_inst(#mainNav) if inst = 0 then alert "lost world behavior mFly_camera" inst.mStart_interp(mdl_or_trans, pass_cntl_flag, beh_inst) end --/--------------------------------------------------------------------------- --| mGet_inst --| Gets the instance of a particular type of behaviour --\--------------------------------------------------------------------------- on mGet_inst me, type inst = pUI_inst_list.getAProp(type) if objectP(inst) then return inst else return 0 end if end --/--------------------------------------------------------------------------- --| mCheck_nav_key_down --| Check to see if any arrow keys are pressed or nav buttons clicked --\--------------------------------------------------------------------------- on mCheck_nav_key_down me if keypressed(123) then return 1 else if keypressed(124) then return 1 else if keypressed(125) then return 1 else if keypressed(126) then return 1 end if end if end if end if -- check for clicking on the nav buttons inst = me.mGet_inst(#btnnav) if inst.pClicked_state then return 1 end if return 0 end --/--------------------------------------------------------------------------- --| mSet_csr_fdbk --| Pass fedback info to cursor feedback obj --\--------------------------------------------------------------------------- on mSet_csr_fdbk me, model, data pCsr_fdbk_obj.mAdd_to_fdbk_data(model, data) end --/--------------------------------------------------------------------------- --| mCheck_node_click --| The world has been clicked - the cursor feedback --| obj can work out if we have clicked on a node --\--------------------------------------------------------------------------- on mCheck_node_click me pCsr_fdbk_obj.mCheck_mse_click() end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Acessor method for pBrowser_frame_rect --\--------------------------------------------------------------------------- on mGet_browser_frame_rect me if voidP(pBrowser_frame_rect) then alert "pBrowser_frame_rect not yet initted" else return pBrowser_frame_rect end if end --/--------------------------------------------------------------------------- --| mLights_on --| Acessor method for world lights and shaders turne off for speed test --\--------------------------------------------------------------------------- on mLights_on me if pLights_on then return TRUE else return FALSE end if end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Mutator method for world lights and shaders turne off for speed test --\--------------------------------------------------------------------------- on mStore_Lights me, aList pLights_lst = aList pLights_on = FALSE end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Acessor method for world lights and shaders turne off for speed test --\--------------------------------------------------------------------------- on mGet_lights me pLights_on = TRUE return pLights_lst end --/--------------------------------------------------------------------------- --| mStore_campos --| Mutator method for camera transform --\--------------------------------------------------------------------------- on mStore_campos me, aTrans pCampos = aTrans end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Acessor method for camera transform --\--------------------------------------------------------------------------- on mGet_campos me return pCampos end UI control parent4,>Fn>/richard rossCASt    --load --models --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| this is a frame script that ensures that all the models are loaded --| before we procede. It also sets up the comms in the UI control object. --| This assumes that all of the UI related sprites have come alive and registered. --\--------------------------------------------------------------------------- global gUI_control_obj global gDBG property p3DMember_list on beginsprite me -- set up the comms lists in the gUI_control_obj gUI_control_obj.mSet_up_comms() p3DMember_list = [:] -- find all models cnt = the number of members of castLib("models") repeat with i = 1 to cnt mem = member(i, "models") if mem.type = #shockwave3d then p3DMember_list.addProp(mem, 0) end if end repeat -- force load repeat with n = p3DMember_list.count down to 1 thisMem = p3DMember_list.getPropAt(n) thisMem.preLoad() end repeat if gDBG then put "start load"&&the timer end --/--------------------------------------------------------------------------- --| exitFrame --| loop here while checking the loading of the 3D media --\--------------------------------------------------------------------------- on exitFrame me -- this frame is where we wait and check that 3D content is ready repeat with n = p3DMember_list.count down to 1 if p3DMember_list[n] = 0 then p3DMember_list.setAt(n, me.mCheck3DState(p3DMember_list.getPropAt(n)) ) end if end repeat -- look for one not loaded if p3DMember_list.getPos(0) then -- carry on looping go the frame else if gDBG then put "end load"&&the timer -- all loaded. Call a customisable script to do any world setup if necessary. -- tell the world object to import in all subordinate objects if gDBG then put "starting adding models"&&the timer gUI_control_obj.mAdd_secondary_3D_mems() if gDBG then put "ended adding models"&&the timer -- custom handler to allow the user to do whatever else they need to do threeD_spr = gUI_control_obj.mFind_3D_world_spr() build_world(threeD_spr) end if end --/--------------------------------------------------------------------------- --| mCheck3DState --| mem - the individual 3D member we are checking --\--------------------------------------------------------------------------- on mCheck3DState me, mem -- a state of 4 means it's ready theState = mem.state if theState = 4 then -- reset the world to the default state mem.resetworld() return true else return false end if end load models 3X,>Fn>richard rossCASt ,global goNetMgr global gUI_control_obj property pAlways_speed_test property pPrev_area on beginsprite me -- retrieve last 3D area if goNetMgr.ilk = #instance then prf_mn = get_prefs_nm("area") pPrev_area = goNetMgr.mGetPref(prf_mn) -- otherwise -- else -- if the runmode = "Author" then -- pPrev_area = 141299 -- end if end if end --- on exitFrame me if voidP(pPrev_area) then -- first speed test go to "speed test" else usable_area_rect = gUI_control_obj.mFind_usable_area_rect() usable_area = usable_area_rect[3]*usable_area_rect[4] if pAlways_speed_test then -- only speed test if the current browser area is greater than the prev stored area if usable_area > pPrev_area then go to "speed test" else -- no speed test as we know that we can use the current browser area gUI_control_obj.mSetUp_UI (usable_area) end if else -- no speed test if usable_area < pPrev_area then -- the browser area is actaully less than what we are capable of so just use that gUI_control_obj.mSetUp_UI (usable_area) else gUI_control_obj.mSetUp_UI (pPrev_area) end if end if end if end --- on getPropertyDescriptionList(aScript) tGPDList = [:] tGPDList[#pAlways_speed_test] = \ [#comment:"test speed every run?",\ #format: #boolean,\ #default: 0] return(tGPDList) end getPropertyDescriptionList decision point[#pAlways_speed_test: [#comment: "test speed every run?", #format: #boolean, #default: 0]]0g,>Fn>richard rossCAStA A>[>f>f>f@[@o@o@o@o@o@o@@@@@@@@@--speed --test --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| this tests the worlds performance so we can guess the optimum world size --| Looks for prefs to see if this movie has already been tested. --| If so, the first test will be at this size, otherwise start at an average sort of area as the initial guess. --| If this test gives a framerate inside the range of pMin_fps to pMin_fps + 2 then we'll have this speed - write prefs --| If not, increase or decrease the area by a factor of 2 and check again --\--------------------------------------------------------------------------- property pTestArea property pInit_camera_trans property pJump property pRot property pTest_stage property pTest_Period property pTest_count property pStart_time property pEnd_time property pCounter property pResultlist property p3DSpr property p3DMember property pMin_fps property pMax_fps property pTargetFPS property pUsable_area_rect property pBrowser_frame_area property pSpeedTestPosX property pSpeedTestPosY property pSpeedTestPosZ property pSpeed_test_type property pFrameCntr property pTest_cnter property pCam1 property pStarted property pInterp_guess_factor property pInitial_guess property pResult_fps global gUI_control_obj global goNodeMgr global goNetMgr global gDBG on beginsprite me pMax_fps = pMin_fps + 1 -- this defines a range pTargetFPS = pMin_fps + (pMax_fps - pMin_fps)/2 pInterp_guess_factor = 1.2 p3DSpr = gUI_control_obj.mFind_3D_world_spr() pUsable_area_rect = gUI_control_obj.mFind_usable_area_rect() pBrowser_frame_area = pUsable_area_rect[3]*pUsable_area_rect[4] p3DMember = sprite(p3DSpr).member pCam1 = p3DMember.camera[1] speedtest_pos = vector( pSpeedTestPosX, pSpeedTestPosY, pSpeedTestPosZ ) -- this should be the point of max overhead. -- store camera pos in the gUI_control_obj cTrans = duplicate(pCam1.transform) pCam1.transform.position = speedtest_pos pInit_camera_trans = duplicate(pCam1.transform) pJump = vector(0, 0, 1) pRot = vector(0, 1, 0) if goNetMgr.ilk = #instance then prf_mn = get_prefs_nm("area") pTestArea_str = goNetMgr.mGetPref(prf_mn) -- retrieve last 3D area end if pInitial_guess = 200000 if voidP(pTestArea_str) then pTestArea = pInitial_guess else pTestArea = value(pTestArea_str) end if -- this is the record of the last efforts pResultlist = [:] sort pResultlist -- values here inproves tha accuracy of each test but slows the whole process down pTest_Period = 40 pTest_count = 40 pTest_cnter = 0 -- switch all lights off so the users cannot see the process -- these must be stored in the UI control object because when resizing we will -- repeat the speed test continuously. If we start a new on before the previous one has finsihed then the stored -- values will be lost and the models will never bbe turned on again. if gUI_control_obj.mLights_on() then gUI_control_obj.mStore_campos (cTrans) stored_light_colors = [:] cnt = p3DMember.light.count back_col = rgb(color(#paletteIndex, the stagecolor).hexString()) repeat with n = 1 to cnt stored_light_colors.addProp(#light, p3DMember.light[n].color) p3DMember.light[n].color = back_col end repeat cnt = p3DMember.shader.count repeat with s = 1 to cnt this_shd = p3DMember.shader[s] nm = this_shd.name emls = [:] emls.addProp(s, this_shd.emissive) this_shd.emissive = back_col stored_light_colors.addProp(#emissive, emls) end repeat gUI_control_obj.mStore_Lights(stored_light_colors) end if pStarted = FALSE pFrameCntr = 0 end --/--------------------------------------------------------------------------- --| exitFrame --| Run a series of tests until a 3D world area is arrived at --| that achieves the taget framerate range. --\--------------------------------------------------------------------------- on exitFrame me if pFrameCntr < 2 then if not pFrameCntr then -- put the 3D world sprite on stage at the first test size me.mSet_up_sprite() end if pFrameCntr = pFrameCntr + 1 pStart_time = the timer pEnd_time = the timer + pTest_Period go the frame exit end if -- to speed things up on faster machines the test is conducted over either -- a fixed period or a fixed nuber of loops, whichever comes first done = FALSE if the timer > pEnd_time then done = TRUE else if pCounter > pTest_count then put "pCounter > pTest_count" done = TRUE end if end if if not done then me.mJump_camera() pCounter = pCounter + 1 else -- recalculate so we have an accurate time t = the timer - pStart_time if t = 0 then t = 1 -- avoid a zero value pResult_fps = float(pCounter)/(float(t)/60.0) pTestArea = integer(pTestArea) pResultlist.addProp(pTestArea, pResult_fps) got_it = me.mCheck_results() if got_it then -- success! me.mEnd_process() exit else pTest_cnter = pTest_cnter + 1 -- run again -- reposition the camera and change the sprite size pCam1.transform = pInit_camera_trans me.mSet_up_sprite() end if end if go the frame end --/--------------------------------------------------------------------------- --| mSet_up_sprite --| Set the world to a new area and init for a new test --\--------------------------------------------------------------------------- on mSet_up_sprite me put "next test is "&pTestArea wh_list = gUI_control_obj.mGet_sprite_WH(pTestArea) sprite(p3DSpr).rect = rect(0,0, wh_list[1], wh_list[2]) -- do a jump just make sure everything is set up me.mJump_camera() updatestage -- now start timing pCounter = 0 pStart_time = the timer pEnd_time = the timer + pTest_Period pFrameCntr = 0 end --/--------------------------------------------------------------------------- --| mJump_camera --| Move the camera by a small amount in the mannar of the defined test --\--------------------------------------------------------------------------- on mJump_camera me if pSpeed_test_type = "translation" then pCam1.transform.position = pCam1.transform.position + pJump else pCam1.transform.rotation = pCam1.transform.rotation + pRot end if end --/--------------------------------------------------------------------------- --| mCheck_results --| Is the result of the last test witin the target frame rate --\--------------------------------------------------------------------------- on mCheck_results me -- is the fps within range? put "pResultlist is"&pResultlist if pResult_fps >= pMin_fps then if pResult_fps < pMax_fps then -- done it! return 1 else -- if we are at the pBrowser_frame_area then we should check no further if pTestArea >= pBrowser_frame_area then return 1 end if -- check again with a larger area return me.mGet_larger_area() end if else -- it's just too small - check again with a smaller area return me.mGet_smaller_area() end if end --/--------------------------------------------------------------------------- --| mGet_larger_area --| Work out the next test area size if we need a larger one --| (ie the frame rate was higher that the taget range) --\--------------------------------------------------------------------------- on mGet_larger_area me put "mGet_larger_area" -- if we have only had one try then double the area so we can interpolate next time. -- (we're looking for a smaller fps) if pResultlist.count = 1 then -- if we have never calibrated this machine the prefs will be pInitial_guess if pTestArea = pInitial_guess then -- if we have a really high frame rate start at the bowser frame size if pResult_fps > pMax_fps*10 then pTestArea = pBrowser_frame_area else pTestArea = pTestArea*2 end if else pTestArea = integer(pTestArea*pInterp_guess_factor) end if -- don't go larger that the browser frame if pTestArea > pBrowser_frame_area then pTestArea = pBrowser_frame_area end if else -- interpolate - find the next nearest and use this (I have no idea about the relationship between fps and area is) this_fps = pResultlist.getAProp(pTestArea) this_pos = pResultlist.getpos(pResult_fps) -- this point is the highest area so far -- 2 is always the larger area and smaller fps if this_pos = pResultlist.count then -- try a larger size area1 = pResultlist.getPropAt(this_pos) area2 = pResultlist.getPropAt(this_pos-1) fps1 = pResultlist[this_pos] fps2 = pResultlist[this_pos-1] if fps1 < fps2 then -- results look good put "good" grad = float(area1 - area2)/float(fps1 - fps2) grad = abs(grad) fps_diff = float(fps1 - pTargetFPS) pTestArea = (area1 + integer(grad*fps_diff))*pInterp_guess_factor else put "squirelly" -- results are squirelly so just guess pTestArea = integer(pTestArea*pInterp_guess_factor) end if -- don't go larger that the browser frame if pTestArea > pBrowser_frame_area then pTestArea = pBrowser_frame_area end if else -- this point is not the highest so far. We need a point in between the two pos2 = this_pos +1 pos1 = this_pos area2 = pResultlist.getPropAt(pos2) fps2 = pResultlist[pos2] area1 = pResultlist.getPropAt(pos1) fps1 = pResultlist[pos1] area_diff = area2 - area1 fps_diff = fps1 - fps2 target_1_fps_diff = fps1 - pTargetFPS if fps_diff > 0 then pTestArea = area1 + float(area_diff)*target_1_fps_diff/fps_diff else -- this should not hapen pTestArea = integer(pTestArea*pInterp_guess_factor) put "this should not hapen" end if end if end if return 0 end --/--------------------------------------------------------------------------- --| mGet_smaller_area --| Work out the next test area size if we need a smaller one --| (ie the frame rate was lower that the taget range) --\--------------------------------------------------------------------------- on mGet_smaller_area me put "mGet_smaller_area" -- if we have only had one try then half the area so we can interpolate next time. if pResultlist.count = 1 then -- if we have never calibrated this machine the prefs will be the initial guess if pTestArea = pInitial_guess then pTestArea = pTestArea/2 else pTestArea = integer(pTestArea/pInterp_guess_factor) end if else -- interpolate this_fps = pResultlist.getAProp(pTestArea) this_pos = pResultlist.getpos(this_fps) -- this point is not the lowest area so far. We need a point in between the two -- 2 is always the larger area and smaller fps if this_pos > 1 then pos2 = this_pos pos1 = this_pos -1 area2 = pResultlist.getPropAt(pos2) fps2 = pResultlist[pos2] area1 = pResultlist.getPropAt(pos1) fps1 = pResultlist[pos1] area_diff = area2 - area1 fps_diff = fps1 - fps2 target_1_fps_diff = pTargetFPS - fps2 pTestArea = area2 - float(area_diff)*target_1_fps_diff/fps_diff else -- needs to be smaller --- pTestArea = integer(pTestArea/pInterp_guess_factor) -- try a larger size area1 = pResultlist.getPropAt(1) area2 = pResultlist.getPropAt(2) fps1 = pResultlist[1] fps2 = pResultlist[2] if fps1 > fps2 then -- results look good put "good" grad = float(area1 - area2)/float(fps1 - fps2) grad = abs(grad) fps_diff = float(fps1 - pTargetFPS) pTestArea = (area1 - integer(grad*fps_diff))*pInterp_guess_factor else put "squirelly" -- results are squirelly so just guess pTestArea = integer(pTestArea/pInterp_guess_factor) end if end if end if return 0 end --/--------------------------------------------------------------------------- --| mEnd_process --| Turn the lights back on. Store the results int heprefs file. --| Start the setup for the actual experience at this area. --\--------------------------------------------------------------------------- on mEnd_process me -- restore the color to the lights stored_light_colors = gUI_control_obj.mGet_lights() cnt = stored_light_colors.count repeat with n = 1 to cnt type = stored_light_colors.getPropAt(n) if type = #light then p3DMember.light[n].color = stored_light_colors[n] else -- it must be stored properties of a shaders, eg emissive shdrVals = stored_light_colors[n] prop = stored_light_colors.getPropAt(n) nm = shdrVals.getPropAt(1) --shdr = p3DMember.shader[nm] val = shdrVals[1] case prop of #emissive: p3DMember.shader(nm).emissive = val end case if p3DMember.shader[nm].name contains "BackdropShader-copy" then p3DMember.shader[nm].emissive = rgb(255, 255, 255) else if p3DMember.shader[nm].name contains "OverlayShader-copy" then p3DMember.shader[nm].emissive = rgb(255, 255, 255) end if end if end if end repeat -- store this in the prefs for next time prf_mn = get_prefs_nm("area") if pTestArea > 0 then if goNetMgr.ilk = #instance then goNetMgr.mSetPref(prf_mn, string(pTestArea)) -- store 3D area end if else put "pTestArea < 0" end if -- return the camera to the original pos (important if we are speed testing when resizing the browser window pCam1.transform = gUI_control_obj.mGet_campos() -- now we can set up the screen. gUI_control_obj.mSetUp_UI (pTestArea) -- just incase we have a scrolling background we should set this up too. gUI_control_obj.mSetUp_background() end --- on getPropertyDescriptionList(aScript) tGPDList = [:] tGPDList[#pMin_fps] = \ [#comment:"Minimun fps",\ #format: #integer,\ #range:[#min:0, #max:20],\ #default: 10] tGPDList[#pSpeedTestPosX] = \ [#comment:"X location for speed test",\ #format: #integer,\ #default: 0] tGPDList[#pSpeedTestPosY] = \ [#comment:"Y location for speed test",\ #format: #integer,\ #default: 0] tGPDList[#pSpeedTestPosZ] = \ [#comment:"Z location for speed test",\ #format: #integer,\ #default: 0] tGPDList[#pSpeed_test_type] = \ [#comment:"Speed test type",\ #format: #string,\ #range:["rotation", \ "translation"],\ #default: "translation"] return(tGPDList) end getPropertyDescriptionList speed test[#pMin_fps: [#comment: "Minimun fps", #format: #integer, #range: [#min: 0, #max: 20], #default: 10], #pSpeedTestPosX: [#comment: "X location for speed test", #format: #integer, #default: 0], #pSpeedTestPosY: [#comment: "Y location for speed test", #format: #integer, #default: 0], #pSpeedTestPosZ: [#comment: "Z location for speed test", #format: #integer, #default: 0], #pSpeed_test_type: [#comment: "Speed test type", #format: #string, #range: ["rotation", "translation"], #default: "translation"]]Cdd,>Fn>richard rossCASt 7CCCCWWWWWWkkkkkkos--world --setup --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property p3D_mbr property pID property pFOV --property pAspect_ratioH --property pAspect_ratioW --property pAspect_ratio property pShow_tt property pShowing on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #world -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if p3D_mbr.resetWorld() end --/--------------------------------------------------------------------------- --| mInit --| Sets up the worlds parameter --\--------------------------------------------------------------------------- on mInit me p3D_mbr = pSpr.member p3D_mbr.resetWorld() pShowing = TRUE end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area if pShowing then pSpr.rect = threeD_sprite_rect else me.mHide() end if p3D_mbr.camera[1].fieldofview = pFOV end --/--------------------------------------------------------------------------- --| mousedown --| Check if we clicked on a node --\--------------------------------------------------------------------------- on mousedown me gUI_control_obj.mCheck_node_click() end --- --/--------------------------------------------------------------------------- --| mHide --| Move the world off screen. --\--------------------------------------------------------------------------- on mHide me pShowing = FALSE pSpr.locH = -9999 pSpr.width = 1 pSpr.height = 1 end --/--------------------------------------------------------------------------- --| mShow --| Move the world on screen to defined rect. --\--------------------------------------------------------------------------- on mShow me, the_rect pSpr.member.directtostage = 1 pShowing = TRUE pSpr.rect = the_rect end --/--------------------------------------------------------------------------- --| getModels --| Find all the models in the member --\--------------------------------------------------------------------------- on getModels(me, aMember, aList) repeat with j = 1 to aMember.model.count if string(aMember.model[j]) contains "model" then aList.add(aMember.model[j].name) end if end repeat return(aList) end getModels --/--------------------------------------------------------------------------- --| mIs3D --| Check that aMember is a 3D member type --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D ---- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] if aScript.mIs3D(sprite(the currentSpriteNum).member) then tGPDList[#pFOV] = \ [#comment:"Field of view",\ #format: #integer,\ #range:[#min:1, #max:99],\ #default: 60] tGPDList[#pShow_tt] = \ [#comment:"Show tooltips?",\ #format: #boolean,\ #default: 1] end if return(tGPDList) end if end getPropertyDescriptionList world setup()CnCn,>Fn>richard rossCAStfG f9 eeeeeeeeeeeeeeeeeeee--camera --setup --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour controls everything to do with the position of the camera (1). --| This includes the start view pos, the final start pos (after an initial fly in and --| collision detection. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gTransfer_im global goNodeMgr property ancestor, spritenum property pSpr property pID property pServIntvl property pTurnSpeed property pMax_turn_speed property pTurn_drag_10 property pTurn_Drag property pTurn_Accel_10 property pTurn_Accel property pMax_speed property pSpeed property pDrag_10 property pDrag property pAccel property pButton_key_pressed property pShowing_LR_button_down property pShowing_UD_button_down property p3DMember property pCam1 property pCam2 property pInter_to_mdl property pButtonControl_obj property pNav_directions_lst property pInitial_start_posX property pInitial_start_posY property pInitial_start_posZ property pInitial_start_pos property pFinal_start_posX property pFinal_start_posY property pFinal_start_posZ property pFinal_start_pos property pFinal_rot_x property pFinal_rot_y property pFinal_rot_z property pUp_vector_component property pUp_vector property pCollisdion_distance property pCollision_snd property pFirstHit property pMUR_model property pInterpol_endtime property pInterpol_period property pTarget_mdl property pInterp_Offset_vector property pInterp_startTransform property pEnd_transform property pCamera_height property pPass_cntl property pTarget_node property pBumpChan on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #mainNav -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mInit() me.mRegister() end --/--------------------------------------------------------------------------- --| mInit --| init params --\--------------------------------------------------------------------------- on mInit me pCollisdion_distance = 5 + pMax_speed pCollision_snd = member "bump" pInitial_start_pos = vector( pInitial_start_posX, pInitial_start_posY , pInitial_start_posZ )-- user definable pFinal_start_pos = vector( pFinal_start_posX, pFinal_start_posY, pFinal_start_posZ )-- user definable pServIntvl = 1 -- user definable (?) pSpr = sprite(me.spritenum) pTurnSpeed = 0 pTurn_Drag = float(pTurn_Drag_10)/10 pTurn_Accel = float(pTurn_Accel_10)/10 pSpeed = 0 pDrag = float(pDrag_10)/10 pButton_key_pressed = #none pShowing_LR_button_down = 0 pShowing_UD_button_down = 0 p3DMember = sprite(pSpr).member pBumpChan = 1 pFirstHit = 0 pMUR_model = "" --pAuto_pilot = FALSE pPass_cntl = 0 -- different modelling packeages can have differnt coordinate systems. case pUp_vector_component of "x": pUp_vector = vector(1,0,0) "y": pUp_vector = vector(0,1,0) "z": pUp_vector = vector(0,0,1) end case end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --/--------------------------------------------------------------------------- --| mEnable_directions --| From behaviour on nav dutton indicating what kind of nav is available (ie, left, right, etc) --\--------------------------------------------------------------------------- on mEnable_directions me, directions_lst pNav_directions_lst = directions_lst sort pNav_directions_lst end --/--------------------------------------------------------------------------- --| set the camera to the start position and begin the initial zoom in --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list -- this should only happen if it has not been done before if not voidP(pCam1) then exit end if pCam1 = p3DMember.camera[1] -- clone the first camera - this is necessary for the flying interpolation pCam1.clone("dummycam") pCam2 = p3DMember.camera[2] start_trans = transform() start_trans.position = pInitial_start_pos final_rot = vector(pFinal_rot_x, pFinal_rot_y, pFinal_rot_z) start_trans.rotation = final_rot pCam1.transform = start_trans -- pCam2.transform.position = pInitial_start_pos -- pCam2.transform.rotation = final_rot final_trans = transform() final_trans.rotation = final_rot final_trans.position = pFinal_start_pos -- we need to define a small offset for the final position otherwise the camera 2 cannot point at the final destination me.mStart_interp(final_trans, 0, 1) end --/--------------------------------------------------------------------------- --| mSet_button_nav_control_obj --| from UI control - allow comms with buttons if there are any --\--------------------------------------------------------------------------- on mSet_button_nav_control_obj me, inst pButtonControl_obj = inst end --/--------------------------------------------------------------------------- --| mArrow_button_clicked --| from button control behavior --\--------------------------------------------------------------------------- on mArrow_button_clicked me, button_key_pressed pButton_key_pressed = button_key_pressed end --/--------------------------------------------------------------------------- --| mService --| from main service loop --\--------------------------------------------------------------------------- on mService me -- if we are interploating from one point to another we'll ignore the arrow nav if gUI_control_obj.pAuto_pilot then me.mInterpol_A_to_B() else me.mArrow_navigate() end if end --/--------------------------------------------------------------------------- --| mArrow_navigate --| This handler contains the logic for all types of navigation (keyboard or button) --| th button handler plugs into this logic --\--------------------------------------------------------------------------- on mArrow_navigate me --if there are no button hotspots then navigation is suspended if not pNav_directions_lst.count then exit -- list the keys pressed keypressedlst = [] -- check if the mouse has stopped clicking down if the mousedown = FALSE then pButton_key_pressed = #none -- are we rotating the camera? -- key button if pButton_key_pressed <> #none then if pButton_key_pressed = #left then if pTurnSpeed < 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed + pTurn_Accel if pTurnSpeed > pMax_turn_speed then pTurnSpeed = pMax_turn_speed else if pButton_key_pressed = #right then if pTurnSpeed > 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed - pTurn_Accel if abs(pTurnSpeed) > pMax_turn_speed then pTurnSpeed = -1*pMax_turn_speed end if end if else -- arrow key if keypressed(123) or keypressed(124) then if keypressed(123) and keypressed(124) then -- both at same time -- make sure buttons are up if pShowing_LR_button_down <> 0 then aList = [#left, #right] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 0 end if else if keypressed(123) then if pTurnSpeed < 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed + pTurn_Accel if pTurnSpeed > pMax_turn_speed then pTurnSpeed = pMax_turn_speed -- show button downstate aList = [#left] call(#mArrow_key_pressed, pButtonControl_obj, aList) -- make sure the other one is up if pShowing_LR_button_down <> 123 then aList = [#right] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 123 end if else if pTurnSpeed > 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed - pTurn_Accel if abs(pTurnSpeed) > pMax_turn_speed then pTurnSpeed = -1*pMax_turn_speed end if aList = [#right] call(#mArrow_key_pressed, pButtonControl_obj, aList) if pShowing_LR_button_down <> 124 then -- make sure the other one is up aList = [#left] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 124 end if end if end if else -- make sure buttons are up if pShowing_LR_button_down <> 0 then aList = [#left, #right] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 0 end if end if end if -- double it if the space bar is pressed if pTurnSpeed <> 0 then if keypressed (7) then pCam1.rotate(0, pTurnSpeed*2, 0, #self) me.mUpdate_backdrop(pTurnSpeed*2) else pCam1.rotate(0, pTurnSpeed, 0, #self) me.mUpdate_backdrop(pTurnSpeed) end if end if -- now do rotation drag if pTurnSpeed <> 0 then if pTurnSpeed > 0 then pTurnSpeed = pTurnSpeed - pTurn_Drag -- don't start going the other way if pTurnSpeed < 0 then pTurnSpeed = 0 else pTurnSpeed = pTurnSpeed + pTurn_Drag -- don't start going the other way if pTurnSpeed > 0 then pTurnSpeed = 0 end if end if --forwards -- if the nav button does not have forwards in it then we are only roating so bail if not pNav_directions_lst.findpos(#up) then exit -- key button if pButton_key_pressed <> #none then if pButton_key_pressed = #down then -- forwards if pSpeed < 0 then pSpeed = 0 pSpeed = pSpeed + pAccel if pSpeed > pMax_speed then pSpeed = pMax_speed else if pButton_key_pressed = #up then -- backwards if pSpeed > 0 then pSpeed = 0 pSpeed = pSpeed - pAccel if abs(pSpeed) > pMax_speed then pSpeed = -1*pMax_speed end if end if else if keypressed(125) or keypressed(126) then if keypressed(125) and keypressed(126) then -- both at same time" -- make sure buttons are up if pShowing_UD_button_down <> 0 then aList = [#up, #down] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 0 end if else if keypressed(125) then -- forwards if pSpeed < 0 then pSpeed = 0 pSpeed = pSpeed + pAccel if pSpeed > pMax_speed then pSpeed = pMax_speed aList = [#down] call(#mArrow_key_pressed, pButtonControl_obj, aList) if pShowing_UD_button_down <> 126 then -- make sure the other one is up aList = [#up] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 126 end if else -- backwards if pSpeed > 0 then pSpeed = 0 pSpeed = pSpeed - pAccel if abs(pSpeed) > pMax_speed then pSpeed = -1*pMax_speed aList = [#up] call(#mArrow_key_pressed, pButtonControl_obj, aList) if pShowing_UD_button_down <> 125 then -- make sure the other one is up aList = [#down] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 125 end if end if end if else -- make sure buttons are up if pShowing_UD_button_down <> 0 then aList = [#up, #down] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 0 end if end if end if -- now move the camera if pSpeed <> 0 then -- check for collisions if pSpeed < 0 then if me.mCheck_collision(-1) then pSpeed = 0 if not pFirstHit then sound(pBumpChan).play([#member: member("bump")]) pFirstHit = 1 end if else pFirstHit = 0 end if else if me.mCheck_collision(1) then pSpeed = 0 if not pFirstHit then sound(pBumpChan).play([#member: member("bump")]) pFirstHit = 1 end if else pFirstHit = 0 end if end if if keypressed (7) then pCam1.translate(0, 0 ,2*pSpeed, #self) else pCam1.translate(0, 0 ,pSpeed, #self) end if end if -- now do drag if pSpeed <> 0 then if pSpeed > 1 then pSpeed = pSpeed - pDrag -- don't start going the other way if pSpeed < 0 then pSpeed = 0 else pSpeed = pSpeed + pDrag -- don't start going the other way if pSpeed > 0 then pSpeed = 0 end if end if end --/--------------------------------------------------------------------------- --| mUpdate_backdrop --| If the world has a panoramic backdrop then this need to be updated --| with the camera rotation --\--------------------------------------------------------------------------- on mUpdate_backdrop me, amt if objectP(gUI_control_obj.pScrlback_inst) then gUI_control_obj.pScrlback_inst.mUpdate_backdrop(amt) end if end --/--------------------------------------------------------------------------- --| mCheck_collision --| Project a ray forward to check collision. If there is a hit of models hit, check the distance of the --| first to see if it is within the collision distance --\--------------------------------------------------------------------------- on mCheck_collision me, direction me.mCheck_camera_height() -- now check for collisions dirvect = direction*(pCam1.getworldtransform().zaxis) pos = pCam1.getworldtransform().position hitlist = p3DMember.modelsunderray(pos, dirvect, 1, #detailed) if hitlist.count then firstHit = hitlist[1] hitmodel = firstHit.model if firstHit.distance < pCollisdion_distance then return 1 end if end if return 0 end --/--------------------------------------------------------------------------- --| mCheck_camera_height --| Check to see that we are a constant distance from the ground by projecting a ray down --| and checking the first model hit with the user defined camera height. --\--------------------------------------------------------------------------- on mCheck_camera_height -- a camera height of zero means no ground if not pCamera_height then exit -- check the distance to the floor incase it is uneven dirvect = -1*(pCam1.getworldtransform().yaxis) pos = pCam1.getworldtransform().position hitlist = p3DMember.modelsunderray(pos, dirvect, 1, #detailed) if hitlist.count then firstHit = hitlist[1] hitmodel = firstHit.model diff = pCamera_height - firstHit.distance if integer(diff) <> 0 then pCam1.translate(0, diff, 0) end if else -- we have gone underground so we must correct it - look for a mode upwards. dirvect = pCam1.getworldtransform().yaxis pos = pCam1.getworldtransform().position hitlist = p3DMember.modelsunderray(pos, dirvect, 1, #detailed) if hitlist.count then firstHit = hitlist[1] hitmodel = firstHit.model pCamera_height = 30 diff = pCamera_height + firstHit.distance pCam1.translate(0, diff, 0) else -- there is no ground --alert "lost the ground plane" end if end if end --/--------------------------------------------------------------------------- --| mInterpol_A_to_B --| This handler interpolates between two points (A and model B) where model B might be moving. --\--------------------------------------------------------------------------- on mInterpol_A_to_B me proportion = integer ( 100 - float(100)*(pInterpol_endtime - the milliseconds)/pInterpol_period ) if proportion < 100 then tTransform = pInterp_startTransform.interpolate(pEnd_transform, proportion) pCam1.transform = tTransform else pCam1.transform = pEnd_transform -- updatestage -- flag that we're done gUI_control_obj.pAuto_pilot = FALSE if pPass_cntl then --Make the appearance high quality by adding the sds modifier me.mAdd_SDS(pTarget_mdl) -- set the new item ID if not voidP(pTarget_node) then if goNodeMgr.ilk = #instance then goNodeMgr.mSetItem(pTarget_node) end if else put "target node ID is void" end if else -- we are not passing control so show the widgets (this should be done after the initial fly through) gUI_control_obj.mShow_widgets () end if end if end --/--------------------------------------------------------------------------- --| mAdd_SDS --| Make the appearance high quality by adding the sds modifier --\--------------------------------------------------------------------------- on mAdd_SDS me, mdl if string(mdl).char[1..5] = "group" then -- get children and recursively set SDS ccnt = mdl.child.count if ccnt then repeat with c = 1 to ccnt nxt_mdl = mdl.child[c] me.mAdd_SDS(nxt_mdl) end repeat end if else if string(mdl).char[1..5] = "model" then -- set model to high quality -- if the re is LOD we must disable it mlst = mdl.modifier if mlst.findpos(#lod) then put "mdl is "&mdl&&mdl.lod.auto mdl.lod.auto = 0 mdl.lod.level = 100 end if mdl.addmodifier(#sds) -- check that it was added sucesssfully - some models will not support it if mlst.findpos(#sds) then mdl.sds.enabled = TRUE mdl.sds.depth = 5 mdl.sds.subdivision = #adaptive end if end if end if end --/--------------------------------------------------------------------------- --| mStart_interp --| This kicks of the auto pilot interpolation --\--------------------------------------------------------------------------- on mStart_interp me, mdl_or_trans, pass_cntl_flag, beh_inst -- this indicates whether at the end of the autopilot we are passing control to a new node if pass_cntl_flag then pPass_cntl = 1 else pPass_cntl = 0 end if pInterp_startTransform = duplicate(pCam1.transform) if mdl_or_trans.ilk = #transform then pEnd_transform = mdl_or_trans --pCam2.transform = pEnd_transform else -- if a ref to the model behaviour has been passed do a callback to say that interolation has started if ilk(beh_inst) = #instance then beh_inst.mStart_fly_to (pInterpol_period) stop_from_dist = beh_inst.getAProp(#pAutopilot_upto_dist) pTarget_node = beh_inst.getAProp(#pNodeID) else put "no bahavior instance pased" end if pInter_to_mdl = 1 pTarget_mdl = mdl_or_trans total_dist_vector = mdl_or_trans.transform.position - pInterp_startTransform.position total_dist_vector.normalize() pInterp_Offset_vector = total_dist_vector*stop_from_dist pCam2.transform = pTarget_mdl.transform pCam2.transform.position = pCam2.transform.position - pInterp_Offset_vector --pCam2.pointAt(pTarget_mdl.transform.position, pUp_vector) pCam2.pointAt(pTarget_mdl.getworldtransform().position, pUp_vector) pEnd_transform = pCam2.transform end if -- don't start this again mid flight if gUI_control_obj.pAuto_pilot then exit gUI_control_obj.pAuto_pilot = TRUE pInterpol_endtime = the milliseconds + pInterpol_period end --/--------------------------------------------------------------------------- --| mIs3D --| Check that aMember is a 3D member type --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D ---- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] if aScript.mIs3D(sprite(the currentSpriteNum).member) then tGPDList[#pInitial_start_posX] = \ [#comment:"Initial start pos X",\ #format: #integer,\ #default: 0] tGPDList[#pInitial_start_posY] = \ [#comment:"Initial start pos Y",\ #format: #integer,\ #default: 0] tGPDList[#pInitial_start_posZ] = \ [#comment:"Initial start pos Z",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_start_posX] = \ [#comment:"Final start pos X",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_start_posY] = \ [#comment:"Final start pos Y (reset by height from ground)",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_start_posZ] = \ [#comment:"Final start pos Z",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_rot_x] = \ [#comment:"Final rotation X",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_rot_y] = \ [#comment:"Final rotation Y",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_rot_z] = \ [#comment:"Final rotation Z",\ #format: #integer,\ #default: 0] tGPDList[#pCamera_height] = \ [#comment:"Height from ground (0 means no ground)",\ #format: #integer,\ #range:[#min:-10000, #max:10000],\ #default: 27] tGPDList[#pMax_turn_speed] = \ [#comment:"Max turn speed",\ #format: #integer,\ #range:[#min:1, #max:20],\ #default: 4] tGPDList[#pTurn_drag_10] = \ [#comment:"Turn drag",\ #format: #integer,\ #range:[#min:1, #max:10],\ #default: 2] tGPDList[#pTurn_Accel_10] = \ [#comment:"Turn acceleration",\ #format: #integer,\ #range:[#min:0, #max:10],\ #default: 5] tGPDList[#pMax_speed] = \ [#comment:"Max speed",\ #format: #integer,\ #range:[#min:1, #max:50],\ #default: 5] tGPDList[#pDrag_10] = \ [#comment:"Drag",\ #format: #integer,\ #range:[#min:1, #max:30],\ #default: 10] tGPDList[#pAccel] = \ [#comment:"Acceleration",\ #format: #integer,\ #range:[#min:1, #max:20],\ #default: 2] tGPDList[#pInterpol_period] = \ [#comment:"Time taken to autopilot (ms)",\ #format: #integer,\ #range:[#min:1, #max:10000],\ #default: 2500] tGPDList[#pUp_vector_component] = \ [#comment:"Up vector in modellers coordinate system (3D Max is y up)",\ #format: #string,\ #range:["x", "y", "z"],\ #default: "y"] end if return(tGPDList) end if end getPropertyDescriptionList camera setupN00,>Fn>richard rossCASt6 6 6 66666262626262626F6F6F6F6F6F6J6N6[--additional --model --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour allows the user to add additional models to the world --| They can define the positon and scale of the model within the world --| They can also define some behaviour. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gDBG property ancestor, spritenum property pSpr property pID property pServIntvl property pBumpChan property pSpeed property pAxisRotation property pAdditional_mem property pAdditional_grp property p3DMember property pPosx property pPosy property pPosz property pScale property pLodbias property pNodeID property pTTTxt property pAutopilot_upto_dist property pRollover property pRolling_flag property pFacing_camera_transform property pInterp_startTransform property pRollup_duration property pInterpol_start_tm property pInterpol_end_tm on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #addModel -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mInit --\--------------------------------------------------------------------------- on mInit me pCollision_snd = member "bump" -- user definable pPos = vector( -26.47, -3000, -24.45 )-- user definable pSpr = sprite(me.spritenum) pServIntvl = 4 -- user definable p3DMember = pSpr.member pBumpChan = 1 pSpeed = float(pSpeed)/10.0 -- check that the node ID is an integer if not (pNodeID.ilk = #integer) then alert "node ID "&pNodeID&"in additional model for "&pAdditional_mem"& is not an integer, please reenter it" end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- on mService me -- start spinning the group as soo as it exists me.mAnimate() end --/--------------------------------------------------------------------------- --| mAnimate --| Do whatever type of animation is required --\--------------------------------------------------------------------------- on mAnimate me if not voidP(pAdditional_grp) then if pRolling_flag then me.mRollover() else case pAxisRotation of "X": me.rotateX() "Y": me.rotateY() "Z": me.rotateZ() end case end if end if end --/--------------------------------------------------------------------------- --| mImport_models --| List all the models in the member to have it's models cloned --| Create a new group of name "member name"&group. Add a string of the inst to make sure that --| it's a unique name. --\--------------------------------------------------------------------------- on mImport_models me aList = [] me.mGetModels(pAdditional_mem, aList) -- make a group called the member name &"group" - add a string of the inst to ensure that the name is unique tname = member(pAdditional_mem).name group_name = "flg_m1_grp_"&tname&string(me) pAdditional_grp = p3DMember.newGroup(group_name) -- put them into the world at their positions cnt = aList.count if gDBG then put "start cloneModelFromCastmember loop"&&the timer if gDBG then put "there are "&cnt&&"models" repeat with n = 1 to cnt modelName = aList[n] newmodelName = tname&n&"_"&modelName&string(me) mdl = p3DMember.cloneModelFromCastmember(newmodelName, modelName, member (pAdditional_mem)) mdl.addmodifier(#lod) mdl.lod.auto = 1 mdl.lod.bias = pLodbias -- make them children of the new group -- move the group to the user defined position and scale pAdditional_grp.addChild(mdl, #preserveParent) end repeat if gDBG then put "end cloneModelFromCastmember loop"&&the timer pos = vector(pPosx, pPosy, pPosz) s = float(pScale)/100 scl = vector(s, s, s) pAdditional_grp.transform.position = pos pAdditional_grp.transform.scale = scl -- make the model start off facing the camera. Store this transform. pAdditional_grp.pointatorientation =[vector( 0.0000, 0.0000, 1.0000 ), vector( 0.0000, 1.0000, 0.0000 )] -- rotate the model so it always faces the camera keeping it's y component or rotation cam_pos = p3DMember.camera[1].getWorldTransform().position mdl_pos_y = pAdditional_grp.getWorldTransform().position.y cam_pos.y = mdl_pos_y pAdditional_grp.pointAt(cam_pos, vector(0,1,0)) pFacing_camera_transform = duplicate(pAdditional_grp.transform) -- bug - the scale set above does not seem top be reflected in the stored transform --pFacing_camera_transform.scale = scl -- now tell the cursor feedback object about it's node and tooltips gUI_control_obj.mSet_csr_fdbk(pAdditional_grp.name, me) end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseWithin me if pRollover then if pRolling_flag = FALSE then pRolling_flag = TRUE pInterpol_start_tm = the milliseconds pInterpol_end_tm = the milliseconds + pRollup_duration pInterp_startTransform = pAdditional_grp.transform end if end if end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseLeave me pRolling_flag = FALSE end --/--------------------------------------------------------------------------- --| mRollover --| Interplolate to the point at camera positon if we are not already there --\--------------------------------------------------------------------------- on mRollover me -- interpolate to the facing camera position if pRolling_flag = 1 then proportion = 1.0*(the milliseconds - pInterpol_start_tm)/float(pRollup_duration) if proportion > 1 then proportion = 1 -- flag so we know we have finished pRolling_flag = 2 end if --ccc tTransform = pInterp_startTransform.interpolate(pFacing_camera_transform, proportion) pAdditional_grp.transform = tTransform end if end --/--------------------------------------------------------------------------- --| mGetModels --| Get the names of the nodes that are in fact models --\--------------------------------------------------------------------------- on mGetModels me, aMember, aList repeat with j = member(aMember).model.count down to 1 if string(member(aMember).model[j]) contains "model" then aList.add(member(aMember).model[j].name) end if end repeat end --/--------------------------------------------------------------------------- --| rotateX --| Rotate on X axix --\--------------------------------------------------------------------------- on rotateX me, aModel pAdditional_grp.rotate(pSpeed,0,0) end --/--------------------------------------------------------------------------- --| rotateY --| Rotate on Y axix --\--------------------------------------------------------------------------- on rotateY me, aModel pAdditional_grp.rotate(0,pSpeed,0) end --/--------------------------------------------------------------------------- --| rotateZ --| Rotate on Z axix --\--------------------------------------------------------------------------- on rotateZ me, aModel pAdditional_grp.rotate(0,0,pSpeed) end --/--------------------------------------------------------------------------- --| mStart_fly_to --| Callback from camera control to say that the camera has just started zooming in --| it passes the fly to period so a model can make sure that it moves back to the correct orienation in time --\--------------------------------------------------------------------------- on mStart_fly_to me, fly_to_period pFly_to_flag = 1 pFly_to_period = fly_to_period pFly_to_end_time = the milliseconds + fly_to_period end --/--------------------------------------------------------------------------- --| mFind_3D_members --| Get a list of all 3D members in the "models" castlib --\--------------------------------------------------------------------------- on mFind_3D_members me, this_mem rtn_lst = [] cnt = the number of members of castLib("models") repeat with i = 1 to cnt mem = member(i, "models") if mem.type = #shockwave3d then -- ignore the world member if mem <> this_mem then rtn_lst.add(mem.name) end if end if end repeat return rtn_lst end --/--------------------------------------------------------------------------- --| mIs3D --| Check that we have dropped this behaviour on a 3D member --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member if aScript.mIs3D(this_mem) then tList = [] tList = aScript.mFind_3D_members(this_mem, tList) if tList = [] then alert "you must import at least one model into the models cast" abort end if tGPDList[#pAdditional_mem] = \ [#comment:"Which 3D member?",\ #format: #string,\ #range: tList,\ #default: tList[1]] tGPDList[#pPosX] = \ [#comment:"Postion x",\ #format: #integer,\ #format: #integer,\ #default: 0] tGPDList[#pPosY] = \ [#comment:"Postion y",\ #format: #integer,\ #format: #integer,\ #default: 0] tGPDList[#pPosZ] = \ [#comment:"Postion z",\ #format: #integer,\ #format: #integer,\ #default: 0] tGPDList[#pScale] = \ [#comment:"Scale x 100",\ #format: #integer,\ #default: 100] tGPDList[#pTTTxt] = \ [#comment:"Tool tip text",\ #format: #string,\ #default: "a short descrition"] tGPDList[#pNodeID] = \ [#comment:"Node ID (0 means it's not a node)",\ #format: #integer,\ #default: 0] tGPDList[#pAutopilot_upto_dist] = \ [#comment:"If node, how close to autopilot to when clicked)",\ #format: #integer,\ #default: 50] tGPDList[#pSpeed] = \ [#comment:"Rotation speed - degrees per anim step x 10",\ #format: #integer,\ #default: 0] tGPDList[#pAxisRotation] = \ [#comment:"Which axis to rotate about",\ #format: #string,\ #range:["X", \ "Y", \ "Z"],\ #default: "Y"] tGPDList[#pRollover] = \ [#comment:"Face camera on rollover",\ #format: #boolean,\ #default: TRUE] tGPDList[#pRollup_duration] = \ [#comment:"Time taken for rollover animation (ms)",\ #format: #integer,\ #default: 1000] tGPDList[#pLodbias] = \ [#comment:"LOD bias",\ #format: #integer,\ #range:[#min:0, #max:100],\ #default: 30] end if return(tGPDList) end if end getPropertyDescriptionList additional model 3X2v2v,>Fn>richard rossCASt3B 34 2v2222222222222222222--model --picker --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| this behaviour should be dropped on the 3D world sprite if you want tool tips --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property pID property pTTTxt property pTT_mdl property pMP_mdl property pNodeID property pAutopilot_upto_dist property pRolling_flag property pFly_to_flag property pFly_to_period property pFly_to_end_time property pRollover property pAxisRotation property pRollup_duration property pInterpol_start_tm property pFacing_camera_transform property pInterpol_end_tm property pInterp_startTransform property pSpeed property pTTTxt_mn_flg property pServIntvl property pGrp_mdl on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #pickedModel -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) pSpr = sprite(me.spritenum) -- check that the node ID is an integer if not (pNodeID.ilk = #integer) then alert "node ID "&pNodeID&" in model picker behaviour for "&pTT_mdl"& is not an integer, please reenter it" me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if pMP_mdl = VOID end --/--------------------------------------------------------------------------- --| mInit --| Tell the cursor feedback object about this model and tooltip --\--------------------------------------------------------------------------- on mInit me pSpeed = float(pSpeed)/10 pServIntvl = 4 -- user definable pFly_to_flag = FALSE pRolling_flag = FALSE end --/--------------------------------------------------------------------------- --| mSetup --| the main world has been setup we can register ourself --\--------------------------------------------------------------------------- on mSetup me mbr = pSpr.member pMP_mdl = mbr.model(pTT_mdl) --pMP_mdl.debug = 1 -- are we deriving the TT name from the model name (double underscore marks the end of the name -- all other underscores will be taken to be space)? if pTTTxt_mn_flg then mdlnm = pMP_mdl.name emkr = "__" spc = "_" emkrpos = offset(emkr, mdlnm) if emkrpos then nm = mdlnm.char[1 .. emkrpos-1] -- now remove spaces repeat while nm contains spc if nm.char [1] = spc then nm = nm.char [2 .. nm.length] else if nm.char [nm.length] = spc then nm = nm.char [1 .. nm.length -1] else temp = nm sppos = offset(spc, temp) nm = temp.char [1 .. sppos-1] put " "&temp.char [sppos+1 .. temp.length] after nm end if end if end repeat pTTTxt = nm else -- name wrong - default to the model name pTTTxt = mdlnm end if end if -- hack to speed up dev. If the model name is listed in the node ID list, override whatever is entered as the node id -- hack me.mInit_default_nodes() group_name = "flg_m1_grp_"&pTT_mdl&string(me) pGrp_mdl = mbr.newGroup(group_name) -- in order for the tooltips -- make them children of the new group -- move the group to the user defined position and scale pGrp_mdl.transform = pMP_mdl.transform pGrp_mdl.addChild(pMP_mdl, #preserveWorld) --pGrp_mdl.pointAtOrientation = [vector(0.0000, 0.0000, 1.0000), vector(0.0000, 1.0000, 0.0000)] camerapos = mbr.camera[1].getworldTransform().position --pGrp_mdl.pointAt(camerapos, vector(0.0000, 1.0000, 0.0000)) pGrp_mdl.pointAt(mbr.camera[1]) pFacing_camera_transform = duplicate(pGrp_mdl.transform) gUI_control_obj.mSet_csr_fdbk(pGrp_mdl.name, me) end --/--------------------------------------------------------------------------- --| mInit_default_nodes --| very inefficient hack --\--------------------------------------------------------------------------- on mInit_default_nodes me id_txt = member ("node IDs").text lcnt = id_txt.line.count id_lst = [:] the itemdelimiter = ":" repeat with n = 1 to lcnt ln = id_txt.line[n] p = ln.item[1] v = value(ln.item[2]) if not voidP(v) then id_lst.addprop(p,v) else put "invalid ID at line "&n end if end repeat ID = id_lst.getAProp(pTTTxt) if not voidP(ID) then pID = ID else put "not auto ID for "&pTTTxt end if end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- on mService me -- start spinning the group as soo as it exists me.mAnimate() end --/--------------------------------------------------------------------------- --| mAnimate --| Do whatever type of animation is required --\--------------------------------------------------------------------------- on mAnimate me if not voidP(pMP_mdl) then if pRolling_flag then me.mRollover() else case pAxisRotation of "X": me.rotateX() "Y": me.rotateY() "Z": me.rotateZ() end case end if end if end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseWithin me if pRollover then -- prepare to start roating the model back towards the camera if pRolling_flag = FALSE then pRolling_flag = TRUE pInterpol_start_tm = the milliseconds pInterpol_end_tm = the milliseconds + pRollup_duration pInterp_startTransform = pGrp_mdl.transform end if end if end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseLeave me pRolling_flag = FALSE end --/--------------------------------------------------------------------------- --| mRollover --| Interplolate to the point at camera positon if we are not already there --\--------------------------------------------------------------------------- on mRollover me -- interpolate to the facing camera position if pRolling_flag = 1 then proportion = 1.0*(the milliseconds - pInterpol_start_tm)/float(pRollup_duration) if proportion > 1 then proportion = 1 -- flag so we know we have finished pRolling_flag = 2 end if tTransform = pInterp_startTransform.interpolate(pFacing_camera_transform, proportion) pGrp_mdl.transform = tTransform end if end --/--------------------------------------------------------------------------- --| rotateX --| Rotate on X axix --\--------------------------------------------------------------------------- on rotateX me, aModel pGrp_mdl.rotate(pSpeed,0,0) end --/--------------------------------------------------------------------------- --| rotateY --| Rotate on Y axix --\--------------------------------------------------------------------------- on rotateY me, aModel pGrp_mdl.rotate(0,pSpeed,0) end --/--------------------------------------------------------------------------- --| rotateZ --| Rotate on Z axix --\--------------------------------------------------------------------------- on rotateZ me, aModel pGrp_mdl.rotate(0,0,pSpeed) end --/--------------------------------------------------------------------------- --| mStart_fly_to --| Callback from camera control to say that the camera has just started zooming in --| it passes the fly to period so a model can make sure that it moves back to the correct orienation in time --\--------------------------------------------------------------------------- on mStart_fly_to me, fly_to_period pFly_to_flag = 1 pFly_to_period = fly_to_period pFly_to_end_time = the milliseconds + fly_to_period end --/--------------------------------------------------------------------------- --| mGetModels --| Get the names of the nodes that are in fact models --\--------------------------------------------------------------------------- on mGetModels me, aMember, aList repeat with j = member(aMember).model.count down to 1 if string(member(aMember).model[j]) contains "model" then -- make sure it's not an hitmdel or group pn = aMember.model[j].parent.name if aMember.model[j].parent.name = "World" then aList.add(aMember.model[j].name) end if end if end repeat return aList end --/--------------------------------------------------------------------------- --| mIs3D --| Check that aMember is a 3D member type --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member if aScript.mIs3D(this_mem) then tList = [] tList = aScript.mGetModels(this_mem, tList) tGPDList[#pTT_mdl] = \ [#comment:"Which model?",\ #format: #string,\ #range: tList,\ #default: tList[1]] tGPDList[#pTTTxt] = \ [#comment:"Tool tip text",\ #format: #string,\ #default: "a short description"] tGPDList[#pTTTxt_mn_flg] = \ [#comment:"Use model name for tool tip text",\ #format: #boolean,\ #default: 1] tGPDList[#pNodeID] = \ [#comment:"Node ID (0 means it's not a node)",\ #format: #integer,\ #default: 69] tGPDList[#pAutopilot_upto_dist] = \ [#comment:"If node, how close to autopilot to when clicked)",\ #format: #integer,\ #range:[#min:0, #max:500],\ #default: 50] tGPDList[#pSpeed] = \ [#comment:"Rotation speed - degrees per anim step x 10",\ #format: #integer,\ #default: 10] tGPDList[#pAxisRotation] = \ [#comment:"Which axis to rotate about",\ #format: #string,\ #range:["X", \ "Y", \ "Z"],\ #default: "Y"] tGPDList[#pRollover] = \ [#comment:"Face camera on rollover",\ #format: #boolean,\ #default: TRUE] tGPDList[#pRollup_duration] = \ [#comment:"Time taken for rollover animation (ms)",\ #format: #integer,\ #default: 500] end if return(tGPDList) end if end getPropertyDescriptionList model picker behaviourZN,>Fn>richard rossCASt%%)m1 4 nav arrows><>richard rossPZa-0 CASt,,0m1 4 nav arrows hilite><>richard rossPZa-0 CASt))==========AERnav button hot areasKQq-=r>richard rossT@CASt7! 7 6O6l6l6l6l666666666666666--button --nav --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| READ ME --| This behavior uses a field member to define the "hot areas of the button - "nav button hot areas" --| If you change the graphic for the button you will have to put new values into this member. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property pID property pUp_member_name property pDown_member_name property pUp_member property pDown_member property pBaseIm property pRollIm property pCurrentIm property pClicked_state property pMain_nav_control_obj property pHotspots_field_name property pHot_rect_list on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #btnnav -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() -- init behaviour specic items if pUp_member_name <> "no nav button required in this space" then pUp_member = member pUp_member_name -- user definable pDown_member = member (pDown_member_name) -- user definable me.mInit() else -- no arrows pHot_rect_list = [:] end if end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if if not voidP(pBaseIm) then pSpr.member.image = pBaseIm end if -- tidy up stored images pBaseIm = VOID pRollIm = VOID pCurrentIm = VOID pMain_nav_control_obj = VOID end --/--------------------------------------------------------------------------- --| incase the behaviour is applied on the fly --\--------------------------------------------------------------------------- on mDestroy me me.endsprite() end --/--------------------------------------------------------------------------- --| find out height so that the bottom bar can be sized correctly --\--------------------------------------------------------------------------- on mGet_dims me, aList if pUp_member_name <> "no nav button required in this space" then aList.addProp(pID, [pSpr.width, pSpr.height]) end if end --/--------------------------------------------------------------------------- --| mRelocate_UI --| place UI element at the right place relative to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list myRect = UI_rects_list.getAProp(pID) pSpr.rect = myRect end --/--------------------------------------------------------------------------- --| mInit --| store images of up member and down member --| and get the clickable areas --\--------------------------------------------------------------------------- on mInit me -- set the sprite member to the one selected pSpr.member = member(pUp_member) -- store images pBaseIm = duplicate(member (pUp_member).image) pRollIm = duplicate(member (pDown_member).image) pCurrentIm = duplicate(pBaseIm) if pHotspots_field_name = "no nav button required in this space" then alert "you have specified no nav hot spots - please look at the parameters on the nav arrow sprite's behavior" abort end if me.mAssign_hot_areas() pClicked_state = 0 end --/--------------------------------------------------------------------------- --| mSet_main_nav_control_obj --| Ref to main nav control is passed in --\--------------------------------------------------------------------------- on mSet_main_nav_control_obj me, inst pMain_nav_control_obj = inst -- pass the nav control a list of allowable nav directions based on the hotspot list direction_lst = [] cnt = pHot_rect_list.count repeat with n = 1 to cnt ttype = pHot_rect_list.getPropAt(n) direction_lst.add(ttype) end repeat pMain_nav_control_obj.mEnable_directions(direction_lst) end --- on mousewithin me relLoc = the mouseloc - point(pSpr.left, pSpr.top) me.mCheck_rollover(relLoc) end --- on mouseleave me relLoc = the mouseloc - point(pSpr.left, pSpr.top) me.mCheck_rollover(relLoc) end --- on mousedown me relLoc = the mouseloc - point(pSpr.left, pSpr.top) me.mCheck_mouseClick(relLoc) end --/--------------------------------------------------------------------------- --| mAssign_hot_areas --| The hot areas are stored in the "nav button hot areas" field member. --| This is in a line format for ease of editing - convert to list. --\--------------------------------------------------------------------------- on mAssign_hot_areas me data = member (pHotspots_field_name) hot_rect_list_str = "[" cnt = data.line.count repeat with n = 1 to cnt ln = data.line[n] if ln.char[1] <> "#" then alert "problem with line "&n&" of nav button hot areas member" put ln after hot_rect_list_str if n < cnt then put ", " after hot_rect_list_str end repeat put "]" after hot_rect_list_str pHot_rect_list = value(hot_rect_list_str) if not listP(pHot_rect_list) then alert "pHot_rect_list is not a list - problem with nav button hot areas member" sort pHot_rect_list end --/--------------------------------------------------------------------------- --| mArrow_key_release --| Allows feedback from keyboard nav so that releasing the arrow keys shows the button up state. --\--------------------------------------------------------------------------- on mArrow_key_release me, button_List -- make sure everything in the button_List is in it's up state cnt = button_List.count repeat with n = 1 to cnt but = button_List[n] but_rect = pHot_rect_list.getAProp(but) -- make sure that there is a button corresponding to the key if listP(but_rect) then copyRect = but_rect pCurrentIm.copyPixels(pBaseIm, copyRect, copyRect) end if end repeat if pHot_rect_list.count then pSpr.member.image = pCurrentIm end if end --/--------------------------------------------------------------------------- --| mArrow_key_pressed --| Allows feedback from keyboard nav so that pressing the arrow keys shows the button down state. --\--------------------------------------------------------------------------- on mArrow_key_pressed me, button_List -- make the button eqiivalent to the key pressed in the down stae -- make sure everything in the button_List is in it's up state cnt = button_List.count repeat with n = 1 to cnt but = button_List[n] but_rect = pHot_rect_list.getAProp(but) if listP(but_rect) then copyRect = but_rect pCurrentIm.copyPixels(pRollIm, copyRect, copyRect) end if end repeat if pHot_rect_list.count then pSpr.member.image = pCurrentIm end if end --/--------------------------------------------------------------------------- --| mCheck_rollover --| Checks for rollovers in a hot area. --\--------------------------------------------------------------------------- on mCheck_rollover me, loc -- make sure the arrow is in the upstate if the mouse is up if not(the mouseDown) and pClicked_state then me.mChange(#down) end if -- check for rollovers cnt = pHot_rect_list.count hit = #no repeat with n = 1 to cnt checkRect = pHot_rect_list[n] if inside(loc, pHot_rect_list[n]) then hit = pHot_rect_list.getPropAt(n) exit repeat end if end repeat if hit = #no then cursor -1 else cursor 280 end if end --/--------------------------------------------------------------------------- --| mCheck_rollover --| Checks for mouseclicks in a hot area. --\--------------------------------------------------------------------------- on mCheck_mouseClick me, loc -- check for hit cnt = pHot_rect_list.count hit = #no repeat with n = 1 to cnt checkRect = pHot_rect_list[n] if inside(loc, pHot_rect_list[n]) then hit = pHot_rect_list.getPropAt(n) exit repeat end if end repeat if hit = #no then else -- set flag in arrow control object to make it do the equivalent to whatever button we're clicking. me.mChange(#up, checkRect) pMain_nav_control_obj.mArrow_button_clicked(hit) end if end --/--------------------------------------------------------------------------- --| mChange --| Show up or down state. --\--------------------------------------------------------------------------- on mChange me, upDown, hitrect if upDown = #up then pClicked_state = 1 pCurrentIm = duplicate(pBaseIm) copyRect = hitrect pCurrentIm.copyPixels(pRollIm, copyRect, copyRect) else pClicked_state = 0 pCurrentIm = duplicate(pBaseIm) end if pSpr.member.image = pCurrentIm end --- on mFind_button_nav_control_behaviour me, aList aList.add( me ) end --- on mGet_offset me return (15 + pBaseIm.width) end --/--------------------------------------------------------------------------- --| mFind_usable_member --| Get a list of all members of the same type as the passed member in the internal and world mgr castlib --\--------------------------------------------------------------------------- on mFind_usable_member me, this_mem, tType, rtn_lst cnt = the number of members of castLib(1) repeat with i = 1 to cnt mem = member(i, 1) if mem.type = tType then rtn_lst.add(mem.name) end if end repeat cnt = the number of members of castLib("worldMgr") repeat with i = 1 to cnt mem = member(i, "worldMgr") if mem.type = tType then rtn_lst.add(mem.name) end if end repeat end --/--------------------------------------------------------------------------- --| mValidate_hot_area --| Remove all not hot areas fields --\--------------------------------------------------------------------------- on mValidate_hot_area me, aList killlst = [] cnt = aList.count repeat with m = 1 to cnt data = member(aList[m]).text lcnt = data.line.count if lcnt > 4 then -- too many lines killlst.add(aList[m]) else repeat with l = 1 to lcnt -- check each line ln = data.line[l] if ln.char[1] <> "#" then killlst.add(aList[m]) exit repeat end if if not (ln contains "rect") then killlst.add(aList[m]) exit repeat end if end repeat end if end repeat -- now remove the entries collected int he kill list repeat with n = killlst.count down to 1 tokill = killlst[n] pos = aList.findPos(tokill) if pos then aList.deleteAt(pos) else alert "lost pos button nav control behaviour" end if end repeat end --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member tType = #bitmap upnm = this_mem.name downnm = upnm&&"hilite" tList = ["no nav button required in this space"] aScript.mFind_usable_member(this_mem, tType, tList) tGPDList[#pUp_member_name] = \ [#comment:"Which navigation arrows member?",\ #format: #string,\ #range: tList,\ #default: upnm] tGPDList[#pDown_member_name] = \ [#comment:"Which navigation arrows hilite member?",\ #format: #string,\ #range: tList,\ #default: downnm] tList1 = [] tType = #field aScript.mFind_usable_member(this_mem, tType, tList1) aScript.mValidate_hot_area(tList1) tList1.add("no nav button required in this space") tGPDList[#pHotspots_field_name] = \ [#comment:"Which navigation arrows hilite member?",\ #format: #string,\ #range: tList1,\ #default: tList1[1]] end if return(tGPDList) end getPropertyDescriptionListbutton nav control behaviourv,>Fn>richard rossCASt%%)m1 2 nav arrows><>richard rossPa 0 CASt,,0m1 2 nav arrows hilite><>richard rossPa60 CASt22222222226:Gnav button hot areas 2 arrows4QB66=r>richard ross* CASt$$(mo help button=n>>richard rossPPT< * CAStz l --help --button --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property pID property pHelp_url property pShow_hlp_name on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #helpbtn -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --- --- overload ancestor --on mSetCurs me -- --end --- on mouseEnter me cursor 280 end mouseEnter --- on mouseleave me cursor -1 end --/--------------------------------------------------------------------------- --| mousedown --| The win manager opens a help web page in it's own window using the url defined for this page --\--------------------------------------------------------------------------- on mousedown me if goWinMgr.ilk = #instance then goWinMgr.mLaunchHelp( pHelp_url ) end if end --/--------------------------------------------------------------------------- --| mGet_dims --| find out height so that the bottom bar can be sized correctly --\--------------------------------------------------------------------------- on mGet_dims me, aList if pShow_hlp_name <> "no help required in this space" then aList.addProp(pID, [pSpr.width, pSpr.height]) end if end --/--------------------------------------------------------------------------- --| mRelocate_UI --| place UI element at the right place relative to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list if goWinMgr.ilk = #instance then myRect = UI_rects_list.getAProp(pID) pSpr.rect = myRect end if end --/--------------------------------------------------------------------------- --| mFind_usable_member --| find members of this type in castlib 1 or the wrldmgr --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mFind_usable_member me, this_mem, tType, rtn_lst cnt = the number of members of castLib(1) repeat with i = 1 to cnt mem = member(i, 1) if mem.type = tType then rtn_lst.add(mem.name) end if end repeat cnt = the number of members of castLib("worldMgr") repeat with i = 1 to cnt mem = member(i, "worldMgr") if mem.type = tType then rtn_lst.add(mem.name) end if end repeat end ------- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] tGPDList[#pHelp_url] = \ [#comment:"Help screen url?",\ #format: #string,\ #default: "http://www....."] this_mem = sprite(the currentSpriteNum).member tType = #bitmap show_hlp = this_mem.name tList = ["no help required in this space"] aScript.mFind_usable_member(this_mem, tType, tList) tGPDList[#pShow_hlp_name] = \ [#comment:"Which show help member?",\ #format: #string,\ #range: tList,\ #default: show_hlp] return(tGPDList) end if end getPropertyDescriptionList help button control behaviour07%7%,>Fn>richard rossCASt # show info=o]>richard rossPDQ< * CASt # hide info=p>richard rossPDQ * CASt< . i --info --button --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gSolar_system property ancestor, spritenum property pSpr property pID property iClickframe global gfrmtime global gStop on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #infobtn -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --- --- overload ancestor on mSetCurs me end --- on mouseEnter me cursor 280 end mouseEnter --- on mouseleave me cursor -1 end --- on mouseDown me, loc if pSpr.member.name = "hide info" then gUI_control_obj.mHide_widgets() else -- make sure tooltips are hidden if objectP(gSolar_system) then gSolar_system.mHide_tool_tips() end if gUI_control_obj.mShow_widgets() end if end -- on mChange_state me, mbr_name pSpr.member = member(mbr_name) end --/--------------------------------------------------------------------------- --| find out height so that the bottom bar can be sized correctly --\--------------------------------------------------------------------------- on mGet_dims me, aList aList.addProp(pID, [pSpr.width, pSpr.height]) end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list if goWinMgr.ilk = #instance then myRect = UI_rects_list.getAProp(pID) pSpr.rect = myRect end if endinfo button control behaviour _,>Fn>richard rossCASt##' tool tip back=>richard rossP-  CAStd!%2tt text>п mText='>richard rosstextg3TEXd2??NoTextureCASt '-- cst -- fdbk --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This object handlers the cursor changes when you roll over a node and --| the tooltips when rolling over anything that has had tool tips attached. --\--------------------------------------------------------------------------- property p3DSpr property p3DMember property pSptLT property pSpr_rect property pFDBck_data_lst property pTT_object property pServIntvl property pLast_mouse_pos property pLast_roll_obj global gUI_control_obj global gDBG --/--------------------------------------------------------------------------- --| Constructor --| Destructor --\--------------------------------------------------------------------------- on new me pServIntvl = 20 pFDBck_data_lst = [:] sort pFDBck_data_lst pLast_mouse_pos = the mouseloc return me end --/--------------------------------------------------------------------------- --| mDestroy --| Destructor --\--------------------------------------------------------------------------- on mDestroy me -- clean pFDBck_data_lst if listP(pFDBck_data_lst) then cnt = pFDBck_data_lst.count repeat with n = 1 to cnt pFDBck_data_lst[n] = VOID end repeat pFDBck_data_lst = VOID end if if objectP(pTT_object) then pTT_object.mDestroy() pTT_object = VOID end if end --/--------------------------------------------------------------------------- --| mInit --| Set up the tooltip control object --\--------------------------------------------------------------------------- on mInit me, tDSpr p3DSpr = sprite(tDSpr) p3DMember = p3DSpr.member if not (pTT_object.ilk = #instance) then pTT_object = script("tool tip control object").new(p3DSpr) else pTT_object.mReinit() end if pSptLT = point(p3DSpr.left, p3DSpr.top) pSpr_rect = p3DSpr.rect end --/--------------------------------------------------------------------------- --| mAdd_to_fdbk_data --| Models register their feedback data to be displayed --\--------------------------------------------------------------------------- on mAdd_to_fdbk_data me, model, data -- check that we are not adding more than one tooltip to the same model pos = pFDBck_data_lst.findpos(model) if voidP(pos) then pFDBck_data_lst.addProp(model, data) else alert "you are adding more than one tooltip to the same model"&string(model) end if end --/--------------------------------------------------------------------------- --| mCheck_mse_click --| If we click on a model and it is a node then we must --| fly to that model and then do the node jump --\--------------------------------------------------------------------------- on mCheck_mse_click me relloc = the mouseloc - pSptLT clicked_model = me.mCheck_over_mdl(relloc) nodeID = 0 if clicked_model <> 0 then -- if there is a node assocated with this model then we must interploate to it cl_m_name = clicked_model.name inst = pFDBck_data_lst.getAProp(cl_m_name) if objectP(inst) then nodeID = inst.getAProp(#pNodeID) if voidP(nodeID) then nodeID = 0 end if end if -- check for interpolation if nodeID then gUI_control_obj.mFly_camera(clicked_model, 1, inst) end if end --/--------------------------------------------------------------------------- --| mService --| This is the main thread that does the checking if the rolled model --\--------------------------------------------------------------------------- on mService me if voidP(pSpr_rect) then exit -- don't do tooltips if we are on autopilot if gUI_control_obj.pAuto_pilot then exit --only check if the mouse is inside the sprite rect if not inside(the mouseloc, pSpr_rect) then exit relloc = the mouseloc - pSptLT rolled_model = me.mCheck_over_mdl(relloc) nodeID = 0 TTtxt = "" if rolled_model <> 0 then if gDBG then put "rolled_model is "&rolled_model -- if there is a node assocated with this model then show a finger cursor rl_m_name = rolled_model.name inst = pFDBck_data_lst.getAProp(rl_m_name) --inst = pFDBck_data_lst.getAProp(rolled_model) if not voidP(inst) then nodeID = inst.getAProp(#pNodeID) if voidP(nodeID) then nodeID = 0 TTtxt = inst.getAProp(#pTTTxt) if voidP(TTtxt) then TTtxt = "" -- tell the behaviour that there is a mousewithin inst.mMouseWithin() pLast_roll_obj = inst else -- tell the last rolled behaviour instance that we have rolled off if objectP(pLast_roll_obj) then pLast_roll_obj.mMouseLeave() pLast_roll_obj = VOID end if end if end if -- set the cursor accordingly if nodeID then put "cursor feedback object roll" cursor 280 else cursor -1 end if -- show or hide tooltips if TTtxt <> "" then pTT_object.mShow_tooltip (TTtxt, relloc) pLast_mouse_pos = the mouseloc else if the mouseloc = pLast_mouse_pos then pTT_object.mHide_tooltip (#pause) else pTT_object.mHide_tooltip (#nopause) end if end if end --/--------------------------------------------------------------------------- --| mCheck_roll_mdl --| Check if relloc is over model. If we hit an imported model --| we need to return the group name --\--------------------------------------------------------------------------- on mCheck_over_mdl me, relloc if voidP(p3DMember) then exit hitmodel = member(p3DMember).camera[1].modelUnderLoc(relloc) -- first check to see if it is an image on a plane. -- If we have hit transparency we need to check for models underneath -- additional models and model picker models are all part of groups with names -- starting with "flg_m1_grp". Step up the parent tree to see if the hit model is one of these. -- this saves the feedback list having to contain hundres of entries (with might be faster, untested) if not voidP(hitmodel) then nm = hitmodel.name mdl = hitmodel repeat while nm <> "World" if nm.char[1..10] = "flg_m1_grp" then return mdl end if l = nm.length if nm.char[l-9 ..l] = "tilt group" then return mdl mdl = member(p3DMember).model(nm).parent nm = member(p3DMember).model(nm).parent.name end repeat return hitmodel end if return 0 end cursor feedback objectna,>Fn>richard rossCAStI ;|property p3DMember property pHotRect property pTexture_name property pTexture_ref property pCurrent_TTText property pOverlayNum property pTT_Offset property pTT_RHS_Offset property pTT_width property pTT_height property pShowing_TT property pLast_loc property pTT_Text_offsetH property pTT_Text_offsetV property pTT_mbr_im property pStayUp_period property pStayUp_time property pLast_mouseloc property pCheck_rct property pCam1 on new me, spr p3DMember = spr.member pCam1 = p3DMember.camera[1] pCheck_rct = pCam1.rect me.mInit() return me end ---- on mDestroy me pCam1.removeBackdrop(1) -- clear the texture p3DMember.deleteTexture(pTexture_name) pTexture_ref = VOID pTT_mbr_im = VOID end --- on mInit me -- grab an overlay and render a dummy tooltip into it pTT_mbr = "tool tip back" pTT_mbr_im = member(pTT_mbr).image -- this dictates how big the start and end of the TT are pTT_Text_offsetH = 10 pTT_Text_offsetV = 5 pStayUp_period = 1*60 pStayUp_time = 0 pLast_mouseloc = the mouseloc pTT_width = member (pTT_mbr).width pTT_height = member (pTT_mbr).height pCurrent_TTText = "" pShowing_TT = 0 pLast_loc = point(-999, -999) im = member (pTT_mbr).image pTexture_name = "ss Tool tip texture" pTexture_ref = p3DMember.newtexture(pTexture_name,#fromImageObject, im) pTexture_ref.quality = #low -- create a new overlay using this texture -- put it off screen loc = point(-999, -999) pCam1.addOverlay(pTexture_ref, loc, 0) pOverlayNum = pCam1.overlay.count pTT_Offset = point(0, member(pTT_mbr).height) + point (-4, 2) pTT_RHS_Offset = point(member(pTT_mbr).width, member(pTT_mbr).height) + point (-4, 2) pTT_TOP_Offset = point(member(pTT_mbr).width, member(pTT_mbr).height) + point (-4, 2) end --- on mReinit me pCheck_rct = pCam1.rect end --- on mShow_tooltip me, text, loc pStayUp_time = pStayUp_period + the timer pLast_mouseloc = the mouseloc -- create the tooltip image and put this into the image if necessary if text <> pCurrent_TTText then pCurrent_TTText = text -- create new ttip image current_im = me.mCreate_new_TT() pTexture_ref.image = current_im pTT_width = current_im.width me.mMove_TT() end if if loc <> pLast_loc then pLast_loc = loc me.mMove_TT() end if -- make sure the TT linger for 3 seconds after the rollover has finished or if the mouse moves end --- on mMove_TT me -- place it at the passed loc -- make sure it does not go off the RHS limitH = pCheck_rct[3] - pTT_width if pLast_loc[1] > limitH then cor_H = -1*pTT_width else cor_H = 4 end if limitV = pCheck_rct[2] + pTT_height if pLast_loc[2] < limitV then cor_V = 2 else cor_V = -1*pTT_height -2 end if tt_loc = pLast_loc + point(cor_H, cor_V) pCam1.overlay[pOverlayNum].loc = tt_loc pShowing_TT = 1 end --- on mCreate_new_TT me -- create new ttip image member ("tt text").text = pCurrent_TTText -- create the background lastchar = pCurrent_TTText.length end_pont = charPosToLoc(member ("tt text"), lastchar+1) text_len = end_pont[1] TT_len = pTT_Text_offsetH + text_len + pTT_Text_offsetH -- smear a slice from the centre of the template all across this image source_rect = rect(pTT_Text_offsetH, 0, pTT_Text_offsetH+1, pTT_height) im = image(TT_len, pTT_height, 16) im.copyPixels(pTT_mbr_im, im.rect, source_rect) -- put the front and back in target_rect = rect(0, 0, pTT_Text_offsetH, pTT_height) im.copyPixels(pTT_mbr_im, target_rect, target_rect) target_rect = rect(TT_len - pTT_Text_offsetH, 0, TT_len, pTT_height) w = pTT_mbr_im.width source_rect = rect(w - pTT_Text_offsetH, 0, w, pTT_height) im.copyPixels(pTT_mbr_im, target_rect, source_rect) -- add the text text_im = member ("tt text").image text_rect = rect(0,0,text_len, text_im.height) offset = point(pTT_Text_offsetH, pTT_Text_offsetV) im.copyPixels (text_im, text_rect + rect(offset, offset), text_rect, [#color: rgb(0,0,0)]) return im end --- on mHide_tooltip me, pauseFlag -- don't hide if the cursor has not moved for the timeout period if pauseFlag = #pause then if the timer < pStayUp_time then -- if the mouseloc = pLast_mouseloc then exit --end if end if end if if pShowing_TT = 1 then pShowing_TT = 0 pLast_loc = point(-999, -999) pCam1.overlay[pOverlayNum].loc = point(-99999, -99999) end if end tool tip control object&3q||,>Fn>richard rossCASt&++;;;;;?CPloading world message>п mText=>richard rosstext3TEXd2??NoTextureCASt&++;;;;;?CPtesting speed message>п mText=>richard rosstext3TEXd2??NoTextureCAStR D--message --align --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global gUI_control_obj on beginsprite me spr = sprite(me.spritenum) --position the sprite along the bottom of the browser frame at the centre b_rect = gUI_control_obj.pBrowser_frame_rect centre = b_rect[1] + (b_rect[3] - b_rect[1])/2 l = centre - spr.member.width/2 t = b_rect[4] - spr.member.height*2 spr.loc = point(l,t) end message align}1Z,>Fn>richard rossCASt1p 1b00000000000000000000--scrolling --background --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour allows the user to add additional models to the world --| They can define the positon and scale of the model within the world --| They can also define some behaviour. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gDBG global gUtils_obj property ancestor, spritenum property pSpr property pID property pMbr property pPano_mem property pPano_source property pBackdrop_im property pBD_tile_v property pBD_tile_h property ptexture_dim property pTestureList property pBackdrop_cnt property pBackdrop_im_w property pDegree_amt property pRot on beginSprite me --/--------------------------------------------------------------------------- -- |the backdrop is used instead of a skybox. It uses n backdrops that use --| pBD_tile_v x pBD_tile_h different textures. These textures are set to chunks of the --| stary sky image via imaging lingo. As the camera is rotated the --| image chunks are grabbed from offset differnt chunks of the big image and the textures are updated --| so giving scrolling. --| Please note that this is not included in any speed tests as initial tests showed almost negligable performace hits with it. --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #scrlback -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mRegister() end --- on mInit me, spr_rect -- if they have been set up before we must clear the old ones if listP(pTestureList) then me.mDestroy() end if pSpr = sprite(me.spritenum) if voidP(spr_rect) then spr_rect = pSpr.rect pMbr = pSpr.member --pMbr.resetWorld() pPano_source = pPano_mem.image im = me.get_current_im_chunk() pano_w = im.width pDegree_amt = 1.0*pano_w/360 pRot = 0 texture_dim = 256 me.mInit_bac(im, texture_dim, spr_rect) end --- --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if me.mDestroy() end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- -- --on mService me -- -- -- start spinning the group as soo as it exists -- -- me.mAnimate() -- --end -- --- --on enterframe me -- -- if keypressed(123) then -- me.mUpdate_backdrop(1) -- else -- if keypressed(124) then -- me.mUpdate_backdrop(-1) -- end if -- end if -- --end -- --- on get_current_im_chunk me -- make an image with the same height as the 3D sprite height but with the width of the original. Take it from the centre. new_height = pSpr.height t = (pPano_source.height - new_height)/2 b = t + new_height w = pPano_source.width -- just incase of huge monitors or small panos if t < 0 then t = 0 b = pPano_source.height w = integer(w*(1.0*new_height/b)) end if -- just in case it's not wide enough if w < pSpr.width then im = image(w*2, new_height, 16) im.copyPixels(pPano_source, rect(0,0,w,new_height), rect(0, t, pPano_source.width, b)) im.copyPixels(pPano_source, rect(w,0,w*2,new_height), rect(0, t, pPano_source.width, b)) else im = image(w, new_height, 16) im.copyPixels(pPano_source, im.rect, rect(0, t, pPano_source.width, b)) end if put "xxxxxx must redo the backdrops after the speed test" return im end --- on mDestroy me -- clear the backdrop models if listP(pTestureList) then cnt = pTestureList.count repeat with n = cnt down to 1 pMbr.camera[1].removeBackdrop(n) end repeat -- clear the textures that were used repeat with n = 1 to cnt the_texture = pTestureList.getPropAt(n) pMbr.deleteTexture(the_texture) end repeat end if pBackdrop_im = VOID gUtils_obj.mClean_list(pTestureList) pTestureList = VOID end --- on mInit_bac me, im, texture_dim, cam_rect pBackdrop_im = im ptexture_dim = texture_dim -- work out how many textures / backgrounds are required. pBD_tile_h = cam_rect.width/ptexture_dim if cam_rect.width mod ptexture_dim then pBD_tile_h = pBD_tile_h + 1 -- to do the shuffling we need an extra one in the row pBD_tile_h = pBD_tile_h + 1 pBD_tile_v = cam_rect.height/ptexture_dim if cam_rect.height mod ptexture_dim then pBD_tile_v = pBD_tile_v + 1 cnt = 1 pTestureList = [:] repeat with h = 1 to pBD_tile_h repeat with v = 1 to pBD_tile_v the_texture = "h"&h&", v"&v destRect_or_quad = rect(0, 0, ptexture_dim, ptexture_dim) sourceRect = ptexture_dim*rect( h-1, v-1, h, v) im = image(ptexture_dim, ptexture_dim, 8) im.copyPixels(pBackdrop_im, destRect_or_quad, sourceRect) texture_ref = pMbr.newtexture(the_texture,#fromImageObject, im) texture_ref.quality = #low -- create a new backdrop using this texture loc = ptexture_dim*point(h-1, v-1) pMbr.camera[1].addBackdrop(texture_ref, loc, 0) data = [:] data.addProp(#the_im, im) data.addProp(#the_rect, sourceRect) data.addProp(#the_loc, loc) pTestureList.addProp(the_texture, data) cnt = cnt + 1 end repeat end repeat pBackdrop_cnt = pMbr.camera[1].backdrop.count pBackdrop_im_w = pBackdrop_im.width end --- on mUpdate_backdrop me, amt_deg amt = integer(pDegree_amt*amt_deg)*2 cnt = 1 --- shuffle the loc of the backdrops along repeat with h = 1 to pBD_tile_h repeat with v = 1 to pBD_tile_v the_texture = "h"&h&", v"&v data = pTestureList.getAProp(the_texture) oldloc = data.the_loc newloc = oldloc + point(amt, 0) if amt > 0 then -- moving right c_rect = pMbr.camera[1].rect right_edge = c_rect.width if newloc[1] > right_edge then -- the texture has gone off camera to the rhs newloc = point(newloc[1] - pBD_tile_h*ptexture_dim , newloc[2]) -- change the texture to the next one along the sky strip me.mUpdate_texture(h, v, #right) end if else -- moving left -- has the texture gone off camera to the lhs if newloc[1] < -1*ptexture_dim then newloc = point(pBD_tile_h*ptexture_dim + newloc[1], newloc[2]) -- change the texture to the next one along the sky strip me.mUpdate_texture(h, v, #left) end if end if pMbr.camera[1].backdrop[cnt].loc = newloc data.the_loc = newloc cnt = cnt + 1 end repeat end repeat end ---- on mUpdate_texture me, h, v, direction -- update the texture of the backdrop to the next chunk along the strip if direction = #left then source_jmp_amt = ptexture_dim*pBD_tile_h else source_jmp_amt = -1*ptexture_dim*pBD_tile_h end if the_texture = "h"&h&", v"&v data = pTestureList.getAProp(the_texture) old_sourceRect = data.the_rect im = data.the_im destRect_or_quad = rect(0, 0, ptexture_dim, ptexture_dim) new_sourceRect = old_sourceRect + rect(point(source_jmp_amt, 0), point(source_jmp_amt, 0)) -- now check for going over the edge by an entire textures worth if new_sourceRect[3] > pBackdrop_im_w then -- do we need to nibble a bit from each end or do we totally wrap around? if new_sourceRect[1] >= pBackdrop_im_w then -- no nibble -- wrap around and start fromthe beginning new_sourceRect = rect(new_sourceRect[1]- pBackdrop_im_w, old_sourceRect[2], new_sourceRect[3] - pBackdrop_im_w , old_sourceRect[4]) im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) pMbr.texture(the_texture).image = im else -- nibble -- end bit im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) -- front bit nibble_len = new_sourceRect[3] - pBackdrop_im_w front_nibble_source = rect(0, new_sourceRect[2], nibble_len, new_sourceRect[4]) nibble_dest = rect(ptexture_dim - nibble_len,0, ptexture_dim, ptexture_dim) im.copyPixels(pBackdrop_im, nibble_dest, front_nibble_source) pMbr.texture(the_texture).image = im end if else if new_sourceRect[1] < 0 then -- test for nibble if new_sourceRect[3] <= 0 then -- no nibble. Just show the start -- wrap back and start from the end new_sourceRect = rect(pBackdrop_im_w + new_sourceRect[1], old_sourceRect[2], pBackdrop_im_w + new_sourceRect[3] , old_sourceRect[4]) im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) pMbr.texture(the_texture).image = im else -- nibble -- end bit im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) -- front bit nibble_len = -1*new_sourceRect[1] front_nibble_source = rect(pBackdrop_im_w - nibble_len, new_sourceRect[2], pBackdrop_im_w, new_sourceRect[4]) nibble_dest = rect(0,0, nibble_len, ptexture_dim) im.copyPixels(pBackdrop_im, nibble_dest, front_nibble_source) pMbr.texture(the_texture).image = im end if else -- no adjustment required im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) pMbr.texture(the_texture).image = im end if end if -- update the stored rect data.the_rect = new_sourceRect end --- --/--------------------------------------------------------------------------- --| mFind_graphics --| Get a list of all 3D members in the "models" castlib --\--------------------------------------------------------------------------- on mFind_graphics me rtn_lst = [] ccnt = the number of castlibs repeat with c = 1 to ccnt cnt = the number of members of castLib(c) repeat with i = 1 to cnt mem = member(i, "models") if mem.type = #bitmap then rtn_lst.add(mem.name) end if end repeat end repeat return rtn_lst end --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] tList = aScript.mFind_graphics(tList) tGPDList[#pPano_mem] = \ [#comment:"Which pano graphic?",\ #format: #graphic,\ #default: member "pano"] return(tGPDList) end if end getPropertyDescriptionList scrolling background0,>Fn>richard rossCASt m _ property pThe_last_channel property pStart_vol_spts property pEnd_vol_spts on new me pThe_last_channel = the lastChannel pStart_vol_spts = 1 pEnd_vol_spts = 1 return me end --- on mDestroy me end --- on mClean_list me, the_list if not listP(the_list) then exit -- this is used to clear out a list - it's a good thing to do to avoid memory leaks -- step through all the list entries and wipe out any lists within lists cnt = the_list.count repeat with n = 1 to cnt entry = the_list[n] if ilk(entry) = #list or ilk(entry) = #proplist then -- if it's a list, recursively clean it me.mClean_list(the_list[n]) else -- if it's an object, then destroy it if ilk(entry) = #object then the_list[n].mDestroy() end if end if the_list[n] = VOID end repeat the_list = VOID end --- on mGet_next_free_sprite me -- find the next unused sprite repeat with thisSprite = pStart_vol_spts to pThe_last_channel if not sprite(thisSprite).membernum then puppetSprite thisSprite, TRUE if thisSprite > pEnd_vol_spts then pEnd_vol_spts = thisSprite end if return thisSprite end if end repeat alert "out of sprites" end --- on mClear_sprites me -- run through all used sprites, destroy their behaviours then kill the sprite repeat with spt = pStart_vol_spts to pEnd_vol_spts me.mClear_spr(spt) end repeat pEnd_vol_spts = pStart_vol_spts end --- on mClear_spr_list me, spr_list -- run through all used sprites in a list, destroy their behaviours then kill the sprite sort spr_list cnt = spr_list.count if cnt then repeat with n = cnt down to 1 spt = spr_list[n] me.mClear_spr(spt) if spt >= pEnd_vol_spts then pEnd_vol_spts = spt - 1 end repeat end if end --- on mClear_spr me, spt -- return all the sprite propertis to the defaults sptObj = sprite(spt) if sptObj.membernum then sptObj.ink = 0 sptObj.locH = -10000 -- offstage sptObj.locZ = spt sptObj.blend = 100 sptObj.stretch = FALSE sptObj.forecolor = 255 sptObj.backcolor = 0 sptObj.member = 0 -- clear behavior list bLst = sptObj.scriptinstancelist bCnt = bLst.count repeat with i=1 to bCnt -- make sure any objects in the behaviours are wiped out bLst[i].mDestroy() bLst[i] = 0 end repeat sptObj.scriptinstancelist = [] puppetSprite(spt,FALSE) end if end --- on mGetEmptySlot me, the_castlib, nextpos -- return the next empty slot in a particular castlib if voidP(nextpos) then nextpos = 1 if voidP(the_castlib) then the_castlib = 1 repeat while true if the type of member nextpos of castlib the_castlib = #empty then return nextpos nextpos = nextpos + 1 end repeat end --- utils|0N,>Fn>richard rossCASt  $ screengrab=@>richard rossP%CASt             $(5--screen --grab --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr, glProps -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global goNetMgr property ancestor, spritenum property pSpr property pID property pIni_im on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #scrngrb -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) pSpr = sprite(me.spritenum) me.mRegister() (the actorlist).add(me) end --/--------------------------------------------------------------------------- --| stepframe --| initialisation is done on the first stepframe to allow all sprites to register --\--------------------------------------------------------------------------- on stepframe me pIni_im = duplicate(pSpr.member.image) prf_mn = get_prefs_nm("area") prev_area = goNetMgr.mGetPref(prf_mn) -- retrieve last 3D area sprite_rect = gUI_control_obj.mGet_sprite_rect (prev_area) im = image(sprite_rect[3] - sprite_rect[1], sprite_rect[4] - sprite_rect[2], 16) -- copypixels to the right size source_im = member("screengrab_ini").image im.copyPixels(source_im, im.rect, source_im.rect) pSpr.member.image = im -- now locate it at the position where the world will be set up cur_loc = pSpr.loc fin_loc = point( sprite_rect[1] + (sprite_rect[3] - sprite_rect[1])/2, sprite_rect[2] + (sprite_rect[4] - sprite_rect[2])/2 ) offset = fin_loc - cur_loc pSpr.member.regpoint = pSpr.member.regpoint - offset pos = (the actorlist).findpos(me) if pos then (the actorlist).deleteAt(pos) else alert "lost pos in screen grab control behaviour" end if end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if -- reset the members image to the starting image if pIni_im.ilk = #image then if pIni_im.width = 1 then pSpr.member.image = pIni_im else -- this should only happen in dev im = image(1, 1, 8) im.fill(0, 0, 1, 1, rgb(255,0,0)) pSpr.member.image = im end if pIni_im = VOID end if end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area --pSpr.locH = -99999 end --/--------------------------------------------------------------------------- --| mHide --| hides the static image --\--------------------------------------------------------------------------- on mHide me pSpr.locH = -99999 end --/--------------------------------------------------------------------------- --| mScreen_grab --| Screen grab the 3D world into the bitmap and place it in the same position that --| the 3D world occupied. --\--------------------------------------------------------------------------- on mScreen_grab me, the_rect, tDMem img = image(the_rect.width, the_rect.height, 16) -- limit to 16-bit for mem efficiency if (img.ilk = #image) then -- VOID indicates no mem avail for image creation img.fill(the_rect, rgb(0,0,0)) -- first fill with black (in case no bkgd img) img.copyPixels((the stage).image, the_rect, the_rect) end if pSpr.member.image = img pSpr.member.regpoint = point(0,0) pSpr.rect = the_rect pSpr.width = sprite (spritenum).member.width pSpr.height = sprite (spritenum).member.height end screen grab control behaviour0,>Fn>richard rossCASt key line=3>richard rossCASt  Yiiii}}}}}}--key --line --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global gUI_control_obj global g3D_sprite_rect property ancestor, spritenum property pSpr property pID on beginSprite me --/--------------------------------------------------------------------------- --| register --\--------------------------------------------------------------------------- pID = #keyline -- ID tag for lookup reference by peer objects pSpr = sprite(me.spritenum) me.mRegister() -- move it into the initial position if not voidP(g3D_sprite_rect) then inflated_rect = inflate(g3D_sprite_rect, 1, 1) pSpr.rect = inflated_rect end if end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| mRelocate_UI --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area -- if threeD_sprite_rect = usable_area then -- -- -- no key line -- pSpr.locH = -99999 -- else inflated_rect = inflate(threeD_sprite_rect, 1, 1) pSpr.rect = inflated_rect -- end if endkeyline control| 0XOO,>Fn>richard rossCASt7 77%787878787L7L7L7L7L7L7`7`7`7`7`7`7d7h7u--add --image --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour allows the user to add additional models to the world --| They can define the positon and scale of the model within the world --| They can also define some behaviour. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gDBG property ancestor, spritenum property pSpr property pID property p3DMember property pServIntvl property pBumpChan property pInitial_im property pFinal_im property pImage_seq_list property pImage_seq_pos property pFinal_roll_im property pRoll_direction property pPlane_model property pFace_camera property pTxtr property pAnim_intlv property pNext_anim_time property pPosx property pPosy property pPosz property pRot_x property pRot_y property pRot_z property pScale property pNodeID property pTTTxt property pAutopilot_upto_dist on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #addImage -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mInit --\--------------------------------------------------------------------------- on mInit me pCollision_snd = member "bump" -- user definable pSpr = sprite(me.spritenum) pServIntvl = 4 -- user definable p3DMember = pSpr.member pBumpChan = 1 pNext_anim_time = the milliseconds + pAnim_intlv if pFinal_im <> "no animation" then -- an animation has been specified if pFinal_roll_im <> "no animation" then alert "you can't specify a continuous animation and a rollover - check the parameters in the behavior on the 3D sprite" pImage_seq_list = [] tStart = member (pInitial_im).number tEnd = member (pFinal_im).number repeat with n = tStart to tEnd pImage_seq_list.add(n) end repeat pImage_seq_pos = 1 else -- a rollover has been specified pImage_seq_list = [] tStart = member (pInitial_im).number tEnd = member (pFinal_roll_im).number repeat with n = tStart to tEnd pImage_seq_list.add(n) end repeat pImage_seq_pos = 1 pRoll_direction = 0 end if -- check that the node ID is an integer if not (pNodeID.ilk = #integer) then alert "node ID "&pNodeID&"in additional model for "&pInitial_im"& is not an integer, please reenter it" end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if -- tidy up the 3D stuff just to be tidy if not voidP(pTxtr) then txture_name = pTxtr.name p3DMember.deleteTexture(txture_name) pTxtr = VOID mdl_name = pPlane_model.name p3DMember.model(mdl_name).removeFromWorld() cnt = pImage_seq_list.count repeat with n = 1 to cnt pImage_seq_list[n] = VOID end repeat pImage_seq_list = VOID end if end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- on mService me -- start spinning the group as soo as it exists me.mAnimate() end --/--------------------------------------------------------------------------- --| mAnimate --| Do whatever type of animation is required --\--------------------------------------------------------------------------- on mAnimate me if pFace_camera then -- rotate the model so it always faces the camera keeping it's y component or rotation cam_pos = p3DMember.camera[1].getWorldTransform().position mdl_pos_y = pPlane_model.getWorldTransform().position.y position = cam_pos position.y = mdl_pos_y pPlane_model.pointAt(position) end if -- do we animate through a series of textures if pFinal_im <> "no animation" then if the milliseconds > pNext_anim_time then pImage_seq_pos = pImage_seq_pos + 1 if pImage_seq_pos > pImage_seq_list.count then pImage_seq_pos = 1 nxt = pImage_seq_list[pImage_seq_pos] if ilk(nxt) <> #image then im = member (nxt).image pImage_seq_list.setat(pImage_seq_pos, im) else im = nxt end if pTxtr.image = im pNext_anim_time = the milliseconds end if else -- are we doing a rollover? if pRoll_direction then if the milliseconds > pNext_anim_time then pImage_seq_pos = pImage_seq_pos + pRoll_direction if pImage_seq_pos > pImage_seq_list.count then pImage_seq_pos = pImage_seq_list.count + 1 pRoll_direction = 0 exit else if pImage_seq_pos < 1 then pRoll_direction = 0 exit end if end if nxt = pImage_seq_list[pImage_seq_pos] if ilk(nxt) <> #image then im = member (nxt).image pImage_seq_list.setat(pImage_seq_pos, im) else im = nxt end if pTxtr.image = im pNext_anim_time = the milliseconds end if end if end if end --/--------------------------------------------------------------------------- --| mAdd_image --| Create as many 256/256 planes as is required to show the selected image --| Create a new group of name "member name"&group. Add a string of the inst to make sure that --| it's a unique name. --\--------------------------------------------------------------------------- on mAdd_image me -- create the required number of planes pPlane_model = me.mCreate_Models() pos = vector(pPosx, pPosy, pPosz) s = float(pScale)/100 scl = vector(s, s, s) pPlane_model.transform.position = pos pPlane_model.transform.scale = scl -- now tell the cursor feedback object about it's node and tooltips gUI_control_obj.mSet_csr_fdbk(pPlane_model.name, me) end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseWithin me -- if there is a rollover animation sequence and we have not already started then start it if pRoll_direction = 0 then pRoll_direction = 1 end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseLeave me if pRoll_direction = 0 then pRoll_direction = -1 end --/--------------------------------------------------------------------------- --| mCreate_Models --| Get the names of the nodes that are in fact models --\--------------------------------------------------------------------------- on mCreate_Models me -- first calculate how many planes are required -- then create the texture im = member (pInitial_im).image planeName = pInitial_im&&string(me) res = p3DMember.newmodelresource(planeName & "res", #plane) res.length = im.height res.width = im.width obj = p3DMember.newmodel(planeName, res) shd = p3DMember.newshader(planeName & "shd", #standard) the_texture = planeName&"_texture" pTxtr = p3DMember.newtexture(the_texture,#fromImageObject , im) -- if it is a 32 bit image set the renber format to support HQ alpha if im.depth = 32 then pTxtr.renderFormat = #rgba8888 end if shd.texture = pTxtr -- --- check we can take this texture size -- -- max_w = pMaxTexturesizes[1] -- -- if Shd.texture.width > max_w then -- Shd.texture.scaledown() -- end if -- -- max_h = pMaxTexturesizes[2] -- -- if Shd.texture.height > max_h then -- Shd.texture.scaledown() -- end if -- obj.shaderlist = shd --aList.add(p3DMember.model(planename)) return obj end --/--------------------------------------------------------------------------- --| mStart_fly_to --| Callback from camera control to say that the camera has just started zooming in --| it passes the fly to period so a model can make sure that it moves back to the correct orienation in time --\--------------------------------------------------------------------------- on mStart_fly_to me, fly_to_period pFly_to_flag = 1 pFly_to_period = fly_to_period pFly_to_end_time = the milliseconds + fly_to_period end --/--------------------------------------------------------------------------- --| mIs3D --| Check that we have dropped this behaviour on a 3D member --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D --- --/--------------------------------------------------------------------------- --| mFind_usable_member --| find members of this type in castlib 1 --\--------------------------------------------------------------------------- on mFind_usable_member me, this_mem, tType, rtn_lst cnt = the number of members of castLib(1) repeat with i = 1 to cnt mem = member(i, 1) if mem.type = tType then rtn_lst.add(mem.name) end if end repeat end ------- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member if aScript.mIs3D(this_mem) then tList = [] tType = #bitmap aScript.mFind_usable_member(this_mem, tType, tList) tGPDList[#pInitial_im] = \ [#comment:"Which inital image?",\ #format: #string,\ #range: tList,\ #default: tList[1]] tList1 = duplicate(tList) tList1.add("no animation") tGPDList[#pFinal_im] = \ [#comment:"Which final image in animation (must be sequential)?",\ #format: #string,\ #range: tList1,\ #default: tList1[tList1.count]] tGPDList[#pFinal_roll_im] = \ [#comment:"Which final rollover image (must be sequential)? You can't have an anim and a rollover.",\ #format: #string,\ #range: tList1,\ #default: tList1[tList1.count]] tGPDList[#pAnim_intlv] = \ [#comment:"Anim interval (ms)",\ #format: #integer,\ #default: 100] tGPDList[#pFace_camera] = \ [#comment:"Always face camera?",\ #format: #boolean,\ #default: 1] tGPDList[#pPosX] = \ [#comment:"Postion x",\ #format: #integer,\ #default: 0] tGPDList[#pPosY] = \ [#comment:"Postion y",\ #format: #integer,\ #default: 0] tGPDList[#pPosZ] = \ [#comment:"Postion z",\ #format: #integer,\ #default: 0] tGPDList[#pRot_x] = \ [#comment:"Rotation X",\ #format: #integer,\ #default: 0] tGPDList[#pRot_y] = \ [#comment:"Rotation Y",\ #format: #integer,\ #default: 0] tGPDList[#pRot_z] = \ [#comment:"Rotation Z",\ #format: #integer,\ #default: 0] tGPDList[#pScale] = \ [#comment:"Scale x 100",\ #format: #integer,\ #range:[#min:0, #max:1000],\ #default: 100] tGPDList[#pTTTxt] = \ [#comment:"Tool tip text",\ #format: #string,\ #default: "a short descrition"] tGPDList[#pNodeID] = \ [#comment:"Node ID (0 means it's not a node)",\ #format: #integer,\ #default: 0] tGPDList[#pAutopilot_upto_dist] = \ [#comment:"If node, how close to autopilot to when clicked)",\ #format: #integer,\ #range:[#min:0, #max:500],\ #default: 50] end if return(tGPDList) end if end getPropertyDescriptionList add image as plane|0N h h,>Fn>richard rossCAStg  $(5 vendorlist>п mText;P>richard rosstext3TEXd2??NoTextureCASt bump=>richard rossCASt # sound off>Op>richard rossP!  CASt "sound on>Oq>richard rossP!  CASt PZZZZnnnnnnon dummy -- this just creates an empty line in the behavors dropdown menu end ----- dev|0N,>Fn>richard rossCASt Phhhh||||||on dummy -- this just creates an empty line in the behavors dropdown menu end *** dev tools behaviors|0N,>Fn>richard rossCASt!.dev - show browser frame=~H>richard rossvCASt       !%2--key --line global gUI_control_obj property ancestor, spritenum property pSpr property pID on beginSprite me --/--------------------------------------------------------------------------- --| register --\--------------------------------------------------------------------------- pID = #shbr -- ID tag for lookup reference by peer objects pSpr = sprite(me.spritenum) me.mRegister() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list, pBrowser_frame_rect pSpr.rect = pBrowser_frame_rect end --- dev - show br frame}1Ycscs,>Fn>richard rossCASts,,,,,04Aoutput>п mTextGrichard rosstextG3TEXd2??NoTextureCASt / ! h z z z z --Ultimo 00, Jakob Hede Madsen --Attach this behavior to a field or text to see fps --As it uses the actorList it will count both native updates, --and those caused by "updateStage". --Samples are included for a timespan determined by "pRange" in mS --The display will update each "pRefreshDur" mS property pTimeList property pSum property pRange property pSampleCnt property pNextTime property pRefreshDur property pMbr property pText property pLapseAverageTime property pLastTime property pSpr global gUI_control_obj on beginSprite me ---- pRange = 1000 pRefreshDur = 500 ---- call #mFpsMeterRemove, (the actorList).duplicate() (the actorList).add(me) pTimeList = [:] pSum = 0.0 pSampleCnt = 0 pNextTime = 0 pMbr = sprite(me.spriteNum).member pMbr.text = "--" pSpr = sprite (me.spritenum) --position the sprite along the bottom of the browser frame at the centre -- b_rect = gUI_control_obj.pBrowser_frame_rect -- -- l = b_rect[3] - pSpr.member.width -- -- t = b_rect[4] + pSpr.member.height*2 -- -- pSpr.loc = point(l,t) end on endSprite me me.mFpsMeterRemove() end on mResize_sprite me, hide_flag if hide_flag = 1 then pSpr.locH = -99999 else --pSpr.loc = point(g3D_sprite_rect[3], g3D_sprite_rect[4]) - point(70, -5) end if end on stepFrame me theTime = the milliSeconds if pLastTime.voidP then pLastTime = theTime return end if theLapsedTime = theTime - pLastTime pLastTime = theTime pSum = pSum + theLapsedTime pSampleCnt = pSampleCnt + 1 pTimeList.addProp(theTime, theLapsedTime) theIncludeTime = theTime - pRange repeat while pTimeList.getPropAt(1) < theIncludeTime pSum = pSum - pTimeList.getAt(1) pTimeList.deleteAt(1) pSampleCnt = pSampleCnt - 1 end repeat if pSampleCnt = 0 then return pLapseAverageTime = pSum / pSampleCnt if pLapseAverageTime = 0 then return theFps = 1000 / pLapseAverageTime if theTime < pNextTime then return pNextTime = theTime + pRefreshDur fp = the floatPrecision the floatPrecision = 1 --theNewText = theFps && "/" && the FrameTempo theNewText = string(theFps )&&"fps" the floatPrecision = fp if theNewText = pText then return pText = theNewText pMbr.text = pText end on mFpsMeterRemove me (the actorList).deleteOne(me) end -------- frame rate scriptP00,>Fn>richard rossCASt !%2node IDsM>N1?>richard rossLctX` v! ?M@ Ir- d@F r-p 9tna 0$6p<)``rÆv@2Lscr\ >@\\\Lscr\ h \\\Lscr\  \\b" Fs"Tnpt<t DCWCgO ICWIBgCW O _ RLDADLCW ALRLa AAALRDK Y%LCW RLBWUI control parent._Lscr444\ )a\^b^}jlvv(*.:&.#Tx|~ g~IBgCPDA\RARLL )LDCWRLa]E JLBguALRT,Ja3RLAJLCg8RLBgALRTIѕDA"\ BWb1;=   Ja3RLA/JLCgJJLKJLCg8CgBg4ALRT2JCgՕCfBWcGIѕDA"\ BWbIѕDA"\ BWbIBgIѕDA"\ BWbICgRLBW1=  KaRLAKBgABWBW1  *Fmodels start load end loadstarting adding modelsended adding modelsLscr\\\\ ` 0<\`d4? gj0"O  I?a@EADCWRI?LCgBP1`  JCWC DBWcZICgRLACgJLACgJRJޕLJ DBWc ILBg LJ ILBg IJBg 1  CRLEEDEEECBg4LBW area speed testtest speed every run?LscrRRR\ r2\   7!?<  G7X xlntItX/,\^^^Lfp rk5hH : < T+oO TG  42A  B  :H! JAPJJJAPDPICgPICgPJACgJJACgJPJCWaPJEACgPJJJCWRJaCWRJpLbJaCWPACWACWI?a@EADCWRI?LCgBR @LCWC  LCWECBWIA(A(ICg,ILBg/CRJCg3R A\C C C RARLL 5LJLC  BguJLC L ALRT8JCg3RARLL DJLCgR L R CR L LL BguL LLL BguALRTGILBg-1`;=           A 4 KBgAA"\A"\CfBWcRA"\ AR DBWbARLKBgArA"\RLARCWLCWBpCWaBguKCgRL KBgAJJbKBgCfBWc1         D BWbICgRJCWLACgJLACgJCWjbjKBgBWA"\A"\1  !DJpJpabJpJp""1 D BWbJ1J ABWJ ABWKCgBW KCgBW1   DBWba3AK#JA  J AJCWaJJCCgyRCgRLa3LCg8RLACg8RLCgJRLACgJRLL GDBWbLLCWLLCWRLC#RLJCWRLLLCWaJDBWbJCWaJJ~LARLR LCg8RLCgJRL Cg8RL CgJRLLR LLRLJR LLL CWL LJCWaD BWbBW1-%$&()./'+,*         D BWba3A)AJCWaCgyRLCgRLAdLRLARLCg8RLCgJRLCg8RLCgJRLLRLLR JLR LLCWL L ACg8RACg8RACgJRACgJRLLGDBWbLLCWLLCWR L C#R LJCWR LL L CWaJDBWbJCWaBW1-%'+&)$(,/*.      ICg.RLa3RARLL LLCg8RLJLC LLCgJ LLCgJRLLCg8RLACg8RLACgJRLdJLCLeJLC D #JLC C 5JLC D  JLC C ALRTDCWR I?a@EAI?LCW}B0 D BWbJICg0bIBg IBg1;=]123`      CRLEEDEEa456ACEA CBg4LEEDEEaECBg4LEEDEEaECBg4LEEDEEaECBg4L!EDEE}4DDCEDCBg4LBW&"  2DTh~6Tr?333333areapCounter > pTest_countnext test is translationpResultlist ismGet_larger_areagood squirellythis should not hapenmGet_smaller_areaBackdropShader-copyOverlayShader-copypTestArea < 0 Minimun fpsX location for speed testY location for speed testZ location for speed testSpeed test type rotationLscr\ r`\l rR0j>wBE<GF=VfH o1.00<08/6fhhH ht [) i 9 z :J$ntv v;8f468 8 Ev<=a@EA1=?C@>>KBDEBg1 BaEEBgAF1F BKbj KBgEEAC GH1I IBg*1FB' JBAKBAL1 BpAbAFBKbj1M ARLKECg3 4KELCgCW}DKKELC BgNALRT=KBW1N_O RKa]dE ARdPKQRAReLBW1NS T`CRKTCWaC;BLGEDEEa45A6AcCEAwB<hjilk^monprs}zabc`efgd~xy]_uvwt=@8xzzT zhjj bi*jH C8( U    v#Vr W    < X R j n n\s Z A,[G1\L)P-5;8*.0Wj0^>X}q E<=?C@>>KBD1 KzzBWI1{JCWCJEACgPJDB|JEACg}CWRL`b~CWRLL"JLbCWRLL"LdbKLABg1I   K1<Kp1IaR KB[ KBW1 za3CRC9 qppqrp,h hhkhh h<p2hhhkhhC# A hKACY.mu tCEDCWCBAuuACWĕJAmBJmBm;mAmnmm mmnmmm1_                               IaCWIpKBX1 KBZKJCRJCaRJLLACRLa3%LACgJRLaRL] ABWBW1   A JCRJCaRJLLACRLa37LACgJRLaRLRLCWaJLBaJCRJCaRJLLACRLa31LACgJRLaRALRJLB      AdAdCWCWaRLAd LCRJLbPJbIbRw8KB\CWCIa@EA IB DBWb IBg"1 KCW}AACgDAKCg3RL.ARLL "KLCgRKLB\ALRT%KCW}AACgDpKRLCgW(D K K BWbKKAdKBLCgW"KAKAK1    K AwwJaCWKa@E KKCW@EA'KBKCgyRKCgy D BWbAKKpaaRLBLLŊ}ab}p}pab}CayBƊ}aIaRIAbR1    RKa]dE ARdPKQRAReLBW1NS TXCRKTCWaC;:LaED EEaECBg4LbED EEaECBg4LcED EEaECBg4LeEDEEaECBg4LfEDEEaECBg4LgEDEEaECBg4L~EDEEaECBg4LEDEEaECBg4LEDEEaECBg4LEDEEa45' 6'CEACBg4LEDEEa45A6ACEACBg4LjEDEEa45A6A CEACBg4LlEDEEa456A CEACBg4L^EDEEa45A6A2CEACBg4LoEDEEa45A6ACEA CBg4LEDEEa45A6ACEACBg4LEDEEa45A6'CE CBg4LxEDEE}4DDDCEDCBg4LBW+(('(((*$ "0LV`l4J`v&bumpxyz dummycamtarget node ID is voidgroupmodelmdl is no bahavior instance pasedInitial start pos XInitial start pos YInitial start pos ZFinal start pos X0Final start pos Y (reset by height from ground)Final start pos ZFinal rotation XFinal rotation YFinal rotation Z'Height from ground (0 means no ground)Max turn speed Turn dragTurn acceleration Max speedDrag AccelerationTime taken to autopilot (ms):Up vector in modellers coordinate system (3D Max is y up)Lscr\ pC!\  >wB<tm=@BDD$1 DcRDH  e_ j8(*,, v ,r6>@@j@TFR TnOFn,A GHBDHtHP^!K:# J$U%`    &k P " r v ~(hw ~;8   *    +_ E<=?C@>>KBD1 KB1CWCK֕ KB͓;dD KBϓ$dD KBГdD KBe1 CRKLBΊCWRD L KCW} RJLCؐLa3RIѕD A"\ BWbIѕD L D BWbARLL jLLCgJRLL D L KCW} RJLLCWCRLBLALڢۊLBALRTmIѕDA"\ BWbފߊCWRCWAdR L L L CWR pLbpL ?CW?CWCJEAC CaR CpR L L L ACWBƊaCWIաKBg)1_;=     / ( A֟a1 1AA?CWRLA ARA֊LCRLb1 KCWECg3RLAwB<m=jfhh)hH z.C rO8/ [  `n dt v K~@rT+,$PRR4R`fhhz5hHl?"<X#@c  $Bn   " & &%y &| ,  'x ;8   ) =  L N T+ C T E<=?C@>>KBDCW 1 mCWA mAP1 BaRLCgǐӊRDRDRLLCW RLLALACgRLLLACgLLALa CgRfLLa CgLLALa ACgRwB<" !$&'(*#=|  M$ H @LPPKPTjll Wl8Zr c R{"`2:<,<WBD !468>8!<^`bb9!f$&(22`H^` , 0 :3 : P  "|P p  h l t%dt tF   (3   )    ) y   +7   -1    1/ EP<=a@EA1=?C@>>KBD$CWCBp$%CW $CW &CW 'CW (1 KB81DK<BKBLCBgu1_ K=6   KKBgN1_A$KBW1 AA\RARLL +LACWRLa]KKLBgNALRT.D A\RARLL +LD CWRLa]KKLBgNALRT.1+;  CRKa3RARLL KLCgJCWPRL Cg3RLALKLCgJBgNaARLL UL LCgRLACgDLKLCgJBgN&LD LKLCgJBgN ALRTXALRTLa3RLA7LLCgJRKLCgWR L KL B? D BWlALRT:1_A;B=@        TCRTCWaRCRLRLD RDCRKLLLBLED EE}4LELCBg4L"EDEE}4LELCBg4CRDRKLLLBKLBLDBgNL*EDEE}4LELACgJCBg4LBW+FGE   #*8FPz%no nav button required in this spacegyou have specified no nav hot spots - please look at the parameters on the nav arrow sprite's behavior[#problem with line of nav button hot areas member, ]HpHot_rect_list is not a list - problem with nav button hot areas member worldMgrrect&lost pos button nav control behaviourhilite Which navigation arrows member?'Which navigation arrows hilite member? Lscr\ Fbp4 \h nx*>wB<IK=PhH (938("$$u? $H .8::jU: <FHH\H9J`bb eb{"h 2s y>FLLtd EO<=a@EA1=?C@>>KBD1 B91A B91Ia@EA IIBJ1 KDK<BKBLCBgu1_ Ia@EAKwB<Q=NSRPlH +V68(&((B (M2466cR6H 8BDDWD FPRR^R90Te  z{ A EM<=a@EA1=?C@>>KBD1 1B91A B91BpD IBg#NCW NBOIBg"1: BKCWb1P K<BKBLCBgu1_Ia@EAK > >\ Pn`[ >\|  t >wB<=:P$rptz<zH  a 0l8. lx P!}w6 >P:PX3 3:8  H P d!|s\ dd  $ & 2- 2< H  /E E<=?C@>>KBDKBg1 BLRLLARLLRKRL "RLRL?LLCWaRLBK `LALAC%RLLLCWjLKLCWjB2LLLALCWjLKLCWjB2-LLAC%RLLajLKLCWjB2DBWbLBW1d #* CW~\a3RLRLAEAC LBlALRT"ARLL !LCg8RLBnALRT$CW BCW 1;=    KKKKKK AAKLKL AARCARL ARL DL D L RCWjRLALALLCWjRAC%QKLLB2L{KC|RL}~LALAC.REAC LLBCRLKBguLMLBguLLBguLLBguLARALRTALRTEAC Cg3K1;e :      KCWaARARARL ARL DL D L RLCgyRLRLLC.RLXEAC ajRLKR LACgJL 0LACgJLACgJC.RKLLBCLACgJA  0LACgJLACgJC.RKLLBEAC LC L:LLLARALRALR1;e    KRA RDK D K RLCgyRLMRLRCWjRLLC.LC.CWjRLACgJLACgJQLACgJLACgJLACgJLACgJCWjRLLLB2LCL%hLLLB2LACgJRLACgJLLACgJCWjRLCWjR LL LB2LCL%LACgJ LACgJ QLACgJLACgJLACgJLACgJCWjRLLLB2LCL%hLLLB2A LACgJRLLACgJLACgJCWjRLCWjR LL LB2LCL% LLLB2LCL%LLM1e  . . CRA\RARLL ILA\RARLL ,LDCWRLa]CLLBgNALRT/ALRTLLBW1;  T6CRKLCRLEDEEDCWCBg4LBW 8>FRj4xxxxxx must redo the backdrops after the speed testh, vmodelsWhich pano graphic?panoLscr\ \\bbSH:'024ER 4K>=`48@v@@^ c ːAAKBW11KCW~Ka3RARLL eKLCgJRLCW@LCW@KKLCgJBLCW@KLCgJBgKLCW Bg4ALRThCW Q1;=   RL 6LCW LABLLLBWALRT:DBWl1  RL KLBALRT̐1 KBWIKa3RLwB<=?M.000@B DV*VH v R ^8,.0 &j0 HJPPJP Tbdd^dhE<=?C@>>KBDa@%RKABp%1AAAC%RLAAC BBpL%CW 1   1IB J1 KKKLAC%RLa@%$LKC BL_i%KKB2BpL%BpC.BKbjBJwCWpKKBJwCWpLL1M   areascreengrab_ini*lost pos in screen grab control behaviourLscr\ p\dh>wB<8 XZ\\H lx||s)|4PB wB<t=@N4 G/H  6~z8r@ J SV3 ?!J/';8 $ ( *( *= 8 v ~ *    +g E<=?C@>>KBDCWC`RJLBnCW RJLCgBa3RARLL LCW Bg4ALRTCW 1;=    KB1;JEAC CaRCpRLRLLLBƊDobAa3ACgJRLCW@%LCW%RLBg4LRL%a3a3AA CgJRLCW@%LCW%RLBg4LRL%1     KCފߊCWRCWAdRLLLCWRpLbpLIKBg)1  A1  A 1CW%RKCW} RJLD CRLLLb LLKKJLLC RJLD  C RLD RJL{LC|LA  EV LLL LBW1   ARKRKR1RKa]dE ARdPKQRAReLBW1NS AA\RARLL +LACWRLa]KKLBgNALRT.1+; TCRTCWaRKLC;CRCRKLLLBLED EE}4LELACgJCBg4LCWRLDBgNLED EE}4LELLa3CgJCBg4LED EE}4LELLa3CgJCBg4LED EEaEAdCBg4LED EEEACBg4LEDEEaECBg4LEDEEaECBg4LEDEEaECBg4LEDEEaECBg4LEDEEaECBg4LEDEEaECBg4LEDEEa456CEAdCBg4LEDEE}EDCBg4LEDEEaECBg4LEDEEa456CEA2CBg4LBW+E  #%%((  Z 0@Pbzbump no animationqyou can't specify a continuous animation and a rollover - check the parameters in the behavior on the 3D sprite node ID in additional model for '& is not an integer, please reenter itresshd _textureWhich inital image?5Which final image in animation (must be sequential)?XWhich final rollover image (must be sequential)? You can't have an anim and a rollover.Anim interval (ms)Always face camera? Postion x Postion y Postion z Rotation X Rotation Y Rotation Z Scale x 100Tool tip texta short descrition"Node ID (0 means it's not a node)1If node, how close to autopilot to when clicked)Lscr\ 0\\\Lscr\ \\\Lscr\ v0\df>wB<688m 8H BNRRRVlnn%nt|f2! BXZ*8`5: PG  *,, h,_[CgBW_[KBgNCKawCWaDPKawCWB1   KB1KAB J1RaC LBWLRLLALLBguLRACg8L (ACgJAB?AT2BW  BW RL BWL\RA]LCW}D RL]L!BWL!!P1$%&'"#      _[KB(1 --fpsLscr\  \V279LKxkD>RQ:XFY56? "022!*28 7) 6RTdCg]dN   /  6  p   r t |;% |  =    "H   X.  * 6 8 J%}3 J ~"0,N<0llnv2$?vx.049X4:R=d} 048?A8!z0 4FG F":^J|#9L$VNPVOD+V%ApRgM&$Td'""$Vzq $(b.X) Z*\%+]Y, ^-""`]". &244a4/:@DDbD0HPRRcRKBgKBW1J2a3RARLL J2LCW Bg4ALRTCW P2J5a3RARLL J5LCW Bg4ALRTCW P5CW P6J7a3RARLL J7LCg8RCW RALRTCW P7J9a3RARLL J9LCW Bg4ALRTCW P9J:BgCW P:1;=<     P>I?a@EADCWRI?LCgBRLCWC PD LCWEPDPFKBgCP2CREHLBWGLBWILa3RARLL *LLCg8RLLCgJRKLLBgALRT-J2BWIAPKCPLJLEMBgNJLEOBgNJLEPBgNCP7CP9PQPRDCWCgP:CWSCgTaURLEVCgW APXPXAPYCP5Ia@EAIKBgZ_[KBgN1`^_;=]<\     KCWaKCWaRJFRKKKBgP>LLJDDBWbDBWcDBWbKBg KBg1defg  KCWCXIa@EA"ICghRLACgJQLACgJQ/_iajRLACgJLACgJQLACgJLACgJQKCWaKCWaCWjPkJkACgJJkACgJRLJFLPF1mnqpo   J>JQKCg( KBg#JQJ7a3RA"\RARLL OJ7LCgJACgJRLL.J7LCg8BgrJ7LCgJALJ7LCgJACgJBg4ALRTR1;s=t    J2KKBgu1]< KEvCg'RL DBWlLawBW1< CRCPxRJkACgJRJLa3RLAJLLCgJRJ2LCgyRLCWBWzDJLLCgJ BWlLE{Cg|DJLLCg8CW} BWl LLBg{LLCgyRLCW~dLLACgJJKRJkACgJLRJkACgJJKLACgJRLLACgJR JkACgJJKR JxLLLL L CWjBguALRT1=]<       JCWCCRCPxRJkACgJRJLa3RLAcJLLCgJRJ2LCgyRLCWDJLLCgJ BWlLE{Cg|DJLLCg8CW} BWl LLBg{ALRTfRLa3RLA,LLCgJRLACgJRLLLRALRT/LJKAPJkACgJJkACgJJCWjPIa@EAIELJKBgJBW1=]<e       JACgJRJACgJRLRLRKCWLLCWRLLRLLRLL#LLLRLLLRLLLRLL#LLLRLLLRLLLRLCWaLCWaCBW1de     J2a3RLATJ2LCgJRLErCg|#CRLBgNLLaBgNJ7LLBguLECg| J9LBgNALRTWKEvCg'RL DBWlLa APPJ#CRLBgNLJ:aBgNJ7J:LBguKEPCg'RKECg'RLCW2KECg'RLCWLLBgLLBg D BWl LBg1=<     J2a3RLAfJ2LCg8EJ2LCgJRLBgJ2LCg8EJ2LCgJRLBgJ2LCg8EJ2LCgJRLBgALRTiKBg1=<    J2a3RLA.J2LCg8EJ2LCgJRLPLBgALRT11=<  J>AP>KBgKCWCKPKJCg!PKBgEJ9JJJxJkBWJ2a3RLA,J2LCg8EJ2LCgJRLJBgALRT/D BWcJ:KCgBg1=<     KBgJACgJJACgJRKLLQKKCgRLACgJRLACgJRJACgJJACgJRJACgJJACgJRLLARLLARJACgJLJACgJLJACgJLJACgJLCWjRLBW1  2APQKBg$Ia@EA IBgKEMCg'RL D BWlLD Bg1<  PQIa@EA IBgKBg%KEMCg'RL D BWlLD Bg1<  KEvCg'RL DBWlKECg'RL DBWlLawCWRLpbBWLJLaBgLBg1  KEvCg'RL DBWlLJBgBWKECg'RL DBWlLBg1<  KECg'RL DBWlLKKKBg1< J2KCgyRLCW LBWBW1]< A{CWĕ ABW6A|CWĕ ABW$A}CWĕ ABWA~CWĕ ABWKEPCg'RLaŕ ABWBW1<  J:KKBg1 J:Bg1JkCWC DBWl JkBW1 JY ABWBW1 KP5PY1_APYJ5BW1KP61J6BW1 (>Nh",HVdmax_fndcursor feedback objectdoing speed test speed testnot doing speed test'lost world behavior mFind_3D_world_sprlost instance of 3you need a mGet_dims handler in the behaviour for "lost world behavior mSet_up_commslost main nav objectlooplost infobtn behaviour hide info show info lost world behavior mHide_worldlost screen grab behavior lost world behavior mShow_world lost world behavior mFly_camera$pBrowser_frame_rect not yet inittedLnam!! ! )dummyini_UI_controlUI_control_stopmovie get_prefs_nmgUI_control_objscriptnewobjectpmDestroyvoid movieNameoffsetlengthsymbolreturnsufxnmsnmgoWinMgr goNodeMgrmInit mNewStgWHmSet_browser_dims stepFrame mRegistermFind_3D_world_sprmGetUI_locationsmFind_usable_area_rectmGet_sprite_WH mSet_up_commsmAdd_secondary_3D_memsmSetUp_background mSetUp_UImGet_sprite_rect mShow_widgets mHide_widgets mHide_world mShow_world mFly_camera mGet_instmCheck_nav_key_down mSet_csr_fdbkmCheck_node_clickmGet_browser_frame_rect mLights_on mStore_Lights mGet_lights mStore_campos mGet_camposme pUI_inst_listcountsetAt pLights_lstpCampos pMServiceList getPropAt pMrelocate_UI pCsr_fdbk_objcntinstn pUI_is_setupgoNetMgrilkinstancemGetPrefvoidp p3Darea_maxedvalue pMax_b_areasendAllSprites mRegister_UIsortgetAtpUI_element_seperationpBottom_UI_element_listinfobtnaddhelpbtnbtnnavpShowing_widgets pAuto_pilotgetRendererServicesgetHardwareInfosupportedTextureRenderFormatsrgba8888findPos pUse_alpha pLights_on mRegSetWH actorListsupported_alph_listtypeprefsaListprf_mnintegerputgowhnew_area old_max_areamGetWHstagerectpBrowser_frame_rectalertbrowser_frame_widthbrowser_frame_height new_b_arearctwhmServicetmnextTimeaddPropworld spriteNumpUI_btm_elements_rectsgetaPropnothing mGet_dimshandlerstringlistpbrdimsltdimslistmin_t offset_RHS pUI_heightpUsable_3D_area worldBtnWmSetProptmaxHsqrtfloatareaaspectHfactoraspectWbhbw pServIntvl mRelocate_UIpShow_tt pCsr_fdbkmainNavmSet_main_nav_control_objmSet_button_nav_control_objtm_lst mNav_InstaddModelmImport_models pickedModelmSetupaddImage mAdd_imagescrlbackpScrlback_instp3DAreap3D_sprite_rectcalltD_areawh_listua_wthreeD_hthreeD_wbrowser_frame_areadiff_wua_hdiff_hSR mShowItemUIs mChange_state mHideItemUIsscrngrbspritemember directToStage updateStage mScreen_grabmHidesg_instwspt world_instmShow mStart_interp mdl_or_transpass_cntl_flagbeh_inst keyPressedpClicked_statemAdd_to_fdbk_datamodeldatamCheck_mse_clickaTrans beginSprite exitFrame mCheck3DStatep3DMember_list shockwave3dpreloadgDBGmemthisMemigetPosframe build_world threeD_sprstate resetWorldtheStategetPropertyDescriptionList pPrev_areapAlways_speed_testusable_area_rect usable_areacommentformatbooleandefaultaScripttGPDListmSet_up_sprite mJump_cameramCheck_resultsmGet_larger_areamGet_smaller_area mEnd_processpMax_fpspMin_fps pTargetFPSpInterp_guess_factorp3DSprpUsable_area_rectpBrowser_frame_area p3DMemberpCam1cameragetPropvectorpSpeedTestPosXpSpeedTestPosYpSpeedTestPosZ duplicate transformpositionpInit_camera_transpJumppRotpInitial_guess pTestArea pResultlist pTest_Period pTest_count pTest_cnterlightrgbcolor paletteIndex hexString getPropRefshadernameemissivepStarted pFrameCntrback_col speedtest_poscTransstored_light_colorsthis_shdemls pTestArea_strs pStart_time pEnd_timepCounter pResult_fpsdonegot_itpSpeed_test_typerotationabsarea1this_posarea2pos2fps1fps2target_1_fps_diffpos1 area_diffthis_fpsgradfps_diffmSetPrefshdrValspropvalrangeminmax pTest_stage endSprite mouseDown getmodelsmIs3DpID goPoolMgrancestorcUIbehmnewmRegBehpSpr mUnRegBehmFreep3D_mbrpShowingpFOV fieldOfViewthreeD_sprite_rectlocHwidthheightthe_rectamemberjtext displayModemode3dtis3dcurrentSpriteNummEnable_directionsmArrow_button_clickedmArrow_navigatemUpdate_backdropmCheck_collisionmCheck_camera_heightmInterpol_A_to_BmAdd_SDSpCollisdion_distance pMax_speedpCollision_sndpInitial_start_pospInitial_start_posXpInitial_start_posYpInitial_start_posZpFinal_start_pospFinal_start_posXpFinal_start_posYpFinal_start_posZ pTurnSpeed pTurn_Drag pTurn_drag_10 pTurn_AccelpTurn_Accel_10pSpeedpDragpDrag_10pButton_key_pressednonepShowing_LR_button_downpShowing_UD_button_down pBumpChan pFirstHit pMUR_model pPass_cntlpUp_vector_component pUp_vectorpNav_directions_lstdirections_lstclonepCam2 pFinal_rot_x pFinal_rot_y pFinal_rot_z UI_rects_list start_trans final_trans final_rotpButtonControl_objbutton_key_pressedleftpMax_turn_speedrightmArrow_key_releasemArrow_key_pressedselfrotateupdownpAccelsoundplay translate keypressedlstamtgetWorldTransformzAxisdetailedmodelsUnderRaydistance directionhitlistposfirstHithitmodeldirVectpCamera_heightyAxisdiffpInterpol_endtime milliSecondspInterpol_periodpInterp_startTransformpEnd_transform interpolate pTarget_mdl pTarget_nodemSetItem tTransform proportioncharchildmodifierlodautolevelsds addModifierenableddepthadaptive subdivisionmdlnxt_mdlccntmlstc mStart_fly_topAutopilot_upto_distpNodeID pInter_to_mdl normalizepInterp_Offset_vectorpointAttotal_dist_vectorstop_from_dist gTransfer_immAnimate mMouseWithin mMouseLeave mRollOver mGetModelsrotatexrotateyrotatezmFind_3D_memberspAdditional_mempPospAdditional_grp pRolling_flag paxisrotationnewGroupcloneModelFromCastmemberpLodbiasbiaspreserveParentaddChildpPosXpPosYpPosZpScalescalepointAtOrientationypFacing_camera_transform mdl_pos_ytName group_namescl newmodelNamecam_pos ModelName pRolloverpInterpol_start_tmpInterpol_end_tmpRollup_durationamodel fly_to_period pFly_to_flagpFly_to_end_timepFly_to_periodthis_memrtn_lstabortpTTTxttListmInit_default_nodespTT_mdlpMP_mdl pTTTxt_mn_flgpGrp_mdl preserveWorld cameraposemkrspposspcmdlnmemkrposmbrtempline itemDelimiteritemVIDlnid_lstlcntid_txtpparentpn mouseWithin mouseLeavemAssign_hot_areasmCheck_rollovermCheck_mouseClickmChange"mFind_button_nav_control_behaviour mGet_offsetmFind_usable_membermValidate_hot_areapUp_member_name pUp_member pDown_memberpDown_member_namepHot_rect_listpBaseImimagepRollIm pCurrentImpMain_nav_control_objmyRectpHotspots_field_nametType direction_lstmouseLocpointtoprelLochot_rect_list_str copyPixels button_Listbut_rectbutcopyRectnoinsidecursorlochit checkRecthitrectupDowndeleteAttokillkilllstmbitmapfieldtList1upnmdownnm mouseEnter pHelp_url mLaunchHelppShow_hlp_nameshow_hlpmSetCurs gSolar_systemmHide_tool_tipsmbr_name iClickframegStopgFrmTimemCheck_over_mdlpFDBck_data_lstpLast_mouse_pos pTT_objectmReinitpSptLT pSpr_recttDSpr cl_m_name clicked_modelnodeIDpLast_roll_obj mShow_tooltippause mHide_tooltipnopause rl_m_nameTTtxt rolled_model modelUnderLocmMove_TTmCreate_new_TT pCheck_rctsprremoveBackdrop pTexture_name deleteTexture pTexture_ref pTT_mbr_impTT_Text_offsetHpTT_Text_offsetVpStayUp_period pStayUp_timepLast_mouseloc pTT_width pTT_heightpCurrent_TTText pShowing_TT pLast_locfromImageObject newTexturelowquality addOverlay pOverlayNumoverlay pTT_OffsetpTT_RHS_OffsetpTT_TOP_OffsetpTT_mbrim current_imlimitVtt_loccor_Hcor_VlimitH charPosToLoctext_len target_rect source_rectTT_len text_recttext_imend_pontlastchar pauseFlagpHotRectcentreb_rectget_current_im_chunk mInit_bacmUpdate_texturemFind_graphics pTestureListpMbr pPano_source ppano_mem pDegree_amtspr_rectpano_w texture_dim new_height pBackdrop_im gUtils_obj mClean_list the_texture ptexture_dim pBD_tile_h pBD_tile_v addBackdropthe_imthe_loc pBackdrop_cntbackdroppBackdrop_im_wcam_rect sourceRect texture_refdestRect_or_quadamt_degnewlocc_rectoldloc right_edgetexturenew_sourceRectold_sourceRect nibble_lenfront_nibble_sourcesource_jmp_amt nibble_destgraphicmGet_next_free_spritemClear_spritesmClear_spr_list mClear_spr mGetEmptySlotpThe_last_channel lastChannelpStart_vol_spts pEnd_vol_sptslistpropListobjectthe_listentry memberNum puppetSprite thisSpritesptspr_listinklocZblendstretch foreColor backColorscriptInstanceListbLstsptObjbCntemptynextpos the_castlibpIni_imregPoint source_im sprite_rectcur_locfin_loc prev_areafilltDMemimgglPropskeylineg3D_sprite_rectinflate inflated_rectmCreate_ModelspNext_anim_time pAnim_intlv pFinal_impFinal_roll_impImage_seq_list pInitial_imnumberpImage_seq_pospRoll_directiontEndtStartpTxtr pPlane_modelremoveFromWorld txture_namemdl_name pFace_cameranxtplanenewModelResourcenewModelstandard newShader renderFormat shaderList planenameobjShdRespRot_xpRot_ypRot_zshbrmResize_spritemFpsMeterRemovepRange pRefreshDur pTimeListpSum pSampleCnt pNextTime hide_flag pLastTimepLapseAverageTimepTextfp theNewTexttheTime theLapsedTimetheIncludeTimetheFps deleteOneccl Fmap<J*:JJArialCourier Courier New HelveticaVERS, f f STXT bREAD ME This castlib contains code pertaining to the authoring of and control of the 3D world. PLEASE DO NOT ALTER ANY CODE. Various behaviors here are already on the 3D world and some may have parameters that may be set by authors of 3rd party 3D spaces. In addition there are behaviors that may be added to sprites. This read me details these possibilities for the author. All of the behaviors that may be used by the author are on the 3D world sprite (channel 4) with the exception of the World setup behaviors which are frame script behaviors. Most of these behaviors are already on the world and one only needs to adjust their parameter. However the group classified as additional elements may be dropped onto the world as is approapriate. World Setup behaviors. "speed test" behavior frame script (under "speed test" label). Author definable parameters: minimum fps, test location, test type. This behavior does the performance checking to estimate the largest size of world that will run at an author definable frame rate. The world is set up. All the lights are switched off and all emissive properties of shaders are set to the same color as the world background. The world is now invisible but keeps the the same performance load. If the test has never been run before, an initial guess is made of the world area. The camera is now placed at the test area and either a small rotation or translation (depending on the author definable test type) is applied for over either a set period or a set number of frames. The process is repeated while changing the world size until the target frame rate is achieved. This world area is then stored in the preferences file. Notes for authors: Obviously some parts of the world are going to be more processor intensive than others. The test location should be at a point that is critical for the users experience to achieve a reasonable frame rate. Also, depending on the world, rotation or translation may be more processor intensive. The setting should be worked out by trail and error over a variety of machines in order to ensure a reasonable performance with an acceptable world size on a baseline machine. "decision point" behavior frame script (before "speed test" label). Author definable parameter: boolean This indicates whether the speed test should be run every time or just once. If the test is run every time the results from the previous test are used as the first guess. World Control Behaviors. "World Setup" behavior (on 3D world sprite) Author definable parameters: Field of View, Aspect Ratio, Show tooltips. This behavior defines the worlds Field of View and the Aspect Ratio. If an aspect ration of 0,0 is used then the world will take the same aspect ration as the browser window. The Show Tooltips behavior can disable all tooltips. "Camera Setup" behavior Author definable parameters: Inital start position, Final start position, Camera height from the ground, start position roation, max speeds, accelerations and drags or camera roation and translation, time to autopilot This behaviour allows the author to define an initial zoom in to a world (from the intial to the final start position). The camara height from the ground will override the final start positioned height as soon as any translation occurs. When a node is clicked, the camera autopilots to that node before jumping to the next Space defined by that node. This autopilot takes the author defined period of time. Notes for authors: World or diffring coordinate systems may be used in this system. If a non right coordinate world is being used you will have to set the rotation so that it appeas the right way round. The camera moves according to it's own local coordinate system. Additional Elements Behaviours "additional model" behaviour (to be dropped onto 3D world sprite) Author definable parameters: Field of View, Aspect Ratio, Show tooltips.         BITD5#c`_c`_c`_|\W[twr]W[twr]W[twr]1"bmvpaquiWbmvo\nuiWbmvmRguiWwj WYsva,$@nvpcW WYsva-%;ivpcW WYsv`0(2]vpcW,\nuuO&.A+0^sumq\nuuN'.A+/Xsumq\nuuN(.A-+Lrumq JDnvp;(Akuh?&DquZDnvo<(Akuh@(@nuZDnvn<)Bluh@)9iuZFdqt8-[uwtwu\*PtYdpt9-[uwtwu\,LtYdmt:-\uwtwu\0CtY ;CjsQkwtS:[vwmbqBChsRkwtS:[vwmbqBCesRkwtS:[vwmapB 1Hjtuxg<%%'CkxupDHhtuxg<%%'CkxupDHdtuxg<%%'CkxupD%IivuU,%)%.VsrXIevuU,%)%.VsrXI^vuU,%)%.VsrX^nuL%()'%[uE^nuL%()'%[uE^nuL%()'%[uE2cs0')&XuD2cs0')&XuD2cs0')&XuDOjt5')*)*)'YvCOjt5')*)*)'YvCOjt5')*)*)'YvC jt6')((]rQjt6')((]rQjt6')((]rQ lr5')((^qNlr5')((^qNlr5')((^qNes5')()`kKes5')()`kKes5')()`kKns6')(*ekMns6')(*ekMns6')(*ekM`u8&)(*gd`u8&)(*gd`u8&)(*gdhs8&)(+jfhs8&)(+jfhs8&)(+jfTw4"%$(miTw4"%$(miTw4"%$(mi^zRFHGJtl^zRFHGJtl^zRFHGJtl`mS[\]\]]\\JS[\]\]]\\JS[\]\]]\\JajoSajoSajoS̾{nd[J?1%   '1>GT_hr|ɸ>dkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUdkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUdkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUq_ k+ dirutqjetvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_ dirutqidtvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_ dirutphctvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_0z gottnJ++PsswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusnJ;RquuqWKgottnK++PsswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusnI9PquuqWKgottnK+,QsswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusmI8MouuqWK xAGgsuoT1(1bstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtj?&5bsuuk_GgsuoU2)1bstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtj?'4_suuk_GgsuoT3)2bstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtk?(3Zsuuk_hdEbvtj7)(1ftux\)&)('+m^tq4')**))(#:lxttL('CmuuskEbvtj8))1ftux\)&)('+m^tq4')**))(#:lxttL('BkuuskEbvtj8))2ftux\)&)('+m^tq4')**))(#:lxttM)(@iuuskWR(WlvqO,)(@otvsJ(()(/sWtr9&)&0[wutY1(+WrutgKWkvqO-)(@otvsJ(()(/sWtr9&)&0[wutZ1(+TrutgKWgvqO.))@ntvsJ(()(/sWtr9&)&0[wutZ1(,PqutgK"zCw Gguva1))3`ttug8%()'2tTwt@%)''GltulG,&6btwo[YGguva1))3_ttug8%()'2tTwt@%)''GltulG,'6`two[YGguva2))3_ttug8%()'2tTwt@%)''GltulG,(6[two[Y6[<Yrusi7))4susv`)')&:tCZvF$)*)(!CustwS)($MstxcYrusi7))5susv`)')&:tCZvF$)*)(!CustwT)(%JstxcYrusj7))6rusv`)')&:tCZvF$)*)(!CustwT))(Estxc<H(&Jputp?)(8mtsw`+')%@uE*uM$)&3justl6)),bttqDJputp?)(7ktsw`+')%@uE*uM$)&3justl6))-attqDJputq?))6gtsw`+')%@uE*uM$)&3justl6))/]ttqDF:+KrutsE)&:stsx\)')%FtItT%)'.fwssl8))0ittrdKrutsE)'8qtsx\)')%FtItT%)'.fwssk8))1ittrdKrutsF))6mtsx\)')%FtItT%)'.fwssl8))1gttrdN <_stK)%Bsx[)'('&!Lu$+qX!%%&&'())(()'+bxssr8)(3mttse_st K)&@qssx[)'('&!Lu$+qX!%%&&'())(()'+bxssr9))5lttse_st L)):nssx[)'('&!Lu$+qX!%%&&'())(()'+bxssr9))6jttseWH LsusuV/%EqssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ysC)(9pttrW LsusuV/&CqssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ysD)(:ottrW LsusuW0(?pssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ysD)):mttrWb ]Jutsui\\nsujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsst_:7@pttuVJutsui\\nsujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsst`:8@pttuVJutsui\\nsujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsst`99AnttuVixX(/@M[irm_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuV_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuV_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuVȿm\G8*  '8Jf|_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX  IN5XfAJjA5IN5XfAJjA5IN5XfAJjA5"~~}~~#@egfG@egfG@egfGZ[gtsosuPgtsosuPgtsosuPrvPzR+/-[xcPzR+/-[xcPzR+/-[xc_yH$(%T}O_yH$(%T}O_yH$(%T}OquC%)%P{_quC%)%P{_quC%)%P{_bw>&)%Lxmdbw>&)%Lxmdbw>&)%Lxmd Olt8&)%GwnDOlt8&)%GwnDOlt8&)%GwnD,rr2')%Cvn(,rr2')%Cvn(,rr2')%Cvn(+M=so,()&=trY=so,()&=trY=so,()&=trYIyaui+()&8rwbaui+()&8rwbaui+()&8rwbbJyc)()'5p{RJyc)()'5p{RJyc)()'5p{RPz\(()'1nwaPz\(()'1nwaPz\(()'1nwaiyV&)(.kuofiyV&)(.kuofiyV&)(.kuof Z|Q%)(,gvo0Z|Q%)(,gvo0Z|Q%)(,gvo0!AfyL%)(*awq1AfyL%)(*awq1AfyL%)(*awq19apvG%)()^wrUapvG%)()^wrUapvG%)()^wrUQHsuA%)'YwskHsuA%)'YwskHsuA%)'Ywsk9j2qtvLUyo6_usvg_vs?1ptvLUyo9\usvg_vs?/otvLVyp1&XusvvsE)/otu_Vyp1'XusvvsF).ntu_Vyp2*VusvvsF).ntu_hvq/))YtstI)(7qsughvq/)*YtstJ)(7qsughvq/),XtstJ))6qsug `ntu=))(Qus uG)(-mtsv^ `ntu=)Pus uG)(.ktsv^ `ntu>))*Pus uG))/htsv^  .lutn5))(MtssuK))%atssuh3.lutn5))(MtssuK))&^tssuh3.lutn5)NtssuK))*Xtssuh3)Eqtsu`-))'PvvM))$Qusv^Eqtsua-))(OvvM))&Nusv^Eqtsua-)NvvM))(Iusv^WoussuW)(IJ))&?rsvn_WoussuX)(IJ))'>rsvn_WoussuY)JJ))(;rsvn_`ntssvD)&9rtsswbR`ntssvE)'6ptsswbR`ntssvE)3ktsswbRaots9)(+ktssvk<aots9)(,gtssvk<aots:),`tssvk<D+dststd,)$Yvssun=dststd,)&Tvssun=dststd-)Hvssun=fXgtssuT))%MqtstsSgtssuU))&HptstsSgtssuV)=ntstsS}y ivssvA$WAquttXAquttXAquttXTxEvwkEvwkEvwkbFXKFXKFXKBITD5#c`_c`_c`_|\W[twr]W[twr]W[twr]1"bvzuiWbzvuzuiWbTvj=^uiWwj WYyvvpcW WYuv}vpcW WYnvULvpcW,\uuwumq\|uuuumq\Ruu;(/pumq JDv|}u߃uZDuvvvuyxuZD`vk!)huc&auZFd{tuwtwutYdutuwtwu{tYdjtPuwtwuR (tY ;C{uwtS:[vwztBCrtxwtS:[vwuzsBC`rCgwtS:[vwkXoB 1Htuxg<%%'CkxuuDHttuxg<%%'CkxusDH]tuxg<%%'CkxuoD%IvuU,%)%.VsrXIsvuU,%)%.VsrXITvuU,%)%.VsrX^nuL%()'%[uE^nuL%()'%[uE^nuL%()'%[uE2cs0')&XuD2cs0')&XuD2cs0')&XuDOjt5')*)*)'YvCOjt5')*)*)'YvCOjt5')*)*)'YvC jt6')((]rQjt6')((]rQjt6')((]rQ lr5')((^qNlr5')((^qNlr5')((^qNes5')()`kKes5')()`kKes5')()`kKns6')(*ekMns6')(*ekMns6')(*ekM`u8&)(*gd`u8&)(*gd`u8&)(*gdhs8&)(+jfhs8&)(+jfhs8&)(+jfTw4"%$(miTw4"%$(miTw4"%$(mi^zRFHGJtl^zRFHGJtl^zRFHGJtl`mS[\]\]]\\JS[\]\]]\\JS[\]\]]\\JajoSajoSajoS̾{nd[J?1%   '1>GT_hr|ɸ>dkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUdkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUdkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUq_ k+ di|ut|xvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_ divutwzywvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_ diiutmaZsvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_0z gottysswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvuszܲzuuqWKgottusswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusuuqWKgottk7@sswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusk16muuqWK xAGgyuxstx_1$&&%%$%&&'()+hatn-$&%$% (Epvtuk_Gguut}stx_1$&&%%$%&&'()+hatn-$&%$%(Epvtxtuuk_GgmumDYstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtf&Jsuuk_hdEvttux\)&)('+m^tq4')**))(#:lxtt̂uuskEwvtxutux\)&)('+m^tq4')**))(#:lxttwuuskEDvte`tux\)&)('+m^tq4')**))(#:lxtt:#cuuskWR(W~vy|tvsJ(()(/sWtr9&)&0[wutyutgKWuvvvtvsJ(()(/sWtr9&)&0[wutzvutgKWavo>'ktvsJ(()(/sWtr9&)&0[wutP:outgK"zCw Gguvttug8%()'2tTwt@%)''Gltuytwo[YGguvz|ttug8%()'2tTwt@%)''Gltuttwo[YGguvYTttug8%()'2tTwt@%)''Gltui4Mtwo[Y6[<Yrusyusv`)')&:tCZvF$)*)(!CustwstxcYruswvusv`)')&:tCZvF$)*)(!CustwstxcYrusepusv`)')&:tCZvF$)*)(!CustwE+stxc<H(&JputyՁtsw`+')%@uE*uM$)&3just}ttqDJputvvtsw`+')%@uE*uM$)&3justvzttqDJputo&`tsw`+')%@uE*uM$)&3justi RttqDF:+Kzutu܀tsx\)')%FtItT%)'.fwssttrdKuuttxtsx\)')%FtItT%)'.fwssxzttrdKjutr/htsx\)')%FtItT%)'.fwssh`ttrdN <_yt }ssx[)'('&!Lu$+qX!%%&&'())(()'+bxsswڃttse_ut wssx[)'('&!Lu$+qX!%%&&'())(()'+bxssuxttse_mt 9jssx[)'('&!Lu$+qX!%%&&'())(()'+bxsspdttseWH LsusuxssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ys}ttrW Lsusu}ussxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\yswttrW LsusuK !nssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ys-jttrWb ]JutsuysujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsstҵ|ttuVJutsuvyzusujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsstxvttuVJutsueRRksujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsstX+kttuVixX(/@M[irm_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuV_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuV_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuVȿm\G8*  '8Jf|_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX  IN5XfAJjA5IN5XfAJjA5IN5XfAJjA5"~~}~~#@egfG@egfG@egfGZ[gtsosuPgtsosuPgtsosuPrvPzR+/-[xcPzR+/-[xcPzR+/-[xc_yH$(%T}O_yH$(%T}O_yH$(%T}OquC%)%P{_quC%)%P{_quC%)%P{_bw>&)%Lxmdbw>&)%Lxmdbw>&)%Lxmd Olt8&)%GwnDOlt8&)%GwnDOlt8&)%GwnD,rr2')%Cvn(,rr2')%Cvn(,rr2')%Cvn(+M=so,()&=trY=so,()&=trY=so,()&=trYIyaui+()&8rwbaui+()&8rwbaui+()&8rwbbJyc)()'5p{RJyc)()'5p{RJyc)()'5p{RPz\(()'1nwaPz\(()'1nwaPz\(()'1nwaiyV&)(.kuofiyV&)(.kuofiyV&)(.kuof Z|Q%)(,gvo0Z|Q%)(,gvo0Z|Q%)(,gvo0!AfyL%)(*awq1AfyL%)(*awq1AfyL%)(*awq19apvG%)()^wrUapvG%)()^wrUapvG%)()^wrUQHsuA%)'YwskHsuA%)'YwskHsuA%)'Ywsk9jWAquttXAquttXAquttXTxEvwkEvwkEvwkbFXKFXKFXKThum7)V4X]534XV4]VVVVVVVV+V+VVV]54+]5]+XW5XVXXV4]V]V XW+]X5]VV+++VV+V V V V ]{4V5X 4W ]5454+W+VXW]++++STXT p#up : rect(37, 1, 61, 25) #left : rect(0, 21, 37, 46) #down : rect(35, 44, 62, 90) #right : rect(58, 21, 99, 46)BITD3 ?pcSG8*  ",7DNZhsZ [^eGgW7d=Ld1OS+X]-Pj3KkQLk]A [^eGgW7d=Ld1OS+X]-Pj3KkQLk]A [^eGgW7d=Ld1OS+X]-Pj3KkQLk]ARķ}lYA. ."0evstuG%&&%$$%%'())*+,*?tO tt?&))(''&%$%#8kvst^$7erttu\V Rutul>"0evstuG%&&%$$%%'())*+,*?tO tt?&))(''&%$%#8kvst^$7erttu\V Rutul>"0evstuG%&&%$$%%'())*+,*?tO tt?&))(''&%$%#8kvst^$7erttu\VTgR7ruuj7#)avstuN%()(%;tOtt>%()%6mvsta$1arttulM7ruuj7#)avstuN%()(%;tOtt>%()%6mvsta$1arttulM7ruuj7#)avstuN%()(%;tOtt>%()%6mvsta$1arttulM_gR;uuth/%'[tstwP&()&&)%6kwst_#,\nusvb ;uuth/%'[tstwP&()&&)%6kwst_#,\nusvb ;uuth/%'[tstwP&()&&)%6kwst_#,\nusvb `gR;rvsc,&(QutsuS(()&&)%8jvsuY%*UntswZ:;rvsc,&(QutsuS(()&&)%8jvsuY%*UntswZ:;rvsc,&(QutsuS(()&&)%8jvsuY%*UntswZ:jhR?wutW#''RvtsvU%()&&)%3husv_&&FkuswjN?wutW#''RvtsvU%()&&)%3husv_&&FkuswjN?wutW#''RvtsvU%()&&)%3husv_&&FkuswjNdb[cttsl>%'LrusvV'()&%'LrusvV'()&%'LrusvV'()&%()%6mvstrttulM7ru }vstuN%()(%;tOtt>%()%6mvst|rttulM7ruu\DvstuN%()(%;tOtt>%()%6mvstU0rttulM_gR;uuttstwP&()&&)%6kwstnusvb ;uutx~tstwP&()&&)%6kwstznusvb ;uutW;tstwP&()&&)%6kwstR(nusvb `gR;rvsxtsuS(()&&)%8jvsuσtswZ:;rvsvtsuS(()&&)%8jvsuyvtswZ:;rvsM/rtsuS(()&&)%8jvsuJ"[tswZ:jhR?wutvtsvU%()&&)%3husvuswjN?wut~vtsvU%()&&)%3husvvyuswjN?wut;,vtsvU%()&&)%3husvSMuswjNdb[cttsuusvV'()&>M>@fdceٸfdceE0"fd?{efNF__FF\fefxfef6&CC&&Tf?eeSM` f'KT9T9T99T`MM_dee fU]Ӑvvvvzdee>M>@fdceٻfdceE0"fd?{efNF__FF\fefxfef6&CC&&Tf?eeSM` f'KT99TB9]`MM_dee fU]Ӑvvvzdee>M>@fdceٻfdceE0"fd?{efNF__FF\fefxfef6&CC&&Tf?eeSM` 9f9f9T9T9TB9]`MM_dee vӹvvvvvzdee?@AABhBCADEFGHIWK LNPRpS0SST.TyTiSRQPONMM%LGKpJJJDJ IIIHDGFFENDCBB'A`@??>:=n<;;:/9Y8l7754J21i/.- +*/('z&K%#"!^dcYEs {Fx P(|Iݷ4YvԓҾE͋,ȃIôz̽XӶ]GTi|!Y^Ƨ;Q)[lVkF|v8cuҷ*X Eģ&ǣʪN,թY;W B~@ 0qX!_$K';* ,/l1479z;>h@C;EHJLO:QTV:XtZ\_-aQcwegikmoOqrtvuwJxz{j|}A}~5I~~~}}|c{Fz)ywvu4srsqonFlkyjhgecbU`^\ZiX.USQ4NLIIGDDBv@ =;:86y4 1/Y-*(R& #!f%" 2 [ ,3Kj9|Oګ@]rƤEۿ{&˸? iup{K}3ɔa~5ċ)r5i؊0Nj\Îhgᒫw>Hՠ%ma/Юv#賻}Esʏ̞Ω2Et-oi4m5 Vr. "%(*-)/2$469(;s=@BADFIKVMOQSUWYWZ\^<_aWbdeZfgi,*(z&\$W"] [Q5[ fk 4(h$\&סj;--(&04DWuLA殐H  *Mk_Ġ&ў|OC_̟>pD夻f?ߪ&?f<R m4v ȩH͜X3֝؏ڃ{lnc:{.6vaF0$1D` 5Pux q"e$/&')+v-J/024s6F79;<>Z?@BBC}DEFGHIJKLMNOtPAPQnQRSSoSSTTVThTETSSS[RRaQQ@POO3N[MLKJI|HHGEDCA@.>=:;:b87643810R.-d+*(h&$#L!2E1k AuI|'_d _]>}۽4֌Z9Ω-˵DWď2p# ߺйɷ+L}г#u˱-*ͭw!ɬYOB61^7!Fk" /c4SIŽ7ȳDLlӤI؆2ݟKHzc naG\cms n`G* v!=!#G$&(E)+-C.02835w78:.;=>?AQBCE:FGHJ-KYLMNOP|Q_R@SSTU:UVW9WXMXYeYZ!ZhZZ[&[<[2[*[![ZZZKYYY7XWW8VUTSRQPONMmL'JIHFFElDBA?>k?B@@ABhCCD5DE8EFFjFFGIGGGGHH,H5H1H*H"HHGGGvGBGFFxF(EEEDD CCBA@@ ?3>U=`'>r>>?0?m?????????X?'>>>b> ==^=<<4;;`::l99-877>6g5432110/+.8-C,3+%*('&%n$-"! S>Z^u ) Nf}1M}!Sq)`AߜwU?)3Z΃ͯ7ˆ-ɆR0ƙŤ7YâZŽU#q<Và<Ċ(ŋyfȌ8ʐC ϼЧљ҉tcVV_hzڌ۟RaBR"z]{Ca+; - #mZ)nO ~!"#$%&'()*+,-k.L/#/012U234'45I56N67M78I89:9:.:y::;;*;L;=;*;;:::::::::[:.:99988077J66F55B44!3l221S0/..-7,\+v*)('&%$#"!n ]F2M:b N'qR+xbD(oVS_emv)Kbx߹P܆۽kM1ױ7DVqӍp$ьG:/$*?Rf{Ѣ7aґ!VӾ&Ԋ`pח/t$ۄ8ވNqI'   :n,DZz~~vmw 5MaxgW># {!^"@##$m%%&''(J(){***+z+,j,- -[--.O../X//0080V0r000000~0q0C0////N/ ...=---,,A++Q**4))(''=&%%K$##"]! At )>Tl >V \ ] [ R SPK8/%'>` ,F`v>p Ay6+IUL(+6߃Cިk"݇<ܠsD)Knܵ7gݘ$hް=ߌtG(1\'h%},9SZBNj0yF6@d!:{*,@Uk    f8\H|*heB5(reV5af # f R!WhV>4Ac~F:!0/3)w!uENm#v4rlN3)08>CHw|+[y5dL\LBUao:p NrLCs,M\I I 4 % aU*"54Y~ [G2Y6ICl_kQ*WHK3:8&_N6[v I  ] E( mQ,l2/Ed4 vSL.?X= j2g F"/eG)A$yh]Y(3?KK;/=/^<<&=Z~e,M6YRT']3_% > N ` l S Q+(du$~F.fDrTOJA1Z,o3t5kq93c O w  - x]UDIDB7+ ?xT 7agS[4a%j1OJg5mWCm_RG;/$UKA74@Ph9;oU L w ZN)=b^yM~N#{,CW~DZQ@3nUAwH , g {  A l  , E _ R e p x ~ p }  r d .  j M 2  S "]*tDc1b/wBp~2j {H~JrA e3{JvIqdAmQ6v]jVB.    :?DL\l}3P6w+Rx'Nu/Z$V$Y*]GtAj 4El$,Qt8Vs)@WppHA9.# n.ycO:$ nS7~eK0z_7lVA*{h^N<- wkcYd[QG=2(7-%   67789;<^_`adhjBITD 7?]ccfecc^]ccfecc^]ccfecc^?{Omefdefeddfmefdefeddfmefdefeddfcsmde]NF>6FFTefdmdelw}}}refdmdeW@3&33JefdKc UffN-*9ad]Uffxid]UffA ]d]7Sfe[52[eo[22DeeUfepeeUfeT?KooW?/eeUsffe>9e\_|w99Tfcffeeh}fcffe!LY]yaFfc'GbfZAADZAAGeebfzPfޕڨeebfP!!AV!!-ee?_eeWIINKIffee]Z״ffeeH**IF}*ff?_ee[QQkMyXQffee}_iffeeL33fHtR3ff?_ee_XX H,5Xffee ]@JffeeQ<cj+@vLv`ffee cW{CYdffeeVFF_ Ce7\c$9_E_Fff?_eegh 7^;(7TL9hahffee RyVDSphU|ffeeZO /V3 0LE2OYOff?_eekp @Z!!Ce,8Xpffee [u<<^GSsffee_X 9S<^$1QXff?_eenw 3{B#%*F|HwXwffee M]>@E`csffeeca ,t;$?uBaRaff?_eer sgW0'(7ffee qJABQffeehj l`P*!"j1jff?_eevS(*y>ffeelACWffeelsM"$s8sff7Wffuv1~v`edffIyedffn}q+xq}[}zed7^ei~Ukv~ef^enm棎ef^ehyPfquefgmfe{Dniddmfe[oddmfezv?ihdd'Cbdf[recbdfqցecbdfVoec?S Uede|jfe]Uedeofe]Uedexife]+ϓ?UedemUedemUedemGwS#^eedefU^eedefU^eedefUThumC7)+++++VVVVV+V||V+V+V|uuQuQuQuQuQVuQuQu{v+ u+%+%++%++%{+%++%+&u{V VPP&P,P&J,PV,J&P+Pv++||P ,JPPJ,PVPWPv|+ {vQPPQPQPP{VPP,QPQPPQPvv ||vPuQQuPVVVQuQuPQuPQv|+ {v{vuQuQ{VQuPQuuQuuvuv +{vuuvuvuV|uPuvuvuv{vu+{uuvuvPЂ{Puuvuvuu{QuQuQQPQuuQuQu+ {QuuQuQu{VPuQuQuQuQuQu+ +{QoPQKtQQuJPQKuQuJQQoPQQ V{PKQJuQJQJQJ{{KKPKPKtQQJu+ VQJPKPJQJPKPQz{P{PKPJQJPJQzVVKJPJQJJQJPJJ{JJPKJPKPJPPJJ&PJJ,JJ,JVVJ,JPVV{P&JJ&JJ&JJ&JJ&J&J&JJ,PV+++BITDS 7?]ccfecc^]ccfecc^]ccfecc^?{Omefdefeddfmefdefeddfmefdefeddfcsmde]NF>6FFTefdmdelw}}}refdmdeW@3&33JefdKc UffN-*9ad]Uffxid]UffA ]d]7S fe[52[eğo[22DeeU fepײ۹eeU feT?KooooW?/eeUsffe>9e\_|ȍw99Tfcffeeh忢}fcffe!LY]y˿aFfc'GbfZAA yDZ|AAGeebfz yPfޕ|ڨeebfP!! yAV|!!-ee?_eeWII NKcIffee ]Z״effeeH** IF}c*ff?_ee[QQkMyXQffee}_iffeeL33fHtR3ff?_ee_XX H,5Xffee ]@ͣJffeeQ<cj+@FLv`ffee cW{CY^dffeeVFF_ Ce7\c$9?E_Fff?_eegh 7^;(7TL9ahffee RyVDSphU|ffeeZO /V3 0LE2YOff?_eekp @Z!!Ce,8Xpffee [u<<^GSsffee_X 9S<^$1QXff?_eenw 3{B#%*F|HjXwffee M]>@E`csffeeca ,t;$?uBcRaff?_eer sgW0'(X7ffee qJABrQffeehj l`P*!"R1jff?_eevS(*y;`ffeelACR`ffeelsM"$ss5`sff7Wffu Bv1~v`edff FIyedffn} Aq+xq}[}zed7^ei ~Ukv~ef^en m棎ef^eh yPfquefgmfe{Dniddmfe[oddmfezv?ihdd'Cbdf[<recbdfq<ցecbdfV<oec?S Uede|jfe]Uedeofe]Uedexife]+ϓ?UedemUedemUedemGwS#^eedefU^eedefU^eedefUThum97)+++++VV+V||V++V|u{QQ{QuQ{+PuQuQ*v|V+ u,%+%%+%++++%+%u{V VQI,,JP&PV&,I,P|+|vP V+VPPPvv+ +{vQPQPPQPP{{VVP,PQPPQP|v+ |v|tQQtQPVWVPQQtQQtQ|v {|vuQuuQ{VWPuQuuRuvuv+ {vuvuvuvP{Puvuvuvuvu+{uvu|{V,uuvuvuu+ {QuuQuQu{{{OuQuQuuQuu+ {QuQuQuQ{{VPPQuQuQuQuQ {QKuQoQQuQKV{QQoQQoQuKQ+ {PKPQJQJQJ{{QPVQJtQJQPQ+ KPKPJQJPJQ{PQVPKPKPJ{VJPJQJPWJPJJ{PPPJJPJJQWJ JPJJP&VVJJJPPV+ VP&P&J&J&J&J &JJ&J&PJP+ + +Thumd7) projectorXMED.FFFF000000060004000177AA00000000004D000000004000110000001-7FFC6FE00480048-10E0-10 E470107000010000003000000001078401010E47038E00011E36000020000000B000000007,7.5 fps00040000000900000002029200050000000900000002019000060000009D0000000320C310FFFF0C00000 10 10B30FFFF0C00000 20 10B30FF000FFFF0C00000 10 00070000004600000002010174618001801010174618001800008000001690000000240,Geneva40,1040304E44000104004000801040,Arial40,10407D104E440001040040008010000900000011000000020E470E47000A00000011000000020E470E47000B00000005000000020000C000000140000000170D16002F1000F0000002100000000400 10  00130000007E00000000DA91F8CE1C1D1E1F7F1B044,-..'"FFFF0FFFF001280000000A000000019001290000000A0000000190STXT Family: 69 Culture: 70 Science: 72 Technology: 73 Architecture: 74 Religion: 75 Conflicts: 76 Media: 77 Construction & Engineering: 78 Social Service: 79 Governance: 80 Commerce: 81 Sports & Recreation: 82 Communities: 83 KEY* d0STXTBITDThumSTXTBITDThumBITDThumSTXTBITDThumBITDThumBITDThum ALFA BITD Thum!Thum!XMED$Thum$XMED%Thum%XMED)BITD)Thum,Thum/Thum/XMED0snd 0sndH0sndS3Thum5Thum5XMEDHBITDHThumIBITDIThum JSTXTBITDThumCAS*CinfDRCFFmapLctXVERSVERSccl VERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSVERSccl DRCFTT::;<,61Cinf~^`|kBMacintosh HD:Users:richardross:Documents:ManyOne:phase2.1:dswmediaCAS*   !"#$%&'()*,-./0I123456JHCAStB 4--/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- on dummy -- this behaviour creates a space in the behaviour drop down menu. It is not used for anything else. end--|0N,>Fn>richard rossCASt] O--/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- on dummy -- this behaviour creates a comment in the behaviour drop down menu. It is not used for anything else. end*** world manager behaviors(B^,>Fn>richard rossCASt $1READ MEbb>7ۯ>richard rossCASt  -- initiate -- UI cntrl --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| These are private interface handlers --\--------------------------------------------------------------------------- global gUI_control_obj global goWinMgr global goNodeMgr --/--------------------------------------------------------------------------- --| These are private interface handlers that --| This must be called from the main preparemovie handler --\--------------------------------------------------------------------------- on ini_UI_control gUI_control_obj = script("UI control parent").new() end --/--------------------------------------------------------------------------- --| This must be called fomr the main stopmovie handler --\--------------------------------------------------------------------------- on UI_control_stopmovie if objectP(gUI_control_obj) then gUI_control_obj.mDestroy() gUI_control_obj = VOID end if end --/--------------------------------------------------------------------------- --| This services the widgets --\--------------------------------------------------------------------------- --on enterframe -- -- -- run the widgets -- -- CDH_enterframe() -- --end --/--------------------------------------------------------------------------- --| get_prefs_nm --| Work out the movie name tag for writing prefs --\--------------------------------------------------------------------------- on get_prefs_nm sufx nm = the moviename if nm contains "." then nm = char 1 to offset(".", nm) -1 of nm end if if nm.length > 15 then nm = char 1 to 15 of nm put "_"&sufx after nm snm = symbol(nm) return snm end ini_UI_control| 0Xcc,>Fn>richard rossCAStd ddd&d&d&d&d:d:d:d:d:d:dNdNdNdNdNdNdRdVdc--UI --MGR --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- property pUI_inst_list property pMserviceList property pMrelocate_UI property pBottom_UI_element_list property pUI_element_seperation property pUI_btm_elements_rects property p3D_sprite_rect property pBrowser_frame_rect property pUsable_3D_area property p3DArea_maxed property pUI_is_setup property pAuto_pilot property pShowing_widgets property pCsr_fdbk_obj property pUse_alpha property pCsr_fdbk property pScrlback_inst property p3DArea property pUI_height property pMax_b_area property pLights_on property pLights_lst property pCampos global goNodeMgr global goWinMgr global goNetMgr --/--------------------------------------------------------------------------- --| constructor --\--------------------------------------------------------------------------- on new me me.minit() return me end --/--------------------------------------------------------------------------- --| destructor --\--------------------------------------------------------------------------- on mDestroy me -- cleanup objects in lists cnt = pUI_inst_list.count repeat with n = 1 to cnt pUI_inst_list[n] = VOID end repeat pUI_inst_list = VOID cnt = pLights_lst.count repeat with n = 1 to cnt pLights_lst[n] = VOID end repeat pLights_lst = VOID pCampos = VOID cnt = pMserviceList.count repeat with n = 1 to cnt inst = pMserviceList.getPropAt(n) inst = VOID end repeat pMserviceList = VOID cnt = pMrelocate_UI.count repeat with n = 1 to cnt pMrelocate_UI[n] = VOID end repeat pMrelocate_UI = VOID pCsr_fdbk_obj.mDestroy() pCsr_fdbk_obj = VOID end --/--------------------------------------------------------------------------- --| mInit --\--------------------------------------------------------------------------- on mInit me pUI_is_setup = FALSE if (goNetMgr.ilk = #instance) then prf_mn = get_prefs_nm("max_fnd") prefs = goNetMgr.mGetPref(prf_mn) end if if voidP(prefs) then p3DArea_maxed = 0 else p3DArea_maxed = value(prefs) end if pMax_b_area = 0 me.mSet_browser_dims() -- all instances of behaviours attached to UI elelments get registered here pUI_inst_list = [:] -- get any UI elements that have already come alive (obviously gets nothing if this is called from on prepare movie, but ... just incase it's moved) aList = [:] sendAllSprites(#mRegister_UI, aList) sort aList cnt = aList.count repeat with n = 1 to cnt type = aList.getPropAt(n) inst = aList[n] me.mRegister( type, inst ) end repeat sort pUI_inst_list pUI_element_seperation = 15 -- if any new UI elements are added their IDs should be added to this list. -- This also defines the L to R order that the elements will appear in. pBottom_UI_element_list = [] pBottom_UI_element_list.add(#infobtn) pBottom_UI_element_list.add(#helpbtn) pBottom_UI_element_list.add(#btnnav) -- these are the comms lists and will be populated with the groups of objects requiing these specific events pMserviceList = [:] pMrelocate_UI = [] pShowing_widgets = FALSE pAuto_pilot = FALSE pCsr_fdbk_obj = script("cursor feedback object").new() -- work out if the renderer will support an alpha chanel supported_alph_list = getRendererServices().getHardwareInfo().supportedTextureRenderFormats if supported_alph_list.findPos(#rgba8888) then pUse_alpha = 1 else pUse_alpha = 0 end if -- props to store light data for speed testing pLights_on = TRUE pLights_lst = [:] -- register to recieve resize events from the winmgr if (goWinMgr.ilk = #instance) then goWinMgr.mRegSetWH(me) else -- use my resize control --xxxx end if -- add to the actorlist (the actorlist).add(me) end --/--------------------------------------------------------------------------- --| mNewStgWH --| Resize event received from the winMgr --\--------------------------------------------------------------------------- on mNewStgWH me, w, h new_area = integer(w)*integer(h) old_max_area = pMax_b_area -- reset browser dimensions in the UI control object me.mSet_browser_dims(w, h) pUI_is_setup = FALSE if new_area > old_max_area and not p3DArea_maxed then put "doing speed test" go to "speed test" else put "not doing speed test" -- if this new area is less that the -- now we can set up the screen. me.mSetUp_UI () -- just incase we have a scrolling background we should set this up too. me.mSetUp_background() end if end --/--------------------------------------------------------------------------- --| mSet_browser_dims --| Set the stored browser frame dims --\--------------------------------------------------------------------------- on mSet_browser_dims me, browser_frame_width, browser_frame_height if voidP(browser_frame_height) then -- get the browser frame rect if not passed if goWinMgr.ilk = #instance then wh = goWinMgr.mGetWH() -- pt = point(w,h) browser_frame_width = wh[1] browser_frame_height = wh[2] else rct = (the stage).rect browser_frame_width = rct[3] - rct[1] browser_frame_height = rct[4] - rct[2] end if end if pBrowser_frame_rect = rect(0, 0, integer(browser_frame_width), integer(browser_frame_height)) new_b_area = pBrowser_frame_rect[3]*pBrowser_frame_rect[4] if new_b_area > pMax_b_area then pMax_b_area = new_b_area end --/--------------------------------------------------------------------------- --| stepframe --| If there is a service list then service everything that needs --| continuous action. --\--------------------------------------------------------------------------- on stepframe me if not pUI_is_setup then exit -- check for keydown if pShowing_widgets then if me.mCheck_nav_key_down() then me.mHide_widgets() end if end if -- add resize checking here xxx Do it on an interval -- no servicing if the widgets are showing if pShowing_widgets then exit -- service the threads that need servicing cnt = pMserviceList.count tm = the timer repeat with n = 1 to cnt nextTime = pMserviceList[n][1] if tm > nextTime then pMserviceList.getPropAt(n).mService() pMserviceList[n][1] = tm + pMserviceList[n][2] end if end repeat end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me, type, inst pUI_inst_list.addProp(type, inst) end --/--------------------------------------------------------------------------- --| mFind_3D_world_mbr --| passes back the 3D world sprite --\--------------------------------------------------------------------------- on mFind_3D_world_spr me inst = me.mGet_inst(#world) if inst = 0 then alert "lost world behavior mFind_3D_world_spr" end if return inst.spritenum end --/--------------------------------------------------------------------------- --| mGetUI_locations --| works out the areas usable for interface elements --\--------------------------------------------------------------------------- on mGetUI_locations me -- poll the UI elements and find the highest member dimslist = [:] pUI_btm_elements_rects = [:] offset_RHS = 0 min_t = pBrowser_frame_rect[4] -- use the long way round to insure that people who add new UI elements do use the requistite handler repeat with n = pBottom_UI_element_list.count down to 1 type = pBottom_UI_element_list[n] inst = pUI_inst_list.getAProp(type) if not objectP (inst) then nothing alert "lost instance of "&pBottom_UI_element_list[n] end if if not inst.handler(#mGet_dims) then alert "you need a mGet_dims handler in the behaviour for "&&string(pBottom_UI_element_list.getPropAt(n)) else inst.mGet_dims(dimslist) end if -- now work out the placing of these UI elements -- we're are counting elements from r to l -- if an element is not going to be thre there will be no entry in the list (ie it does not return it's dims in the get_dims) dims = dimslist.getAProp(type) if listP(dims) then offset_RHS = offset_RHS + dims[1] + pUI_element_seperation l = pBrowser_frame_rect[3] - offset_RHS t = pBrowser_frame_rect[4] - (pUI_element_seperation + dims[2]) r = l + dims[1] b = pBrowser_frame_rect[4] - pUI_element_seperation pUI_btm_elements_rects.addProp(type, rect(l,t,r,b)) end if end repeat end --/--------------------------------------------------------------------------- --| mFind_usable_area_rect --| works out the areas usable for the 3D world --| and an area below for the UI controls --\--------------------------------------------------------------------------- on mFind_usable_area_rect me if voidP(pUI_height) then -- poll the UI elements and find the highest member dimslist = [:] pUI_btm_elements_rects = [:] offset_RHS = 0 min_t = pBrowser_frame_rect[4] -- find the hightest UI element repeat with n = pBottom_UI_element_list.count down to 1 type = pBottom_UI_element_list[n] inst = pUI_inst_list.getAProp(type) if not objectP (inst) then alert "lost instance of "&pBottom_UI_element_list[n] if not inst.handler(#mGet_dims) then alert "you need a mGet_dims handler in the behaviour for "&&string(pBottom_UI_element_list.getPropAt(n)) else inst.mGet_dims(dimslist) end if end repeat tmaxH = 0 repeat with n = dimslist.count down to 1 dims = dimslist[n] h = dims[2] if h > tmaxH then tmaxH = h end repeat pUI_height = tmaxH + pUI_element_seperation*2 end if pUsable_3D_area = rect(0,0,pBrowser_frame_rect[3], pBrowser_frame_rect[4] - pUI_height) -- tell the window manager what the width of the world control button area is -- so that when the minimise buttons are placed they start stacking on a second (and thrid, etc) -- level when they reach this point if goWinMgr.ilk = #instance then goWinMgr.mSetProp(#worldBtnW, (offset_RHS + pUI_element_seperation)) end if return pUsable_3D_area end --/--------------------------------------------------------------------------- --| mGet_sprite_WH --| This works out the rect of the sprite for a particular area based on the --| uasable area and the aspect ratio --\--------------------------------------------------------------------------- on mGet_sprite_WH me, area -- work out the rect from the aspect ratio bw = pUsable_3D_area[3] bh = pUsable_3D_area[4] -- -- just in case -- if voidP(pAspect_ratio) then -- inst = me.mGet_inst(#world) -- if inst = 0 then -- alert "lost world behavior" -- else -- pAspect_ratio = inst.pAspect_ratio -- end if -- end if -- -- -- if pAspect_ratio = [0,0] then aspectW = bw aspectH = bh -- else -- aspectW = pAspect_ratio[1] -- aspectH = pAspect_ratio[2] -- end if factor = sqrt( float(area)/(aspectW*aspectH) ) w = aspectW*factor h = aspectH*factor -- check that neither is greater than the browser frame w and h -- check w if w > bw then h = bw*aspectH/aspectW -- check we're not making h too big if h > bh then h = bh end if w = h*aspectW/aspectH end if -- check h if h > bh then w = bh*aspectW/aspectH -- check we're not making h too big if w > bw then w = bw end if h = w*aspectH/aspectW end if return [integer(w),integer(h)] end --/--------------------------------------------------------------------------- --| mSet_up_comms --| this checks all the registered behaviours for the presence of various key handlers: --| mService and mRelocate_UI. It makes lists of the instances that want these call. --\--------------------------------------------------------------------------- on mSet_up_comms me repeat with n = pUI_inst_list.count down to 1 inst = pUI_inst_list[n] if inst.handler(#mService) then tm_lst = [] tm_lst.add(0) tm_lst.add(inst.pServIntvl) pMserviceList.addProp(inst, tm_lst) end if if inst.handler(#mRelocate_UI) then pMrelocate_UI.add(inst) end if end repeat -- do we want the cursor feedback inst = me.mGet_inst(#world) if inst = 0 then alert "lost world behavior mSet_up_comms" end if if inst.pShow_tt then pCsr_fdbk = 1 else pCsr_fdbk = 0 end if -- add the cursor feedback obj to the pMserviceList if pCsr_fdbk then tm_lst = [] tm_lst.add(0) tm_lst.add(pCsr_fdbk_obj.pServIntvl) pMserviceList.addProp(pCsr_fdbk_obj, tm_lst) end if -- if there is a button nav object it needs to know about the main nav control obj and vice versa inst = me.mGet_inst(#btnnav) mNav_Inst = me.mGet_inst(#mainNav) if objectP(inst) then mNav_Inst = me.mGet_inst(#mainNav) if objectP(mNav_Inst) then inst.mSet_main_nav_control_obj(mNav_Inst) mNav_Inst.mSet_button_nav_control_obj(inst) else alert "lost main nav object" end if else -- no button nav mNav_Inst.mSet_button_nav_control_obj(0) end if end --/--------------------------------------------------------------------------- --| mAdd_secondary_3D_mems --| After all the 3D media is loaded we must see if there are any secondary 3D media --| attatched with the "additional model" behaviour. If so they must add their models to the world. --| Also check for a background. --\--------------------------------------------------------------------------- on mAdd_secondary_3D_mems me repeat with n = pUI_inst_list.count down to 1 -- look for the add model behavior instances and tell them to add their models to the world if pUI_inst_list.getPropAt(n) = #addModel then inst = pUI_inst_list[n] inst.mImport_models() end if -- look for the model picker behavior instances and tell them to initial their models if pUI_inst_list.getPropAt(n) = #pickedModel then inst = pUI_inst_list[n] inst.mSetup() end if -- look for the add image behavior and create plane with the image mapped onto it if pUI_inst_list.getPropAt(n) = #addImage then inst = pUI_inst_list[n] inst.mAdd_image() end if end repeat -- incase we ghave a scrolling background me.mSetUp_background() end --/--------------------------------------------------------------------------- --| mSetUp_background --| This checks for a scrolling background behaviour and if there is one, the background is set up --\--------------------------------------------------------------------------- on mSetUp_background me -- if there is a scrolling background behavior we must init it repeat with n = pUI_inst_list.count down to 1 -- look for the scrolling background behavior if pUI_inst_list.getPropAt(n) = #scrlback then inst = pUI_inst_list[n] pScrlback_inst = inst inst.mInit() end if end repeat --/--------------------------------------------------------------------------- --| mSetUp_UI --| ( re ) locates all the UI elements according to the new browser window size --| and the new sprite rect --\--------------------------------------------------------------------------- on mSetUp_UI me, tD_area -- dev if pUI_is_setup then exit end if pUI_is_setup = TRUE me.mFind_usable_area_rect() if not voidP(tD_area) then -- if the speed test result is not greater than the last speed test the we'll say we've reached the max -- Flag is so we never have to speed test again. Make sure we are testing with a usable area larger than the test area. -- if not p3DArea_maxed then -- -- possible_area = pUsable_3D_area[3]*pUsable_3D_area[4] -- if tD_area < possible_area then -- -- p3DArea_maxed = TRUE -- -- -- store this in the prefs for next time -- -- prf_mn = get_prefs_nm("max_fnd") -- goNetMgr.mSetPref(prf_mn, "1") -- end if -- end if p3DArea = tD_area end if -- centre the 3D sprite in the usable area p3D_sprite_rect = me.mGet_sprite_rect(p3DArea) me.mGetUI_locations() ---the last param is dev only call(#mRelocate_UI, pMrelocate_UI, p3D_sprite_rect, pUsable_3D_area, pUI_btm_elements_rects, pBrowser_frame_rect) -- if there is a scrolling background behavior we must init it repeat with n = pUI_inst_list.count down to 1 -- look for the scrolling background behavior if pUI_inst_list.getPropAt(n) = #scrlback then inst = pUI_inst_list[n] inst.mInit(p3D_sprite_rect) end if end repeat go to "loop" -- init the cursor feedback object pCsr_fdbk_obj.mInit(me.mFind_3D_world_spr() ) end --/--------------------------------------------------------------------------- --| mGet_sprite_rect --| get the 3D world rect --\--------------------------------------------------------------------------- on mGet_sprite_rect me, tD_area me.mFind_usable_area_rect() browser_frame_area = pUsable_3D_area[3]*pUsable_3D_area[4] if tD_area > browser_frame_area then tD_area = browser_frame_area end if wh_list = me.mGet_sprite_WH(tD_area) threeD_w = wh_list[1] threeD_h = wh_list[2] ua_w = pUsable_3D_area[3] - pUsable_3D_area[1] ua_h = pUsable_3D_area[4] - pUsable_3D_area[2] diff_w = (ua_w - threeD_w)/2 diff_h = (ua_h - threeD_h)/2 sr = rect(pUsable_3D_area[1] + diff_w, pUsable_3D_area[2] + diff_h, pUsable_3D_area[3] - diff_w, pUsable_3D_area[4] - diff_h) return sr end --/--------------------------------------------------------------------------- --| mShow_widgets --| hide the 3D world (show a screen grabbed bitmap) and display the widgets --\--------------------------------------------------------------------------- on mShow_widgets me pShowing_widgets = TRUE me.mHide_world() if goNodeMgr.ilk = #instance then goNodeMgr.mShowItemUIs() end if -- make sure screen button is in hide state inst = me.mGet_inst(#infobtn) if inst = 0 then alert "lost infobtn behaviour" inst.mChange_state("hide info") end --/--------------------------------------------------------------------------- --| mHide_widgets --| Show the 3D world and hide the widgets --\--------------------------------------------------------------------------- on mHide_widgets me pShowing_widgets = FALSE if goNodeMgr.ilk = #instance then goNodeMgr.mHideItemUIs() end if me.mShow_world() -- make sure screen button is in show state inst = me.mGet_inst(#infobtn) if inst = 0 then alert "lost infobtn behaviour" inst.mChange_state("show info") end --/--------------------------------------------------------------------------- --| mHide_world --| For the sake of speed we screengrab the 3D world and put it into the background sprite. --| Then move the world off stage and make sure that no more mServicing is called. --\--------------------------------------------------------------------------- on mHide_world me --xxxx world_inst = me.mGet_inst(#world) if world_inst = 0 then alert "lost world behavior mHide_world" -- make sure the bitmap is off stage sg_inst = me.mGet_inst(#scrngrb) if sg_inst = 0 then alert "lost screen grab behavior" -- screen grab and locate (it can't be DDS to screengrab) wspt = sprite(world_inst.spritenum) wspt.member.directtostage = 0 updatestage sg_inst.mScreen_grab(p3D_sprite_rect, wspt.member) -- hide world world_inst.mHide() --rrt --wspt.member.directtostage = 1 end --/--------------------------------------------------------------------------- --| mShow_world --| Move the world back on stage and start mServicing --\--------------------------------------------------------------------------- on mShow_world me -- show world inst = me.mGet_inst(#world) if inst = 0 then alert "lost world behavior mShow_world" inst.mShow(p3D_sprite_rect) updatestage -- make sure the screengrab is off stage sg_inst = me.mGet_inst(#scrngrb) if sg_inst = 0 then alert "lost screen grab behavior" sg_inst.mHide() end --/--------------------------------------------------------------------------- --| mFly_camera --| This tells the nav behaviour to initiate the interpolation to mdl --\--------------------------------------------------------------------------- on mFly_camera me, mdl_or_trans, pass_cntl_flag, beh_inst inst = me.mGet_inst(#mainNav) if inst = 0 then alert "lost world behavior mFly_camera" inst.mStart_interp(mdl_or_trans, pass_cntl_flag, beh_inst) end --/--------------------------------------------------------------------------- --| mGet_inst --| Gets the instance of a particular type of behaviour --\--------------------------------------------------------------------------- on mGet_inst me, type inst = pUI_inst_list.getAProp(type) if objectP(inst) then return inst else return 0 end if end --/--------------------------------------------------------------------------- --| mCheck_nav_key_down --| Check to see if any arrow keys are pressed or nav buttons clicked --\--------------------------------------------------------------------------- on mCheck_nav_key_down me if keypressed(123) then return 1 else if keypressed(124) then return 1 else if keypressed(125) then return 1 else if keypressed(126) then return 1 end if end if end if end if -- check for clicking on the nav buttons inst = me.mGet_inst(#btnnav) if inst.pClicked_state then return 1 end if return 0 end --/--------------------------------------------------------------------------- --| mSet_csr_fdbk --| Pass fedback info to cursor feedback obj --\--------------------------------------------------------------------------- on mSet_csr_fdbk me, model, data pCsr_fdbk_obj.mAdd_to_fdbk_data(model, data) end --/--------------------------------------------------------------------------- --| mCheck_node_click --| The world has been clicked - the cursor feedback --| obj can work out if we have clicked on a node --\--------------------------------------------------------------------------- on mCheck_node_click me pCsr_fdbk_obj.mCheck_mse_click() end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Acessor method for pBrowser_frame_rect --\--------------------------------------------------------------------------- on mGet_browser_frame_rect me if voidP(pBrowser_frame_rect) then alert "pBrowser_frame_rect not yet initted" else return pBrowser_frame_rect end if end --/--------------------------------------------------------------------------- --| mLights_on --| Acessor method for world lights and shaders turne off for speed test --\--------------------------------------------------------------------------- on mLights_on me if pLights_on then return TRUE else return FALSE end if end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Mutator method for world lights and shaders turne off for speed test --\--------------------------------------------------------------------------- on mStore_Lights me, aList pLights_lst = aList pLights_on = FALSE end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Acessor method for world lights and shaders turne off for speed test --\--------------------------------------------------------------------------- on mGet_lights me pLights_on = TRUE return pLights_lst end --/--------------------------------------------------------------------------- --| mStore_campos --| Mutator method for camera transform --\--------------------------------------------------------------------------- on mStore_campos me, aTrans pCampos = aTrans end --/--------------------------------------------------------------------------- --| mGet_browser_frame_rect --| Acessor method for camera transform --\--------------------------------------------------------------------------- on mGet_campos me return pCampos end UI control parent0,>Fn>/richard rossCASt    --load --models --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| this is a frame script that ensures that all the models are loaded --| before we procede. It also sets up the comms in the UI control object. --| This assumes that all of the UI related sprites have come alive and registered. --\--------------------------------------------------------------------------- global gUI_control_obj global gDBG property p3DMember_list on beginsprite me -- set up the comms lists in the gUI_control_obj gUI_control_obj.mSet_up_comms() p3DMember_list = [:] -- find all models cnt = the number of members of castLib("models") repeat with i = 1 to cnt mem = member(i, "models") if mem.type = #shockwave3d then p3DMember_list.addProp(mem, 0) end if end repeat -- force load repeat with n = p3DMember_list.count down to 1 thisMem = p3DMember_list.getPropAt(n) thisMem.preLoad() end repeat if gDBG then put "start load"&&the timer end --/--------------------------------------------------------------------------- --| exitFrame --| loop here while checking the loading of the 3D media --\--------------------------------------------------------------------------- on exitFrame me -- this frame is where we wait and check that 3D content is ready repeat with n = p3DMember_list.count down to 1 if p3DMember_list[n] = 0 then p3DMember_list.setAt(n, me.mCheck3DState(p3DMember_list.getPropAt(n)) ) end if end repeat -- look for one not loaded if p3DMember_list.getPos(0) then -- carry on looping go the frame else if gDBG then put "end load"&&the timer -- all loaded. Call a customisable script to do any world setup if necessary. -- tell the world object to import in all subordinate objects if gDBG then put "starting adding models"&&the timer gUI_control_obj.mAdd_secondary_3D_mems() if gDBG then put "ended adding models"&&the timer -- custom handler to allow the user to do whatever else they need to do threeD_spr = gUI_control_obj.mFind_3D_world_spr() build_world(threeD_spr) end if end --/--------------------------------------------------------------------------- --| mCheck3DState --| mem - the individual 3D member we are checking --\--------------------------------------------------------------------------- on mCheck3DState me, mem -- a state of 4 means it's ready theState = mem.state if theState = 4 then -- reset the world to the default state mem.resetworld() return true else return false end if end load models 3X,>Fn>richard rossCASt ,global goNetMgr global gUI_control_obj property pAlways_speed_test property pPrev_area on beginsprite me -- retrieve last 3D area if goNetMgr.ilk = #instance then prf_mn = get_prefs_nm("area") pPrev_area = goNetMgr.mGetPref(prf_mn) -- otherwise -- else -- if the runmode = "Author" then -- pPrev_area = 141299 -- end if end if end --- on exitFrame me if voidP(pPrev_area) then -- first speed test go to "speed test" else usable_area_rect = gUI_control_obj.mFind_usable_area_rect() usable_area = usable_area_rect[3]*usable_area_rect[4] if pAlways_speed_test then -- only speed test if the current browser area is greater than the prev stored area if usable_area > pPrev_area then go to "speed test" else -- no speed test as we know that we can use the current browser area gUI_control_obj.mSetUp_UI (usable_area) end if else -- no speed test if usable_area < pPrev_area then -- the browser area is actaully less than what we are capable of so just use that gUI_control_obj.mSetUp_UI (usable_area) else gUI_control_obj.mSetUp_UI (pPrev_area) end if end if end if end --- on getPropertyDescriptionList(aScript) tGPDList = [:] tGPDList[#pAlways_speed_test] = \ [#comment:"test speed every run?",\ #format: #boolean,\ #default: 0] return(tGPDList) end getPropertyDescriptionList decision point[#pAlways_speed_test: [#comment: "test speed every run?", #format: #boolean, #default: 0]]0g,>Fn>richard rossCAStA A>[>f>f>f@[@o@o@o@o@o@o@@@@@@@@@--speed --test --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| this tests the worlds performance so we can guess the optimum world size --| Looks for prefs to see if this movie has already been tested. --| If so, the first test will be at this size, otherwise start at an average sort of area as the initial guess. --| If this test gives a framerate inside the range of pMin_fps to pMin_fps + 2 then we'll have this speed - write prefs --| If not, increase or decrease the area by a factor of 2 and check again --\--------------------------------------------------------------------------- property pTestArea property pInit_camera_trans property pJump property pRot property pTest_stage property pTest_Period property pTest_count property pStart_time property pEnd_time property pCounter property pResultlist property p3DSpr property p3DMember property pMin_fps property pMax_fps property pTargetFPS property pUsable_area_rect property pBrowser_frame_area property pSpeedTestPosX property pSpeedTestPosY property pSpeedTestPosZ property pSpeed_test_type property pFrameCntr property pTest_cnter property pCam1 property pStarted property pInterp_guess_factor property pInitial_guess property pResult_fps global gUI_control_obj global goNodeMgr global goNetMgr global gDBG on beginsprite me pMax_fps = pMin_fps + 1 -- this defines a range pTargetFPS = pMin_fps + (pMax_fps - pMin_fps)/2 pInterp_guess_factor = 1.2 p3DSpr = gUI_control_obj.mFind_3D_world_spr() pUsable_area_rect = gUI_control_obj.mFind_usable_area_rect() pBrowser_frame_area = pUsable_area_rect[3]*pUsable_area_rect[4] p3DMember = sprite(p3DSpr).member pCam1 = p3DMember.camera[1] speedtest_pos = vector( pSpeedTestPosX, pSpeedTestPosY, pSpeedTestPosZ ) -- this should be the point of max overhead. -- store camera pos in the gUI_control_obj cTrans = duplicate(pCam1.transform) pCam1.transform.position = speedtest_pos pInit_camera_trans = duplicate(pCam1.transform) pJump = vector(0, 0, 1) pRot = vector(0, 1, 0) if goNetMgr.ilk = #instance then prf_mn = get_prefs_nm("area") pTestArea_str = goNetMgr.mGetPref(prf_mn) -- retrieve last 3D area end if pInitial_guess = 200000 if voidP(pTestArea_str) then pTestArea = pInitial_guess else pTestArea = value(pTestArea_str) end if -- this is the record of the last efforts pResultlist = [:] sort pResultlist -- values here inproves tha accuracy of each test but slows the whole process down pTest_Period = 40 pTest_count = 40 pTest_cnter = 0 -- switch all lights off so the users cannot see the process -- these must be stored in the UI control object because when resizing we will -- repeat the speed test continuously. If we start a new on before the previous one has finsihed then the stored -- values will be lost and the models will never bbe turned on again. if gUI_control_obj.mLights_on() then gUI_control_obj.mStore_campos (cTrans) stored_light_colors = [:] cnt = p3DMember.light.count back_col = rgb(color(#paletteIndex, the stagecolor).hexString()) repeat with n = 1 to cnt stored_light_colors.addProp(#light, p3DMember.light[n].color) p3DMember.light[n].color = back_col end repeat cnt = p3DMember.shader.count repeat with s = 1 to cnt this_shd = p3DMember.shader[s] nm = this_shd.name emls = [:] emls.addProp(s, this_shd.emissive) this_shd.emissive = back_col stored_light_colors.addProp(#emissive, emls) end repeat gUI_control_obj.mStore_Lights(stored_light_colors) end if pStarted = FALSE pFrameCntr = 0 end --/--------------------------------------------------------------------------- --| exitFrame --| Run a series of tests until a 3D world area is arrived at --| that achieves the taget framerate range. --\--------------------------------------------------------------------------- on exitFrame me if pFrameCntr < 2 then if not pFrameCntr then -- put the 3D world sprite on stage at the first test size me.mSet_up_sprite() end if pFrameCntr = pFrameCntr + 1 pStart_time = the timer pEnd_time = the timer + pTest_Period go the frame exit end if -- to speed things up on faster machines the test is conducted over either -- a fixed period or a fixed nuber of loops, whichever comes first done = FALSE if the timer > pEnd_time then done = TRUE else if pCounter > pTest_count then put "pCounter > pTest_count" done = TRUE end if end if if not done then me.mJump_camera() pCounter = pCounter + 1 else -- recalculate so we have an accurate time t = the timer - pStart_time if t = 0 then t = 1 -- avoid a zero value pResult_fps = float(pCounter)/(float(t)/60.0) pTestArea = integer(pTestArea) pResultlist.addProp(pTestArea, pResult_fps) got_it = me.mCheck_results() if got_it then -- success! me.mEnd_process() exit else pTest_cnter = pTest_cnter + 1 -- run again -- reposition the camera and change the sprite size pCam1.transform = pInit_camera_trans me.mSet_up_sprite() end if end if go the frame end --/--------------------------------------------------------------------------- --| mSet_up_sprite --| Set the world to a new area and init for a new test --\--------------------------------------------------------------------------- on mSet_up_sprite me put "next test is "&pTestArea wh_list = gUI_control_obj.mGet_sprite_WH(pTestArea) sprite(p3DSpr).rect = rect(0,0, wh_list[1], wh_list[2]) -- do a jump just make sure everything is set up me.mJump_camera() updatestage -- now start timing pCounter = 0 pStart_time = the timer pEnd_time = the timer + pTest_Period pFrameCntr = 0 end --/--------------------------------------------------------------------------- --| mJump_camera --| Move the camera by a small amount in the mannar of the defined test --\--------------------------------------------------------------------------- on mJump_camera me if pSpeed_test_type = "translation" then pCam1.transform.position = pCam1.transform.position + pJump else pCam1.transform.rotation = pCam1.transform.rotation + pRot end if end --/--------------------------------------------------------------------------- --| mCheck_results --| Is the result of the last test witin the target frame rate --\--------------------------------------------------------------------------- on mCheck_results me -- is the fps within range? put "pResultlist is"&pResultlist if pResult_fps >= pMin_fps then if pResult_fps < pMax_fps then -- done it! return 1 else -- if we are at the pBrowser_frame_area then we should check no further if pTestArea >= pBrowser_frame_area then return 1 end if -- check again with a larger area return me.mGet_larger_area() end if else -- it's just too small - check again with a smaller area return me.mGet_smaller_area() end if end --/--------------------------------------------------------------------------- --| mGet_larger_area --| Work out the next test area size if we need a larger one --| (ie the frame rate was higher that the taget range) --\--------------------------------------------------------------------------- on mGet_larger_area me put "mGet_larger_area" -- if we have only had one try then double the area so we can interpolate next time. -- (we're looking for a smaller fps) if pResultlist.count = 1 then -- if we have never calibrated this machine the prefs will be pInitial_guess if pTestArea = pInitial_guess then -- if we have a really high frame rate start at the bowser frame size if pResult_fps > pMax_fps*10 then pTestArea = pBrowser_frame_area else pTestArea = pTestArea*2 end if else pTestArea = integer(pTestArea*pInterp_guess_factor) end if -- don't go larger that the browser frame if pTestArea > pBrowser_frame_area then pTestArea = pBrowser_frame_area end if else -- interpolate - find the next nearest and use this (I have no idea about the relationship between fps and area is) this_fps = pResultlist.getAProp(pTestArea) this_pos = pResultlist.getpos(pResult_fps) -- this point is the highest area so far -- 2 is always the larger area and smaller fps if this_pos = pResultlist.count then -- try a larger size area1 = pResultlist.getPropAt(this_pos) area2 = pResultlist.getPropAt(this_pos-1) fps1 = pResultlist[this_pos] fps2 = pResultlist[this_pos-1] if fps1 < fps2 then -- results look good put "good" grad = float(area1 - area2)/float(fps1 - fps2) grad = abs(grad) fps_diff = float(fps1 - pTargetFPS) pTestArea = (area1 + integer(grad*fps_diff))*pInterp_guess_factor else put "squirelly" -- results are squirelly so just guess pTestArea = integer(pTestArea*pInterp_guess_factor) end if -- don't go larger that the browser frame if pTestArea > pBrowser_frame_area then pTestArea = pBrowser_frame_area end if else -- this point is not the highest so far. We need a point in between the two pos2 = this_pos +1 pos1 = this_pos area2 = pResultlist.getPropAt(pos2) fps2 = pResultlist[pos2] area1 = pResultlist.getPropAt(pos1) fps1 = pResultlist[pos1] area_diff = area2 - area1 fps_diff = fps1 - fps2 target_1_fps_diff = fps1 - pTargetFPS if fps_diff > 0 then pTestArea = area1 + float(area_diff)*target_1_fps_diff/fps_diff else -- this should not hapen pTestArea = integer(pTestArea*pInterp_guess_factor) put "this should not hapen" end if end if end if return 0 end --/--------------------------------------------------------------------------- --| mGet_smaller_area --| Work out the next test area size if we need a smaller one --| (ie the frame rate was lower that the taget range) --\--------------------------------------------------------------------------- on mGet_smaller_area me put "mGet_smaller_area" -- if we have only had one try then half the area so we can interpolate next time. if pResultlist.count = 1 then -- if we have never calibrated this machine the prefs will be the initial guess if pTestArea = pInitial_guess then pTestArea = pTestArea/2 else pTestArea = integer(pTestArea/pInterp_guess_factor) end if else -- interpolate this_fps = pResultlist.getAProp(pTestArea) this_pos = pResultlist.getpos(this_fps) -- this point is not the lowest area so far. We need a point in between the two -- 2 is always the larger area and smaller fps if this_pos > 1 then pos2 = this_pos pos1 = this_pos -1 area2 = pResultlist.getPropAt(pos2) fps2 = pResultlist[pos2] area1 = pResultlist.getPropAt(pos1) fps1 = pResultlist[pos1] area_diff = area2 - area1 fps_diff = fps1 - fps2 target_1_fps_diff = pTargetFPS - fps2 pTestArea = area2 - float(area_diff)*target_1_fps_diff/fps_diff else -- needs to be smaller --- pTestArea = integer(pTestArea/pInterp_guess_factor) -- try a larger size area1 = pResultlist.getPropAt(1) area2 = pResultlist.getPropAt(2) fps1 = pResultlist[1] fps2 = pResultlist[2] if fps1 > fps2 then -- results look good put "good" grad = float(area1 - area2)/float(fps1 - fps2) grad = abs(grad) fps_diff = float(fps1 - pTargetFPS) pTestArea = (area1 - integer(grad*fps_diff))*pInterp_guess_factor else put "squirelly" -- results are squirelly so just guess pTestArea = integer(pTestArea/pInterp_guess_factor) end if end if end if return 0 end --/--------------------------------------------------------------------------- --| mEnd_process --| Turn the lights back on. Store the results int heprefs file. --| Start the setup for the actual experience at this area. --\--------------------------------------------------------------------------- on mEnd_process me -- restore the color to the lights stored_light_colors = gUI_control_obj.mGet_lights() cnt = stored_light_colors.count repeat with n = 1 to cnt type = stored_light_colors.getPropAt(n) if type = #light then p3DMember.light[n].color = stored_light_colors[n] else -- it must be stored properties of a shaders, eg emissive shdrVals = stored_light_colors[n] prop = stored_light_colors.getPropAt(n) nm = shdrVals.getPropAt(1) --shdr = p3DMember.shader[nm] val = shdrVals[1] case prop of #emissive: p3DMember.shader(nm).emissive = val end case if p3DMember.shader[nm].name contains "BackdropShader-copy" then p3DMember.shader[nm].emissive = rgb(255, 255, 255) else if p3DMember.shader[nm].name contains "OverlayShader-copy" then p3DMember.shader[nm].emissive = rgb(255, 255, 255) end if end if end if end repeat -- store this in the prefs for next time prf_mn = get_prefs_nm("area") if pTestArea > 0 then if goNetMgr.ilk = #instance then goNetMgr.mSetPref(prf_mn, string(pTestArea)) -- store 3D area end if else put "pTestArea < 0" end if -- return the camera to the original pos (important if we are speed testing when resizing the browser window pCam1.transform = gUI_control_obj.mGet_campos() -- now we can set up the screen. gUI_control_obj.mSetUp_UI (pTestArea) -- just incase we have a scrolling background we should set this up too. gUI_control_obj.mSetUp_background() end --- on getPropertyDescriptionList(aScript) tGPDList = [:] tGPDList[#pMin_fps] = \ [#comment:"Minimun fps",\ #format: #integer,\ #range:[#min:0, #max:20],\ #default: 10] tGPDList[#pSpeedTestPosX] = \ [#comment:"X location for speed test",\ #format: #integer,\ #default: 0] tGPDList[#pSpeedTestPosY] = \ [#comment:"Y location for speed test",\ #format: #integer,\ #default: 0] tGPDList[#pSpeedTestPosZ] = \ [#comment:"Z location for speed test",\ #format: #integer,\ #default: 0] tGPDList[#pSpeed_test_type] = \ [#comment:"Speed test type",\ #format: #string,\ #range:["rotation", \ "translation"],\ #default: "translation"] return(tGPDList) end getPropertyDescriptionList speed test[#pMin_fps: [#comment: "Minimun fps", #format: #integer, #range: [#min: 0, #max: 20], #default: 10], #pSpeedTestPosX: [#comment: "X location for speed test", #format: #integer, #default: 0], #pSpeedTestPosY: [#comment: "Y location for speed test", #format: #integer, #default: 0], #pSpeedTestPosZ: [#comment: "Z location for speed test", #format: #integer, #default: 0], #pSpeed_test_type: [#comment: "Speed test type", #format: #string, #range: ["rotation", "translation"], #default: "translation"]]Cdd,>Fn>richard rossCASt 7CCCCWWWWWWkkkkkkos--world --setup --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property p3D_mbr property pID property pFOV --property pAspect_ratioH --property pAspect_ratioW --property pAspect_ratio property pShow_tt property pShowing on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #world -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if p3D_mbr.resetWorld() end --/--------------------------------------------------------------------------- --| mInit --| Sets up the worlds parameter --\--------------------------------------------------------------------------- on mInit me p3D_mbr = pSpr.member p3D_mbr.resetWorld() pShowing = TRUE end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area if pShowing then pSpr.rect = threeD_sprite_rect else me.mHide() end if p3D_mbr.camera[1].fieldofview = pFOV end --/--------------------------------------------------------------------------- --| mousedown --| Check if we clicked on a node --\--------------------------------------------------------------------------- on mousedown me gUI_control_obj.mCheck_node_click() end --- --/--------------------------------------------------------------------------- --| mHide --| Move the world off screen. --\--------------------------------------------------------------------------- on mHide me pShowing = FALSE pSpr.locH = -9999 pSpr.width = 1 pSpr.height = 1 end --/--------------------------------------------------------------------------- --| mShow --| Move the world on screen to defined rect. --\--------------------------------------------------------------------------- on mShow me, the_rect pSpr.member.directtostage = 1 pShowing = TRUE pSpr.rect = the_rect end --/--------------------------------------------------------------------------- --| getModels --| Find all the models in the member --\--------------------------------------------------------------------------- on getModels(me, aMember, aList) repeat with j = 1 to aMember.model.count if string(aMember.model[j]) contains "model" then aList.add(aMember.model[j].name) end if end repeat return(aList) end getModels --/--------------------------------------------------------------------------- --| mIs3D --| Check that aMember is a 3D member type --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D ---- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] if aScript.mIs3D(sprite(the currentSpriteNum).member) then tGPDList[#pFOV] = \ [#comment:"Field of view",\ #format: #integer,\ #range:[#min:1, #max:99],\ #default: 60] tGPDList[#pShow_tt] = \ [#comment:"Show tooltips?",\ #format: #boolean,\ #default: 1] end if return(tGPDList) end if end getPropertyDescriptionList world setup()CnCn,>Fn>richard rossCAStfG f9 eeeeeeeeeeeeeeeeeeee--camera --setup --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour controls everything to do with the position of the camera (1). --| This includes the start view pos, the final start pos (after an initial fly in and --| collision detection. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gTransfer_im global goNodeMgr property ancestor, spritenum property pSpr property pID property pServIntvl property pTurnSpeed property pMax_turn_speed property pTurn_drag_10 property pTurn_Drag property pTurn_Accel_10 property pTurn_Accel property pMax_speed property pSpeed property pDrag_10 property pDrag property pAccel property pButton_key_pressed property pShowing_LR_button_down property pShowing_UD_button_down property p3DMember property pCam1 property pCam2 property pInter_to_mdl property pButtonControl_obj property pNav_directions_lst property pInitial_start_posX property pInitial_start_posY property pInitial_start_posZ property pInitial_start_pos property pFinal_start_posX property pFinal_start_posY property pFinal_start_posZ property pFinal_start_pos property pFinal_rot_x property pFinal_rot_y property pFinal_rot_z property pUp_vector_component property pUp_vector property pCollisdion_distance property pCollision_snd property pFirstHit property pMUR_model property pInterpol_endtime property pInterpol_period property pTarget_mdl property pInterp_Offset_vector property pInterp_startTransform property pEnd_transform property pCamera_height property pPass_cntl property pTarget_node property pBumpChan on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #mainNav -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mInit() me.mRegister() end --/--------------------------------------------------------------------------- --| mInit --| init params --\--------------------------------------------------------------------------- on mInit me pCollisdion_distance = 5 + pMax_speed pCollision_snd = member "bump" pInitial_start_pos = vector( pInitial_start_posX, pInitial_start_posY , pInitial_start_posZ )-- user definable pFinal_start_pos = vector( pFinal_start_posX, pFinal_start_posY, pFinal_start_posZ )-- user definable pServIntvl = 1 -- user definable (?) pSpr = sprite(me.spritenum) pTurnSpeed = 0 pTurn_Drag = float(pTurn_Drag_10)/10 pTurn_Accel = float(pTurn_Accel_10)/10 pSpeed = 0 pDrag = float(pDrag_10)/10 pButton_key_pressed = #none pShowing_LR_button_down = 0 pShowing_UD_button_down = 0 p3DMember = sprite(pSpr).member pBumpChan = 1 pFirstHit = 0 pMUR_model = "" --pAuto_pilot = FALSE pPass_cntl = 0 -- different modelling packeages can have differnt coordinate systems. case pUp_vector_component of "x": pUp_vector = vector(1,0,0) "y": pUp_vector = vector(0,1,0) "z": pUp_vector = vector(0,0,1) end case end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --/--------------------------------------------------------------------------- --| mEnable_directions --| From behaviour on nav dutton indicating what kind of nav is available (ie, left, right, etc) --\--------------------------------------------------------------------------- on mEnable_directions me, directions_lst pNav_directions_lst = directions_lst sort pNav_directions_lst end --/--------------------------------------------------------------------------- --| set the camera to the start position and begin the initial zoom in --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list -- this should only happen if it has not been done before if not voidP(pCam1) then exit end if pCam1 = p3DMember.camera[1] -- clone the first camera - this is necessary for the flying interpolation pCam1.clone("dummycam") pCam2 = p3DMember.camera[2] start_trans = transform() start_trans.position = pInitial_start_pos final_rot = vector(pFinal_rot_x, pFinal_rot_y, pFinal_rot_z) start_trans.rotation = final_rot pCam1.transform = start_trans -- pCam2.transform.position = pInitial_start_pos -- pCam2.transform.rotation = final_rot final_trans = transform() final_trans.rotation = final_rot final_trans.position = pFinal_start_pos -- we need to define a small offset for the final position otherwise the camera 2 cannot point at the final destination me.mStart_interp(final_trans, 0, 1) end --/--------------------------------------------------------------------------- --| mSet_button_nav_control_obj --| from UI control - allow comms with buttons if there are any --\--------------------------------------------------------------------------- on mSet_button_nav_control_obj me, inst pButtonControl_obj = inst end --/--------------------------------------------------------------------------- --| mArrow_button_clicked --| from button control behavior --\--------------------------------------------------------------------------- on mArrow_button_clicked me, button_key_pressed pButton_key_pressed = button_key_pressed end --/--------------------------------------------------------------------------- --| mService --| from main service loop --\--------------------------------------------------------------------------- on mService me -- if we are interploating from one point to another we'll ignore the arrow nav if gUI_control_obj.pAuto_pilot then me.mInterpol_A_to_B() else me.mArrow_navigate() end if end --/--------------------------------------------------------------------------- --| mArrow_navigate --| This handler contains the logic for all types of navigation (keyboard or button) --| th button handler plugs into this logic --\--------------------------------------------------------------------------- on mArrow_navigate me --if there are no button hotspots then navigation is suspended if not pNav_directions_lst.count then exit -- list the keys pressed keypressedlst = [] -- check if the mouse has stopped clicking down if the mousedown = FALSE then pButton_key_pressed = #none -- are we rotating the camera? -- key button if pButton_key_pressed <> #none then if pButton_key_pressed = #left then if pTurnSpeed < 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed + pTurn_Accel if pTurnSpeed > pMax_turn_speed then pTurnSpeed = pMax_turn_speed else if pButton_key_pressed = #right then if pTurnSpeed > 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed - pTurn_Accel if abs(pTurnSpeed) > pMax_turn_speed then pTurnSpeed = -1*pMax_turn_speed end if end if else -- arrow key if keypressed(123) or keypressed(124) then if keypressed(123) and keypressed(124) then -- both at same time -- make sure buttons are up if pShowing_LR_button_down <> 0 then aList = [#left, #right] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 0 end if else if keypressed(123) then if pTurnSpeed < 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed + pTurn_Accel if pTurnSpeed > pMax_turn_speed then pTurnSpeed = pMax_turn_speed -- show button downstate aList = [#left] call(#mArrow_key_pressed, pButtonControl_obj, aList) -- make sure the other one is up if pShowing_LR_button_down <> 123 then aList = [#right] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 123 end if else if pTurnSpeed > 0 then pTurnSpeed = 0 pTurnSpeed = pTurnSpeed - pTurn_Accel if abs(pTurnSpeed) > pMax_turn_speed then pTurnSpeed = -1*pMax_turn_speed end if aList = [#right] call(#mArrow_key_pressed, pButtonControl_obj, aList) if pShowing_LR_button_down <> 124 then -- make sure the other one is up aList = [#left] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 124 end if end if end if else -- make sure buttons are up if pShowing_LR_button_down <> 0 then aList = [#left, #right] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_LR_button_down = 0 end if end if end if -- double it if the space bar is pressed if pTurnSpeed <> 0 then if keypressed (7) then pCam1.rotate(0, pTurnSpeed*2, 0, #self) me.mUpdate_backdrop(pTurnSpeed*2) else pCam1.rotate(0, pTurnSpeed, 0, #self) me.mUpdate_backdrop(pTurnSpeed) end if end if -- now do rotation drag if pTurnSpeed <> 0 then if pTurnSpeed > 0 then pTurnSpeed = pTurnSpeed - pTurn_Drag -- don't start going the other way if pTurnSpeed < 0 then pTurnSpeed = 0 else pTurnSpeed = pTurnSpeed + pTurn_Drag -- don't start going the other way if pTurnSpeed > 0 then pTurnSpeed = 0 end if end if --forwards -- if the nav button does not have forwards in it then we are only roating so bail if not pNav_directions_lst.findpos(#up) then exit -- key button if pButton_key_pressed <> #none then if pButton_key_pressed = #down then -- forwards if pSpeed < 0 then pSpeed = 0 pSpeed = pSpeed + pAccel if pSpeed > pMax_speed then pSpeed = pMax_speed else if pButton_key_pressed = #up then -- backwards if pSpeed > 0 then pSpeed = 0 pSpeed = pSpeed - pAccel if abs(pSpeed) > pMax_speed then pSpeed = -1*pMax_speed end if end if else if keypressed(125) or keypressed(126) then if keypressed(125) and keypressed(126) then -- both at same time" -- make sure buttons are up if pShowing_UD_button_down <> 0 then aList = [#up, #down] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 0 end if else if keypressed(125) then -- forwards if pSpeed < 0 then pSpeed = 0 pSpeed = pSpeed + pAccel if pSpeed > pMax_speed then pSpeed = pMax_speed aList = [#down] call(#mArrow_key_pressed, pButtonControl_obj, aList) if pShowing_UD_button_down <> 126 then -- make sure the other one is up aList = [#up] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 126 end if else -- backwards if pSpeed > 0 then pSpeed = 0 pSpeed = pSpeed - pAccel if abs(pSpeed) > pMax_speed then pSpeed = -1*pMax_speed aList = [#up] call(#mArrow_key_pressed, pButtonControl_obj, aList) if pShowing_UD_button_down <> 125 then -- make sure the other one is up aList = [#down] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 125 end if end if end if else -- make sure buttons are up if pShowing_UD_button_down <> 0 then aList = [#up, #down] call(#mArrow_key_release, pButtonControl_obj, aList) pShowing_UD_button_down = 0 end if end if end if -- now move the camera if pSpeed <> 0 then -- check for collisions if pSpeed < 0 then if me.mCheck_collision(-1) then pSpeed = 0 if not pFirstHit then sound(pBumpChan).play([#member: member("bump")]) pFirstHit = 1 end if else pFirstHit = 0 end if else if me.mCheck_collision(1) then pSpeed = 0 if not pFirstHit then sound(pBumpChan).play([#member: member("bump")]) pFirstHit = 1 end if else pFirstHit = 0 end if end if if keypressed (7) then pCam1.translate(0, 0 ,2*pSpeed, #self) else pCam1.translate(0, 0 ,pSpeed, #self) end if end if -- now do drag if pSpeed <> 0 then if pSpeed > 1 then pSpeed = pSpeed - pDrag -- don't start going the other way if pSpeed < 0 then pSpeed = 0 else pSpeed = pSpeed + pDrag -- don't start going the other way if pSpeed > 0 then pSpeed = 0 end if end if end --/--------------------------------------------------------------------------- --| mUpdate_backdrop --| If the world has a panoramic backdrop then this need to be updated --| with the camera rotation --\--------------------------------------------------------------------------- on mUpdate_backdrop me, amt if objectP(gUI_control_obj.pScrlback_inst) then gUI_control_obj.pScrlback_inst.mUpdate_backdrop(amt) end if end --/--------------------------------------------------------------------------- --| mCheck_collision --| Project a ray forward to check collision. If there is a hit of models hit, check the distance of the --| first to see if it is within the collision distance --\--------------------------------------------------------------------------- on mCheck_collision me, direction me.mCheck_camera_height() -- now check for collisions dirvect = direction*(pCam1.getworldtransform().zaxis) pos = pCam1.getworldtransform().position hitlist = p3DMember.modelsunderray(pos, dirvect, 1, #detailed) if hitlist.count then firstHit = hitlist[1] hitmodel = firstHit.model if firstHit.distance < pCollisdion_distance then return 1 end if end if return 0 end --/--------------------------------------------------------------------------- --| mCheck_camera_height --| Check to see that we are a constant distance from the ground by projecting a ray down --| and checking the first model hit with the user defined camera height. --\--------------------------------------------------------------------------- on mCheck_camera_height -- a camera height of zero means no ground if not pCamera_height then exit -- check the distance to the floor incase it is uneven dirvect = -1*(pCam1.getworldtransform().yaxis) pos = pCam1.getworldtransform().position hitlist = p3DMember.modelsunderray(pos, dirvect, 1, #detailed) if hitlist.count then firstHit = hitlist[1] hitmodel = firstHit.model diff = pCamera_height - firstHit.distance if integer(diff) <> 0 then pCam1.translate(0, diff, 0) end if else -- we have gone underground so we must correct it - look for a mode upwards. dirvect = pCam1.getworldtransform().yaxis pos = pCam1.getworldtransform().position hitlist = p3DMember.modelsunderray(pos, dirvect, 1, #detailed) if hitlist.count then firstHit = hitlist[1] hitmodel = firstHit.model pCamera_height = 30 diff = pCamera_height + firstHit.distance pCam1.translate(0, diff, 0) else -- there is no ground --alert "lost the ground plane" end if end if end --/--------------------------------------------------------------------------- --| mInterpol_A_to_B --| This handler interpolates between two points (A and model B) where model B might be moving. --\--------------------------------------------------------------------------- on mInterpol_A_to_B me proportion = integer ( 100 - float(100)*(pInterpol_endtime - the milliseconds)/pInterpol_period ) if proportion < 100 then tTransform = pInterp_startTransform.interpolate(pEnd_transform, proportion) pCam1.transform = tTransform else pCam1.transform = pEnd_transform -- updatestage -- flag that we're done gUI_control_obj.pAuto_pilot = FALSE if pPass_cntl then --Make the appearance high quality by adding the sds modifier me.mAdd_SDS(pTarget_mdl) -- set the new item ID if not voidP(pTarget_node) then if goNodeMgr.ilk = #instance then goNodeMgr.mSetItem(pTarget_node) end if else put "target node ID is void" end if else -- we are not passing control so show the widgets (this should be done after the initial fly through) gUI_control_obj.mShow_widgets () end if end if end --/--------------------------------------------------------------------------- --| mAdd_SDS --| Make the appearance high quality by adding the sds modifier --\--------------------------------------------------------------------------- on mAdd_SDS me, mdl if string(mdl).char[1..5] = "group" then -- get children and recursively set SDS ccnt = mdl.child.count if ccnt then repeat with c = 1 to ccnt nxt_mdl = mdl.child[c] me.mAdd_SDS(nxt_mdl) end repeat end if else if string(mdl).char[1..5] = "model" then -- set model to high quality -- if the re is LOD we must disable it mlst = mdl.modifier if mlst.findpos(#lod) then put "mdl is "&mdl&&mdl.lod.auto mdl.lod.auto = 0 mdl.lod.level = 100 end if mdl.addmodifier(#sds) -- check that it was added sucesssfully - some models will not support it if mlst.findpos(#sds) then mdl.sds.enabled = TRUE mdl.sds.depth = 5 mdl.sds.subdivision = #adaptive end if end if end if end --/--------------------------------------------------------------------------- --| mStart_interp --| This kicks of the auto pilot interpolation --\--------------------------------------------------------------------------- on mStart_interp me, mdl_or_trans, pass_cntl_flag, beh_inst -- this indicates whether at the end of the autopilot we are passing control to a new node if pass_cntl_flag then pPass_cntl = 1 else pPass_cntl = 0 end if pInterp_startTransform = duplicate(pCam1.transform) if mdl_or_trans.ilk = #transform then pEnd_transform = mdl_or_trans --pCam2.transform = pEnd_transform else -- if a ref to the model behaviour has been passed do a callback to say that interolation has started if ilk(beh_inst) = #instance then beh_inst.mStart_fly_to (pInterpol_period) stop_from_dist = beh_inst.getAProp(#pAutopilot_upto_dist) pTarget_node = beh_inst.getAProp(#pNodeID) else put "no bahavior instance pased" end if pInter_to_mdl = 1 pTarget_mdl = mdl_or_trans total_dist_vector = mdl_or_trans.transform.position - pInterp_startTransform.position total_dist_vector.normalize() pInterp_Offset_vector = total_dist_vector*stop_from_dist pCam2.transform = pTarget_mdl.transform pCam2.transform.position = pCam2.transform.position - pInterp_Offset_vector --pCam2.pointAt(pTarget_mdl.transform.position, pUp_vector) pCam2.pointAt(pTarget_mdl.getworldtransform().position, pUp_vector) pEnd_transform = pCam2.transform end if -- don't start this again mid flight if gUI_control_obj.pAuto_pilot then exit gUI_control_obj.pAuto_pilot = TRUE pInterpol_endtime = the milliseconds + pInterpol_period end --/--------------------------------------------------------------------------- --| mIs3D --| Check that aMember is a 3D member type --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D ---- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] if aScript.mIs3D(sprite(the currentSpriteNum).member) then tGPDList[#pInitial_start_posX] = \ [#comment:"Initial start pos X",\ #format: #integer,\ #default: 0] tGPDList[#pInitial_start_posY] = \ [#comment:"Initial start pos Y",\ #format: #integer,\ #default: 0] tGPDList[#pInitial_start_posZ] = \ [#comment:"Initial start pos Z",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_start_posX] = \ [#comment:"Final start pos X",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_start_posY] = \ [#comment:"Final start pos Y (reset by height from ground)",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_start_posZ] = \ [#comment:"Final start pos Z",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_rot_x] = \ [#comment:"Final rotation X",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_rot_y] = \ [#comment:"Final rotation Y",\ #format: #integer,\ #default: 0] tGPDList[#pFinal_rot_z] = \ [#comment:"Final rotation Z",\ #format: #integer,\ #default: 0] tGPDList[#pCamera_height] = \ [#comment:"Height from ground (0 means no ground)",\ #format: #integer,\ #range:[#min:-10000, #max:10000],\ #default: 27] tGPDList[#pMax_turn_speed] = \ [#comment:"Max turn speed",\ #format: #integer,\ #range:[#min:1, #max:20],\ #default: 4] tGPDList[#pTurn_drag_10] = \ [#comment:"Turn drag",\ #format: #integer,\ #range:[#min:1, #max:10],\ #default: 2] tGPDList[#pTurn_Accel_10] = \ [#comment:"Turn acceleration",\ #format: #integer,\ #range:[#min:0, #max:10],\ #default: 5] tGPDList[#pMax_speed] = \ [#comment:"Max speed",\ #format: #integer,\ #range:[#min:1, #max:50],\ #default: 5] tGPDList[#pDrag_10] = \ [#comment:"Drag",\ #format: #integer,\ #range:[#min:1, #max:30],\ #default: 10] tGPDList[#pAccel] = \ [#comment:"Acceleration",\ #format: #integer,\ #range:[#min:1, #max:20],\ #default: 2] tGPDList[#pInterpol_period] = \ [#comment:"Time taken to autopilot (ms)",\ #format: #integer,\ #range:[#min:1, #max:10000],\ #default: 2500] tGPDList[#pUp_vector_component] = \ [#comment:"Up vector in modellers coordinate system (3D Max is y up)",\ #format: #string,\ #range:["x", "y", "z"],\ #default: "y"] end if return(tGPDList) end if end getPropertyDescriptionList camera setupN00,>Fn>richard rossCASt6 6 6 66666262626262626F6F6F6F6F6F6J6N6[--additional --model --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour allows the user to add additional models to the world --| They can define the positon and scale of the model within the world --| They can also define some behaviour. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gDBG property ancestor, spritenum property pSpr property pID property pServIntvl property pBumpChan property pSpeed property pAxisRotation property pAdditional_mem property pAdditional_grp property p3DMember property pPosx property pPosy property pPosz property pScale property pLodbias property pNodeID property pTTTxt property pAutopilot_upto_dist property pRollover property pRolling_flag property pFacing_camera_transform property pInterp_startTransform property pRollup_duration property pInterpol_start_tm property pInterpol_end_tm on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #addModel -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mInit --\--------------------------------------------------------------------------- on mInit me pCollision_snd = member "bump" -- user definable pPos = vector( -26.47, -3000, -24.45 )-- user definable pSpr = sprite(me.spritenum) pServIntvl = 4 -- user definable p3DMember = pSpr.member pBumpChan = 1 pSpeed = float(pSpeed)/10.0 -- check that the node ID is an integer if not (pNodeID.ilk = #integer) then alert "node ID "&pNodeID&"in additional model for "&pAdditional_mem"& is not an integer, please reenter it" end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- on mService me -- start spinning the group as soo as it exists me.mAnimate() end --/--------------------------------------------------------------------------- --| mAnimate --| Do whatever type of animation is required --\--------------------------------------------------------------------------- on mAnimate me if not voidP(pAdditional_grp) then if pRolling_flag then me.mRollover() else case pAxisRotation of "X": me.rotateX() "Y": me.rotateY() "Z": me.rotateZ() end case end if end if end --/--------------------------------------------------------------------------- --| mImport_models --| List all the models in the member to have it's models cloned --| Create a new group of name "member name"&group. Add a string of the inst to make sure that --| it's a unique name. --\--------------------------------------------------------------------------- on mImport_models me aList = [] me.mGetModels(pAdditional_mem, aList) -- make a group called the member name &"group" - add a string of the inst to ensure that the name is unique tname = member(pAdditional_mem).name group_name = "flg_m1_grp_"&tname&string(me) pAdditional_grp = p3DMember.newGroup(group_name) -- put them into the world at their positions cnt = aList.count if gDBG then put "start cloneModelFromCastmember loop"&&the timer if gDBG then put "there are "&cnt&&"models" repeat with n = 1 to cnt modelName = aList[n] newmodelName = tname&n&"_"&modelName&string(me) mdl = p3DMember.cloneModelFromCastmember(newmodelName, modelName, member (pAdditional_mem)) mdl.addmodifier(#lod) mdl.lod.auto = 1 mdl.lod.bias = pLodbias -- make them children of the new group -- move the group to the user defined position and scale pAdditional_grp.addChild(mdl, #preserveParent) end repeat if gDBG then put "end cloneModelFromCastmember loop"&&the timer pos = vector(pPosx, pPosy, pPosz) s = float(pScale)/100 scl = vector(s, s, s) pAdditional_grp.transform.position = pos pAdditional_grp.transform.scale = scl -- make the model start off facing the camera. Store this transform. pAdditional_grp.pointatorientation =[vector( 0.0000, 0.0000, 1.0000 ), vector( 0.0000, 1.0000, 0.0000 )] -- rotate the model so it always faces the camera keeping it's y component or rotation cam_pos = p3DMember.camera[1].getWorldTransform().position mdl_pos_y = pAdditional_grp.getWorldTransform().position.y cam_pos.y = mdl_pos_y pAdditional_grp.pointAt(cam_pos, vector(0,1,0)) pFacing_camera_transform = duplicate(pAdditional_grp.transform) -- bug - the scale set above does not seem top be reflected in the stored transform --pFacing_camera_transform.scale = scl -- now tell the cursor feedback object about it's node and tooltips gUI_control_obj.mSet_csr_fdbk(pAdditional_grp.name, me) end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseWithin me if pRollover then if pRolling_flag = FALSE then pRolling_flag = TRUE pInterpol_start_tm = the milliseconds pInterpol_end_tm = the milliseconds + pRollup_duration pInterp_startTransform = pAdditional_grp.transform end if end if end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseLeave me pRolling_flag = FALSE end --/--------------------------------------------------------------------------- --| mRollover --| Interplolate to the point at camera positon if we are not already there --\--------------------------------------------------------------------------- on mRollover me -- interpolate to the facing camera position if pRolling_flag = 1 then proportion = 1.0*(the milliseconds - pInterpol_start_tm)/float(pRollup_duration) if proportion > 1 then proportion = 1 -- flag so we know we have finished pRolling_flag = 2 end if --ccc tTransform = pInterp_startTransform.interpolate(pFacing_camera_transform, proportion) pAdditional_grp.transform = tTransform end if end --/--------------------------------------------------------------------------- --| mGetModels --| Get the names of the nodes that are in fact models --\--------------------------------------------------------------------------- on mGetModels me, aMember, aList repeat with j = member(aMember).model.count down to 1 if string(member(aMember).model[j]) contains "model" then aList.add(member(aMember).model[j].name) end if end repeat end --/--------------------------------------------------------------------------- --| rotateX --| Rotate on X axix --\--------------------------------------------------------------------------- on rotateX me, aModel pAdditional_grp.rotate(pSpeed,0,0) end --/--------------------------------------------------------------------------- --| rotateY --| Rotate on Y axix --\--------------------------------------------------------------------------- on rotateY me, aModel pAdditional_grp.rotate(0,pSpeed,0) end --/--------------------------------------------------------------------------- --| rotateZ --| Rotate on Z axix --\--------------------------------------------------------------------------- on rotateZ me, aModel pAdditional_grp.rotate(0,0,pSpeed) end --/--------------------------------------------------------------------------- --| mStart_fly_to --| Callback from camera control to say that the camera has just started zooming in --| it passes the fly to period so a model can make sure that it moves back to the correct orienation in time --\--------------------------------------------------------------------------- on mStart_fly_to me, fly_to_period pFly_to_flag = 1 pFly_to_period = fly_to_period pFly_to_end_time = the milliseconds + fly_to_period end --/--------------------------------------------------------------------------- --| mFind_3D_members --| Get a list of all 3D members in the "models" castlib --\--------------------------------------------------------------------------- on mFind_3D_members me, this_mem rtn_lst = [] cnt = the number of members of castLib("models") repeat with i = 1 to cnt mem = member(i, "models") if mem.type = #shockwave3d then -- ignore the world member if mem <> this_mem then rtn_lst.add(mem.name) end if end if end repeat return rtn_lst end --/--------------------------------------------------------------------------- --| mIs3D --| Check that we have dropped this behaviour on a 3D member --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member if aScript.mIs3D(this_mem) then tList = [] tList = aScript.mFind_3D_members(this_mem, tList) if tList = [] then alert "you must import at least one model into the models cast" abort end if tGPDList[#pAdditional_mem] = \ [#comment:"Which 3D member?",\ #format: #string,\ #range: tList,\ #default: tList[1]] tGPDList[#pPosX] = \ [#comment:"Postion x",\ #format: #integer,\ #format: #integer,\ #default: 0] tGPDList[#pPosY] = \ [#comment:"Postion y",\ #format: #integer,\ #format: #integer,\ #default: 0] tGPDList[#pPosZ] = \ [#comment:"Postion z",\ #format: #integer,\ #format: #integer,\ #default: 0] tGPDList[#pScale] = \ [#comment:"Scale x 100",\ #format: #integer,\ #default: 100] tGPDList[#pTTTxt] = \ [#comment:"Tool tip text",\ #format: #string,\ #default: "a short descrition"] tGPDList[#pNodeID] = \ [#comment:"Node ID (0 means it's not a node)",\ #format: #integer,\ #default: 0] tGPDList[#pAutopilot_upto_dist] = \ [#comment:"If node, how close to autopilot to when clicked)",\ #format: #integer,\ #default: 50] tGPDList[#pSpeed] = \ [#comment:"Rotation speed - degrees per anim step x 10",\ #format: #integer,\ #default: 0] tGPDList[#pAxisRotation] = \ [#comment:"Which axis to rotate about",\ #format: #string,\ #range:["X", \ "Y", \ "Z"],\ #default: "Y"] tGPDList[#pRollover] = \ [#comment:"Face camera on rollover",\ #format: #boolean,\ #default: TRUE] tGPDList[#pRollup_duration] = \ [#comment:"Time taken for rollover animation (ms)",\ #format: #integer,\ #default: 1000] tGPDList[#pLodbias] = \ [#comment:"LOD bias",\ #format: #integer,\ #range:[#min:0, #max:100],\ #default: 30] end if return(tGPDList) end if end getPropertyDescriptionList additional model 3X2v2v,>Fn>richard rossCASt3B 34 2v2222222222222222222--model --picker --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| this behaviour should be dropped on the 3D world sprite if you want tool tips --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property pID property pTTTxt property pTT_mdl property pMP_mdl property pNodeID property pAutopilot_upto_dist property pRolling_flag property pFly_to_flag property pFly_to_period property pFly_to_end_time property pRollover property pAxisRotation property pRollup_duration property pInterpol_start_tm property pFacing_camera_transform property pInterpol_end_tm property pInterp_startTransform property pSpeed property pTTTxt_mn_flg property pServIntvl property pGrp_mdl on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #pickedModel -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) pSpr = sprite(me.spritenum) -- check that the node ID is an integer if not (pNodeID.ilk = #integer) then alert "node ID "&pNodeID&" in model picker behaviour for "&pTT_mdl"& is not an integer, please reenter it" me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if pMP_mdl = VOID end --/--------------------------------------------------------------------------- --| mInit --| Tell the cursor feedback object about this model and tooltip --\--------------------------------------------------------------------------- on mInit me pSpeed = float(pSpeed)/10 pServIntvl = 4 -- user definable pFly_to_flag = FALSE pRolling_flag = FALSE end --/--------------------------------------------------------------------------- --| mSetup --| the main world has been setup we can register ourself --\--------------------------------------------------------------------------- on mSetup me mbr = pSpr.member pMP_mdl = mbr.model(pTT_mdl) --pMP_mdl.debug = 1 -- are we deriving the TT name from the model name (double underscore marks the end of the name -- all other underscores will be taken to be space)? if pTTTxt_mn_flg then mdlnm = pMP_mdl.name emkr = "__" spc = "_" emkrpos = offset(emkr, mdlnm) if emkrpos then nm = mdlnm.char[1 .. emkrpos-1] -- now remove spaces repeat while nm contains spc if nm.char [1] = spc then nm = nm.char [2 .. nm.length] else if nm.char [nm.length] = spc then nm = nm.char [1 .. nm.length -1] else temp = nm sppos = offset(spc, temp) nm = temp.char [1 .. sppos-1] put " "&temp.char [sppos+1 .. temp.length] after nm end if end if end repeat pTTTxt = nm else -- name wrong - default to the model name pTTTxt = mdlnm end if end if -- hack to speed up dev. If the model name is listed in the node ID list, override whatever is entered as the node id -- hack me.mInit_default_nodes() group_name = "flg_m1_grp_"&pTT_mdl&string(me) pGrp_mdl = mbr.newGroup(group_name) -- in order for the tooltips -- make them children of the new group -- move the group to the user defined position and scale pGrp_mdl.transform = pMP_mdl.transform pGrp_mdl.addChild(pMP_mdl, #preserveWorld) --pGrp_mdl.pointAtOrientation = [vector(0.0000, 0.0000, 1.0000), vector(0.0000, 1.0000, 0.0000)] camerapos = mbr.camera[1].getworldTransform().position --pGrp_mdl.pointAt(camerapos, vector(0.0000, 1.0000, 0.0000)) pGrp_mdl.pointAt(mbr.camera[1]) pFacing_camera_transform = duplicate(pGrp_mdl.transform) gUI_control_obj.mSet_csr_fdbk(pGrp_mdl.name, me) end --/--------------------------------------------------------------------------- --| mInit_default_nodes --| very inefficient hack --\--------------------------------------------------------------------------- on mInit_default_nodes me id_txt = member ("node IDs").text lcnt = id_txt.line.count id_lst = [:] the itemdelimiter = ":" repeat with n = 1 to lcnt ln = id_txt.line[n] p = ln.item[1] v = value(ln.item[2]) if not voidP(v) then id_lst.addprop(p,v) else put "invalid ID at line "&n end if end repeat ID = id_lst.getAProp(pTTTxt) if not voidP(ID) then pID = ID else put "not auto ID for "&pTTTxt end if end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- on mService me -- start spinning the group as soo as it exists me.mAnimate() end --/--------------------------------------------------------------------------- --| mAnimate --| Do whatever type of animation is required --\--------------------------------------------------------------------------- on mAnimate me if not voidP(pMP_mdl) then if pRolling_flag then me.mRollover() else case pAxisRotation of "X": me.rotateX() "Y": me.rotateY() "Z": me.rotateZ() end case end if end if end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseWithin me if pRollover then -- prepare to start roating the model back towards the camera if pRolling_flag = FALSE then pRolling_flag = TRUE pInterpol_start_tm = the milliseconds pInterpol_end_tm = the milliseconds + pRollup_duration pInterp_startTransform = pGrp_mdl.transform end if end if end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseLeave me pRolling_flag = FALSE end --/--------------------------------------------------------------------------- --| mRollover --| Interplolate to the point at camera positon if we are not already there --\--------------------------------------------------------------------------- on mRollover me -- interpolate to the facing camera position if pRolling_flag = 1 then proportion = 1.0*(the milliseconds - pInterpol_start_tm)/float(pRollup_duration) if proportion > 1 then proportion = 1 -- flag so we know we have finished pRolling_flag = 2 end if tTransform = pInterp_startTransform.interpolate(pFacing_camera_transform, proportion) pGrp_mdl.transform = tTransform end if end --/--------------------------------------------------------------------------- --| rotateX --| Rotate on X axix --\--------------------------------------------------------------------------- on rotateX me, aModel pGrp_mdl.rotate(pSpeed,0,0) end --/--------------------------------------------------------------------------- --| rotateY --| Rotate on Y axix --\--------------------------------------------------------------------------- on rotateY me, aModel pGrp_mdl.rotate(0,pSpeed,0) end --/--------------------------------------------------------------------------- --| rotateZ --| Rotate on Z axix --\--------------------------------------------------------------------------- on rotateZ me, aModel pGrp_mdl.rotate(0,0,pSpeed) end --/--------------------------------------------------------------------------- --| mStart_fly_to --| Callback from camera control to say that the camera has just started zooming in --| it passes the fly to period so a model can make sure that it moves back to the correct orienation in time --\--------------------------------------------------------------------------- on mStart_fly_to me, fly_to_period pFly_to_flag = 1 pFly_to_period = fly_to_period pFly_to_end_time = the milliseconds + fly_to_period end --/--------------------------------------------------------------------------- --| mGetModels --| Get the names of the nodes that are in fact models --\--------------------------------------------------------------------------- on mGetModels me, aMember, aList repeat with j = member(aMember).model.count down to 1 if string(member(aMember).model[j]) contains "model" then -- make sure it's not an hitmdel or group pn = aMember.model[j].parent.name if aMember.model[j].parent.name = "World" then aList.add(aMember.model[j].name) end if end if end repeat return aList end --/--------------------------------------------------------------------------- --| mIs3D --| Check that aMember is a 3D member type --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member if aScript.mIs3D(this_mem) then tList = [] tList = aScript.mGetModels(this_mem, tList) tGPDList[#pTT_mdl] = \ [#comment:"Which model?",\ #format: #string,\ #range: tList,\ #default: tList[1]] tGPDList[#pTTTxt] = \ [#comment:"Tool tip text",\ #format: #string,\ #default: "a short description"] tGPDList[#pTTTxt_mn_flg] = \ [#comment:"Use model name for tool tip text",\ #format: #boolean,\ #default: 1] tGPDList[#pNodeID] = \ [#comment:"Node ID (0 means it's not a node)",\ #format: #integer,\ #default: 69] tGPDList[#pAutopilot_upto_dist] = \ [#comment:"If node, how close to autopilot to when clicked)",\ #format: #integer,\ #range:[#min:0, #max:500],\ #default: 50] tGPDList[#pSpeed] = \ [#comment:"Rotation speed - degrees per anim step x 10",\ #format: #integer,\ #default: 10] tGPDList[#pAxisRotation] = \ [#comment:"Which axis to rotate about",\ #format: #string,\ #range:["X", \ "Y", \ "Z"],\ #default: "Y"] tGPDList[#pRollover] = \ [#comment:"Face camera on rollover",\ #format: #boolean,\ #default: TRUE] tGPDList[#pRollup_duration] = \ [#comment:"Time taken for rollover animation (ms)",\ #format: #integer,\ #default: 500] end if return(tGPDList) end if end getPropertyDescriptionList model picker behaviourZN,>Fn>richard rossCASt%%)m1 4 nav arrows><>richard rossPZa-0 CASt,,0m1 4 nav arrows hilite><>richard rossPZa-0 CASt))==========AERnav button hot areasKQq-=r>richard rossT@CASt7! 7 6O6l6l6l6l666666666666666--button --nav --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| READ ME --| This behavior uses a field member to define the "hot areas of the button - "nav button hot areas" --| If you change the graphic for the button you will have to put new values into this member. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property pID property pUp_member_name property pDown_member_name property pUp_member property pDown_member property pBaseIm property pRollIm property pCurrentIm property pClicked_state property pMain_nav_control_obj property pHotspots_field_name property pHot_rect_list on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #btnnav -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() -- init behaviour specic items if pUp_member_name <> "no nav button required in this space" then pUp_member = member pUp_member_name -- user definable pDown_member = member (pDown_member_name) -- user definable me.mInit() else -- no arrows pHot_rect_list = [:] end if end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if if not voidP(pBaseIm) then pSpr.member.image = pBaseIm end if -- tidy up stored images pBaseIm = VOID pRollIm = VOID pCurrentIm = VOID pMain_nav_control_obj = VOID end --/--------------------------------------------------------------------------- --| incase the behaviour is applied on the fly --\--------------------------------------------------------------------------- on mDestroy me me.endsprite() end --/--------------------------------------------------------------------------- --| find out height so that the bottom bar can be sized correctly --\--------------------------------------------------------------------------- on mGet_dims me, aList if pUp_member_name <> "no nav button required in this space" then aList.addProp(pID, [pSpr.width, pSpr.height]) end if end --/--------------------------------------------------------------------------- --| mRelocate_UI --| place UI element at the right place relative to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list myRect = UI_rects_list.getAProp(pID) pSpr.rect = myRect end --/--------------------------------------------------------------------------- --| mInit --| store images of up member and down member --| and get the clickable areas --\--------------------------------------------------------------------------- on mInit me -- set the sprite member to the one selected pSpr.member = member(pUp_member) -- store images pBaseIm = duplicate(member (pUp_member).image) pRollIm = duplicate(member (pDown_member).image) pCurrentIm = duplicate(pBaseIm) if pHotspots_field_name = "no nav button required in this space" then alert "you have specified no nav hot spots - please look at the parameters on the nav arrow sprite's behavior" abort end if me.mAssign_hot_areas() pClicked_state = 0 end --/--------------------------------------------------------------------------- --| mSet_main_nav_control_obj --| Ref to main nav control is passed in --\--------------------------------------------------------------------------- on mSet_main_nav_control_obj me, inst pMain_nav_control_obj = inst -- pass the nav control a list of allowable nav directions based on the hotspot list direction_lst = [] cnt = pHot_rect_list.count repeat with n = 1 to cnt ttype = pHot_rect_list.getPropAt(n) direction_lst.add(ttype) end repeat pMain_nav_control_obj.mEnable_directions(direction_lst) end --- on mousewithin me relLoc = the mouseloc - point(pSpr.left, pSpr.top) me.mCheck_rollover(relLoc) end --- on mouseleave me relLoc = the mouseloc - point(pSpr.left, pSpr.top) me.mCheck_rollover(relLoc) end --- on mousedown me relLoc = the mouseloc - point(pSpr.left, pSpr.top) me.mCheck_mouseClick(relLoc) end --/--------------------------------------------------------------------------- --| mAssign_hot_areas --| The hot areas are stored in the "nav button hot areas" field member. --| This is in a line format for ease of editing - convert to list. --\--------------------------------------------------------------------------- on mAssign_hot_areas me data = member (pHotspots_field_name) hot_rect_list_str = "[" cnt = data.line.count repeat with n = 1 to cnt ln = data.line[n] if ln.char[1] <> "#" then alert "problem with line "&n&" of nav button hot areas member" put ln after hot_rect_list_str if n < cnt then put ", " after hot_rect_list_str end repeat put "]" after hot_rect_list_str pHot_rect_list = value(hot_rect_list_str) if not listP(pHot_rect_list) then alert "pHot_rect_list is not a list - problem with nav button hot areas member" sort pHot_rect_list end --/--------------------------------------------------------------------------- --| mArrow_key_release --| Allows feedback from keyboard nav so that releasing the arrow keys shows the button up state. --\--------------------------------------------------------------------------- on mArrow_key_release me, button_List -- make sure everything in the button_List is in it's up state cnt = button_List.count repeat with n = 1 to cnt but = button_List[n] but_rect = pHot_rect_list.getAProp(but) -- make sure that there is a button corresponding to the key if listP(but_rect) then copyRect = but_rect pCurrentIm.copyPixels(pBaseIm, copyRect, copyRect) end if end repeat if pHot_rect_list.count then pSpr.member.image = pCurrentIm end if end --/--------------------------------------------------------------------------- --| mArrow_key_pressed --| Allows feedback from keyboard nav so that pressing the arrow keys shows the button down state. --\--------------------------------------------------------------------------- on mArrow_key_pressed me, button_List -- make the button eqiivalent to the key pressed in the down stae -- make sure everything in the button_List is in it's up state cnt = button_List.count repeat with n = 1 to cnt but = button_List[n] but_rect = pHot_rect_list.getAProp(but) if listP(but_rect) then copyRect = but_rect pCurrentIm.copyPixels(pRollIm, copyRect, copyRect) end if end repeat if pHot_rect_list.count then pSpr.member.image = pCurrentIm end if end --/--------------------------------------------------------------------------- --| mCheck_rollover --| Checks for rollovers in a hot area. --\--------------------------------------------------------------------------- on mCheck_rollover me, loc -- make sure the arrow is in the upstate if the mouse is up if not(the mouseDown) and pClicked_state then me.mChange(#down) end if -- check for rollovers cnt = pHot_rect_list.count hit = #no repeat with n = 1 to cnt checkRect = pHot_rect_list[n] if inside(loc, pHot_rect_list[n]) then hit = pHot_rect_list.getPropAt(n) exit repeat end if end repeat if hit = #no then cursor -1 else cursor 280 end if end --/--------------------------------------------------------------------------- --| mCheck_rollover --| Checks for mouseclicks in a hot area. --\--------------------------------------------------------------------------- on mCheck_mouseClick me, loc -- check for hit cnt = pHot_rect_list.count hit = #no repeat with n = 1 to cnt checkRect = pHot_rect_list[n] if inside(loc, pHot_rect_list[n]) then hit = pHot_rect_list.getPropAt(n) exit repeat end if end repeat if hit = #no then else -- set flag in arrow control object to make it do the equivalent to whatever button we're clicking. me.mChange(#up, checkRect) pMain_nav_control_obj.mArrow_button_clicked(hit) end if end --/--------------------------------------------------------------------------- --| mChange --| Show up or down state. --\--------------------------------------------------------------------------- on mChange me, upDown, hitrect if upDown = #up then pClicked_state = 1 pCurrentIm = duplicate(pBaseIm) copyRect = hitrect pCurrentIm.copyPixels(pRollIm, copyRect, copyRect) else pClicked_state = 0 pCurrentIm = duplicate(pBaseIm) end if pSpr.member.image = pCurrentIm end --- on mFind_button_nav_control_behaviour me, aList aList.add( me ) end --- on mGet_offset me return (15 + pBaseIm.width) end --/--------------------------------------------------------------------------- --| mFind_usable_member --| Get a list of all members of the same type as the passed member in the internal and world mgr castlib --\--------------------------------------------------------------------------- on mFind_usable_member me, this_mem, tType, rtn_lst cnt = the number of members of castLib(1) repeat with i = 1 to cnt mem = member(i, 1) if mem.type = tType then rtn_lst.add(mem.name) end if end repeat cnt = the number of members of castLib("worldMgr") repeat with i = 1 to cnt mem = member(i, "worldMgr") if mem.type = tType then rtn_lst.add(mem.name) end if end repeat end --/--------------------------------------------------------------------------- --| mValidate_hot_area --| Remove all not hot areas fields --\--------------------------------------------------------------------------- on mValidate_hot_area me, aList killlst = [] cnt = aList.count repeat with m = 1 to cnt data = member(aList[m]).text lcnt = data.line.count if lcnt > 4 then -- too many lines killlst.add(aList[m]) else repeat with l = 1 to lcnt -- check each line ln = data.line[l] if ln.char[1] <> "#" then killlst.add(aList[m]) exit repeat end if if not (ln contains "rect") then killlst.add(aList[m]) exit repeat end if end repeat end if end repeat -- now remove the entries collected int he kill list repeat with n = killlst.count down to 1 tokill = killlst[n] pos = aList.findPos(tokill) if pos then aList.deleteAt(pos) else alert "lost pos button nav control behaviour" end if end repeat end --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member tType = #bitmap upnm = this_mem.name downnm = upnm&&"hilite" tList = ["no nav button required in this space"] aScript.mFind_usable_member(this_mem, tType, tList) tGPDList[#pUp_member_name] = \ [#comment:"Which navigation arrows member?",\ #format: #string,\ #range: tList,\ #default: upnm] tGPDList[#pDown_member_name] = \ [#comment:"Which navigation arrows hilite member?",\ #format: #string,\ #range: tList,\ #default: downnm] tList1 = [] tType = #field aScript.mFind_usable_member(this_mem, tType, tList1) aScript.mValidate_hot_area(tList1) tList1.add("no nav button required in this space") tGPDList[#pHotspots_field_name] = \ [#comment:"Which navigation arrows hilite member?",\ #format: #string,\ #range: tList1,\ #default: tList1[1]] end if return(tGPDList) end getPropertyDescriptionListbutton nav control behaviourv,>Fn>richard rossCASt%%)m1 2 nav arrows><>richard rossPa 0 CASt,,0m1 2 nav arrows hilite><>richard rossPa60 CASt22222222226:Gnav button hot areas 2 arrows4QB66=r>richard ross* CASt$$(mo help button=n>>richard rossPPT< * CAStz l --help --button --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj property ancestor, spritenum property pSpr property pID property pHelp_url property pShow_hlp_name on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #helpbtn -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --- --- overload ancestor --on mSetCurs me -- --end --- on mouseEnter me cursor 280 end mouseEnter --- on mouseleave me cursor -1 end --/--------------------------------------------------------------------------- --| mousedown --| The win manager opens a help web page in it's own window using the url defined for this page --\--------------------------------------------------------------------------- on mousedown me if goWinMgr.ilk = #instance then goWinMgr.mLaunchHelp( pHelp_url ) end if end --/--------------------------------------------------------------------------- --| mGet_dims --| find out height so that the bottom bar can be sized correctly --\--------------------------------------------------------------------------- on mGet_dims me, aList if pShow_hlp_name <> "no help required in this space" then aList.addProp(pID, [pSpr.width, pSpr.height]) end if end --/--------------------------------------------------------------------------- --| mRelocate_UI --| place UI element at the right place relative to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list if goWinMgr.ilk = #instance then myRect = UI_rects_list.getAProp(pID) pSpr.rect = myRect end if end --/--------------------------------------------------------------------------- --| mFind_usable_member --| find members of this type in castlib 1 or the wrldmgr --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mFind_usable_member me, this_mem, tType, rtn_lst cnt = the number of members of castLib(1) repeat with i = 1 to cnt mem = member(i, 1) if mem.type = tType then rtn_lst.add(mem.name) end if end repeat cnt = the number of members of castLib("worldMgr") repeat with i = 1 to cnt mem = member(i, "worldMgr") if mem.type = tType then rtn_lst.add(mem.name) end if end repeat end ------- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] tGPDList[#pHelp_url] = \ [#comment:"Help screen url?",\ #format: #string,\ #default: "http://www....."] this_mem = sprite(the currentSpriteNum).member tType = #bitmap show_hlp = this_mem.name tList = ["no help required in this space"] aScript.mFind_usable_member(this_mem, tType, tList) tGPDList[#pShow_hlp_name] = \ [#comment:"Which show help member?",\ #format: #string,\ #range: tList,\ #default: show_hlp] return(tGPDList) end if end getPropertyDescriptionList help button control behaviour07%7%,>Fn>richard rossCASt # show info=o]>richard rossPDQ< * CASt # hide info=p>richard rossPDQ * CASt< . i --info --button --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gSolar_system property ancestor, spritenum property pSpr property pID property iClickframe global gfrmtime global gStop on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #infobtn -- ID tag for lookup reference by peer objects if goPoolMgr.ilk = #instance then ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) end if pSpr = sprite(me.spritenum) me.mRegister() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if end --- --- overload ancestor on mSetCurs me end --- on mouseEnter me cursor 280 end mouseEnter --- on mouseleave me cursor -1 end --- on mouseDown me, loc if pSpr.member.name = "hide info" then gUI_control_obj.mHide_widgets() else -- make sure tooltips are hidden if objectP(gSolar_system) then gSolar_system.mHide_tool_tips() end if gUI_control_obj.mShow_widgets() end if end -- on mChange_state me, mbr_name pSpr.member = member(mbr_name) end --/--------------------------------------------------------------------------- --| find out height so that the bottom bar can be sized correctly --\--------------------------------------------------------------------------- on mGet_dims me, aList aList.addProp(pID, [pSpr.width, pSpr.height]) end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list if goWinMgr.ilk = #instance then myRect = UI_rects_list.getAProp(pID) pSpr.rect = myRect end if endinfo button control behaviour _,>Fn>richard rossCASt##' tool tip back=>richard rossP-  CAStd!%2tt text>п mText='>richard rosstextg3TEXd2??NoTextureCASt '-- cst -- fdbk --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This object handlers the cursor changes when you roll over a node and --| the tooltips when rolling over anything that has had tool tips attached. --\--------------------------------------------------------------------------- property p3DSpr property p3DMember property pSptLT property pSpr_rect property pFDBck_data_lst property pTT_object property pServIntvl property pLast_mouse_pos property pLast_roll_obj global gUI_control_obj global gDBG --/--------------------------------------------------------------------------- --| Constructor --| Destructor --\--------------------------------------------------------------------------- on new me pServIntvl = 20 pFDBck_data_lst = [:] sort pFDBck_data_lst pLast_mouse_pos = the mouseloc return me end --/--------------------------------------------------------------------------- --| mDestroy --| Destructor --\--------------------------------------------------------------------------- on mDestroy me -- clean pFDBck_data_lst if listP(pFDBck_data_lst) then cnt = pFDBck_data_lst.count repeat with n = 1 to cnt pFDBck_data_lst[n] = VOID end repeat pFDBck_data_lst = VOID end if if objectP(pTT_object) then pTT_object.mDestroy() pTT_object = VOID end if end --/--------------------------------------------------------------------------- --| mInit --| Set up the tooltip control object --\--------------------------------------------------------------------------- on mInit me, tDSpr p3DSpr = sprite(tDSpr) p3DMember = p3DSpr.member if not (pTT_object.ilk = #instance) then pTT_object = script("tool tip control object").new(p3DSpr) else pTT_object.mReinit() end if pSptLT = point(p3DSpr.left, p3DSpr.top) pSpr_rect = p3DSpr.rect end --/--------------------------------------------------------------------------- --| mAdd_to_fdbk_data --| Models register their feedback data to be displayed --\--------------------------------------------------------------------------- on mAdd_to_fdbk_data me, model, data -- check that we are not adding more than one tooltip to the same model pos = pFDBck_data_lst.findpos(model) if voidP(pos) then pFDBck_data_lst.addProp(model, data) else alert "you are adding more than one tooltip to the same model"&string(model) end if end --/--------------------------------------------------------------------------- --| mCheck_mse_click --| If we click on a model and it is a node then we must --| fly to that model and then do the node jump --\--------------------------------------------------------------------------- on mCheck_mse_click me relloc = the mouseloc - pSptLT clicked_model = me.mCheck_over_mdl(relloc) nodeID = 0 if clicked_model <> 0 then -- if there is a node assocated with this model then we must interploate to it cl_m_name = clicked_model.name inst = pFDBck_data_lst.getAProp(cl_m_name) if objectP(inst) then nodeID = inst.getAProp(#pNodeID) if voidP(nodeID) then nodeID = 0 end if end if -- check for interpolation if nodeID then gUI_control_obj.mFly_camera(clicked_model, 1, inst) end if end --/--------------------------------------------------------------------------- --| mService --| This is the main thread that does the checking if the rolled model --\--------------------------------------------------------------------------- on mService me if voidP(pSpr_rect) then exit -- don't do tooltips if we are on autopilot if gUI_control_obj.pAuto_pilot then exit --only check if the mouse is inside the sprite rect if not inside(the mouseloc, pSpr_rect) then exit relloc = the mouseloc - pSptLT rolled_model = me.mCheck_over_mdl(relloc) nodeID = 0 TTtxt = "" if rolled_model <> 0 then if gDBG then put "rolled_model is "&rolled_model -- if there is a node assocated with this model then show a finger cursor rl_m_name = rolled_model.name inst = pFDBck_data_lst.getAProp(rl_m_name) --inst = pFDBck_data_lst.getAProp(rolled_model) if not voidP(inst) then nodeID = inst.getAProp(#pNodeID) if voidP(nodeID) then nodeID = 0 TTtxt = inst.getAProp(#pTTTxt) if voidP(TTtxt) then TTtxt = "" -- tell the behaviour that there is a mousewithin inst.mMouseWithin() pLast_roll_obj = inst else -- tell the last rolled behaviour instance that we have rolled off if objectP(pLast_roll_obj) then pLast_roll_obj.mMouseLeave() pLast_roll_obj = VOID end if end if end if -- set the cursor accordingly if nodeID then put "cursor feedback object roll" cursor 280 else cursor -1 end if -- show or hide tooltips if TTtxt <> "" then pTT_object.mShow_tooltip (TTtxt, relloc) pLast_mouse_pos = the mouseloc else if the mouseloc = pLast_mouse_pos then pTT_object.mHide_tooltip (#pause) else pTT_object.mHide_tooltip (#nopause) end if end if end --/--------------------------------------------------------------------------- --| mCheck_roll_mdl --| Check if relloc is over model. If we hit an imported model --| we need to return the group name --\--------------------------------------------------------------------------- on mCheck_over_mdl me, relloc if voidP(p3DMember) then exit hitmodel = member(p3DMember).camera[1].modelUnderLoc(relloc) -- first check to see if it is an image on a plane. -- If we have hit transparency we need to check for models underneath -- additional models and model picker models are all part of groups with names -- starting with "flg_m1_grp". Step up the parent tree to see if the hit model is one of these. -- this saves the feedback list having to contain hundres of entries (with might be faster, untested) if not voidP(hitmodel) then nm = hitmodel.name mdl = hitmodel repeat while nm <> "World" if nm.char[1..10] = "flg_m1_grp" then return mdl end if l = nm.length if nm.char[l-9 ..l] = "tilt group" then return mdl mdl = member(p3DMember).model(nm).parent nm = member(p3DMember).model(nm).parent.name end repeat return hitmodel end if return 0 end cursor feedback objectna,>Fn>richard rossCAStI ;|property p3DMember property pHotRect property pTexture_name property pTexture_ref property pCurrent_TTText property pOverlayNum property pTT_Offset property pTT_RHS_Offset property pTT_width property pTT_height property pShowing_TT property pLast_loc property pTT_Text_offsetH property pTT_Text_offsetV property pTT_mbr_im property pStayUp_period property pStayUp_time property pLast_mouseloc property pCheck_rct property pCam1 on new me, spr p3DMember = spr.member pCam1 = p3DMember.camera[1] pCheck_rct = pCam1.rect me.mInit() return me end ---- on mDestroy me pCam1.removeBackdrop(1) -- clear the texture p3DMember.deleteTexture(pTexture_name) pTexture_ref = VOID pTT_mbr_im = VOID end --- on mInit me -- grab an overlay and render a dummy tooltip into it pTT_mbr = "tool tip back" pTT_mbr_im = member(pTT_mbr).image -- this dictates how big the start and end of the TT are pTT_Text_offsetH = 10 pTT_Text_offsetV = 5 pStayUp_period = 1*60 pStayUp_time = 0 pLast_mouseloc = the mouseloc pTT_width = member (pTT_mbr).width pTT_height = member (pTT_mbr).height pCurrent_TTText = "" pShowing_TT = 0 pLast_loc = point(-999, -999) im = member (pTT_mbr).image pTexture_name = "ss Tool tip texture" pTexture_ref = p3DMember.newtexture(pTexture_name,#fromImageObject, im) pTexture_ref.quality = #low -- create a new overlay using this texture -- put it off screen loc = point(-999, -999) pCam1.addOverlay(pTexture_ref, loc, 0) pOverlayNum = pCam1.overlay.count pTT_Offset = point(0, member(pTT_mbr).height) + point (-4, 2) pTT_RHS_Offset = point(member(pTT_mbr).width, member(pTT_mbr).height) + point (-4, 2) pTT_TOP_Offset = point(member(pTT_mbr).width, member(pTT_mbr).height) + point (-4, 2) end --- on mReinit me pCheck_rct = pCam1.rect end --- on mShow_tooltip me, text, loc pStayUp_time = pStayUp_period + the timer pLast_mouseloc = the mouseloc -- create the tooltip image and put this into the image if necessary if text <> pCurrent_TTText then pCurrent_TTText = text -- create new ttip image current_im = me.mCreate_new_TT() pTexture_ref.image = current_im pTT_width = current_im.width me.mMove_TT() end if if loc <> pLast_loc then pLast_loc = loc me.mMove_TT() end if -- make sure the TT linger for 3 seconds after the rollover has finished or if the mouse moves end --- on mMove_TT me -- place it at the passed loc -- make sure it does not go off the RHS limitH = pCheck_rct[3] - pTT_width if pLast_loc[1] > limitH then cor_H = -1*pTT_width else cor_H = 4 end if limitV = pCheck_rct[2] + pTT_height if pLast_loc[2] < limitV then cor_V = 2 else cor_V = -1*pTT_height -2 end if tt_loc = pLast_loc + point(cor_H, cor_V) pCam1.overlay[pOverlayNum].loc = tt_loc pShowing_TT = 1 end --- on mCreate_new_TT me -- create new ttip image member ("tt text").text = pCurrent_TTText -- create the background lastchar = pCurrent_TTText.length end_pont = charPosToLoc(member ("tt text"), lastchar+1) text_len = end_pont[1] TT_len = pTT_Text_offsetH + text_len + pTT_Text_offsetH -- smear a slice from the centre of the template all across this image source_rect = rect(pTT_Text_offsetH, 0, pTT_Text_offsetH+1, pTT_height) im = image(TT_len, pTT_height, 16) im.copyPixels(pTT_mbr_im, im.rect, source_rect) -- put the front and back in target_rect = rect(0, 0, pTT_Text_offsetH, pTT_height) im.copyPixels(pTT_mbr_im, target_rect, target_rect) target_rect = rect(TT_len - pTT_Text_offsetH, 0, TT_len, pTT_height) w = pTT_mbr_im.width source_rect = rect(w - pTT_Text_offsetH, 0, w, pTT_height) im.copyPixels(pTT_mbr_im, target_rect, source_rect) -- add the text text_im = member ("tt text").image text_rect = rect(0,0,text_len, text_im.height) offset = point(pTT_Text_offsetH, pTT_Text_offsetV) im.copyPixels (text_im, text_rect + rect(offset, offset), text_rect, [#color: rgb(0,0,0)]) return im end --- on mHide_tooltip me, pauseFlag -- don't hide if the cursor has not moved for the timeout period if pauseFlag = #pause then if the timer < pStayUp_time then -- if the mouseloc = pLast_mouseloc then exit --end if end if end if if pShowing_TT = 1 then pShowing_TT = 0 pLast_loc = point(-999, -999) pCam1.overlay[pOverlayNum].loc = point(-99999, -99999) end if end tool tip control object&3q||,>Fn>richard rossCASt&++;;;;;?CPloading world message>п mText=>richard rosstext3TEXd2??NoTextureCASt&++;;;;;?CPtesting speed message>п mText=>richard rosstext3TEXd2??NoTextureCAStR D--message --align --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global gUI_control_obj on beginsprite me spr = sprite(me.spritenum) --position the sprite along the bottom of the browser frame at the centre b_rect = gUI_control_obj.pBrowser_frame_rect centre = b_rect[1] + (b_rect[3] - b_rect[1])/2 l = centre - spr.member.width/2 t = b_rect[4] - spr.member.height*2 spr.loc = point(l,t) end message align}1Z,>Fn>richard rossCASt1p 1b00000000000000000000--scrolling --background --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour allows the user to add additional models to the world --| They can define the positon and scale of the model within the world --| They can also define some behaviour. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gDBG global gUtils_obj property ancestor, spritenum property pSpr property pID property pMbr property pPano_mem property pPano_source property pBackdrop_im property pBD_tile_v property pBD_tile_h property ptexture_dim property pTestureList property pBackdrop_cnt property pBackdrop_im_w property pDegree_amt property pRot on beginSprite me --/--------------------------------------------------------------------------- -- |the backdrop is used instead of a skybox. It uses n backdrops that use --| pBD_tile_v x pBD_tile_h different textures. These textures are set to chunks of the --| stary sky image via imaging lingo. As the camera is rotated the --| image chunks are grabbed from offset differnt chunks of the big image and the textures are updated --| so giving scrolling. --| Please note that this is not included in any speed tests as initial tests showed almost negligable performace hits with it. --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #scrlback -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mRegister() end --- on mInit me, spr_rect -- if they have been set up before we must clear the old ones if listP(pTestureList) then me.mDestroy() end if pSpr = sprite(me.spritenum) if voidP(spr_rect) then spr_rect = pSpr.rect pMbr = pSpr.member --pMbr.resetWorld() pPano_source = pPano_mem.image im = me.get_current_im_chunk() pano_w = im.width pDegree_amt = 1.0*pano_w/360 pRot = 0 texture_dim = 256 me.mInit_bac(im, texture_dim, spr_rect) end --- --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if me.mDestroy() end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- -- --on mService me -- -- -- start spinning the group as soo as it exists -- -- me.mAnimate() -- --end -- --- --on enterframe me -- -- if keypressed(123) then -- me.mUpdate_backdrop(1) -- else -- if keypressed(124) then -- me.mUpdate_backdrop(-1) -- end if -- end if -- --end -- --- on get_current_im_chunk me -- make an image with the same height as the 3D sprite height but with the width of the original. Take it from the centre. new_height = pSpr.height t = (pPano_source.height - new_height)/2 b = t + new_height w = pPano_source.width -- just incase of huge monitors or small panos if t < 0 then t = 0 b = pPano_source.height w = integer(w*(1.0*new_height/b)) end if -- just in case it's not wide enough if w < pSpr.width then im = image(w*2, new_height, 16) im.copyPixels(pPano_source, rect(0,0,w,new_height), rect(0, t, pPano_source.width, b)) im.copyPixels(pPano_source, rect(w,0,w*2,new_height), rect(0, t, pPano_source.width, b)) else im = image(w, new_height, 16) im.copyPixels(pPano_source, im.rect, rect(0, t, pPano_source.width, b)) end if put "xxxxxx must redo the backdrops after the speed test" return im end --- on mDestroy me -- clear the backdrop models if listP(pTestureList) then cnt = pTestureList.count repeat with n = cnt down to 1 pMbr.camera[1].removeBackdrop(n) end repeat -- clear the textures that were used repeat with n = 1 to cnt the_texture = pTestureList.getPropAt(n) pMbr.deleteTexture(the_texture) end repeat end if pBackdrop_im = VOID gUtils_obj.mClean_list(pTestureList) pTestureList = VOID end --- on mInit_bac me, im, texture_dim, cam_rect pBackdrop_im = im ptexture_dim = texture_dim -- work out how many textures / backgrounds are required. pBD_tile_h = cam_rect.width/ptexture_dim if cam_rect.width mod ptexture_dim then pBD_tile_h = pBD_tile_h + 1 -- to do the shuffling we need an extra one in the row pBD_tile_h = pBD_tile_h + 1 pBD_tile_v = cam_rect.height/ptexture_dim if cam_rect.height mod ptexture_dim then pBD_tile_v = pBD_tile_v + 1 cnt = 1 pTestureList = [:] repeat with h = 1 to pBD_tile_h repeat with v = 1 to pBD_tile_v the_texture = "h"&h&", v"&v destRect_or_quad = rect(0, 0, ptexture_dim, ptexture_dim) sourceRect = ptexture_dim*rect( h-1, v-1, h, v) im = image(ptexture_dim, ptexture_dim, 8) im.copyPixels(pBackdrop_im, destRect_or_quad, sourceRect) texture_ref = pMbr.newtexture(the_texture,#fromImageObject, im) texture_ref.quality = #low -- create a new backdrop using this texture loc = ptexture_dim*point(h-1, v-1) pMbr.camera[1].addBackdrop(texture_ref, loc, 0) data = [:] data.addProp(#the_im, im) data.addProp(#the_rect, sourceRect) data.addProp(#the_loc, loc) pTestureList.addProp(the_texture, data) cnt = cnt + 1 end repeat end repeat pBackdrop_cnt = pMbr.camera[1].backdrop.count pBackdrop_im_w = pBackdrop_im.width end --- on mUpdate_backdrop me, amt_deg amt = integer(pDegree_amt*amt_deg)*2 cnt = 1 --- shuffle the loc of the backdrops along repeat with h = 1 to pBD_tile_h repeat with v = 1 to pBD_tile_v the_texture = "h"&h&", v"&v data = pTestureList.getAProp(the_texture) oldloc = data.the_loc newloc = oldloc + point(amt, 0) if amt > 0 then -- moving right c_rect = pMbr.camera[1].rect right_edge = c_rect.width if newloc[1] > right_edge then -- the texture has gone off camera to the rhs newloc = point(newloc[1] - pBD_tile_h*ptexture_dim , newloc[2]) -- change the texture to the next one along the sky strip me.mUpdate_texture(h, v, #right) end if else -- moving left -- has the texture gone off camera to the lhs if newloc[1] < -1*ptexture_dim then newloc = point(pBD_tile_h*ptexture_dim + newloc[1], newloc[2]) -- change the texture to the next one along the sky strip me.mUpdate_texture(h, v, #left) end if end if pMbr.camera[1].backdrop[cnt].loc = newloc data.the_loc = newloc cnt = cnt + 1 end repeat end repeat end ---- on mUpdate_texture me, h, v, direction -- update the texture of the backdrop to the next chunk along the strip if direction = #left then source_jmp_amt = ptexture_dim*pBD_tile_h else source_jmp_amt = -1*ptexture_dim*pBD_tile_h end if the_texture = "h"&h&", v"&v data = pTestureList.getAProp(the_texture) old_sourceRect = data.the_rect im = data.the_im destRect_or_quad = rect(0, 0, ptexture_dim, ptexture_dim) new_sourceRect = old_sourceRect + rect(point(source_jmp_amt, 0), point(source_jmp_amt, 0)) -- now check for going over the edge by an entire textures worth if new_sourceRect[3] > pBackdrop_im_w then -- do we need to nibble a bit from each end or do we totally wrap around? if new_sourceRect[1] >= pBackdrop_im_w then -- no nibble -- wrap around and start fromthe beginning new_sourceRect = rect(new_sourceRect[1]- pBackdrop_im_w, old_sourceRect[2], new_sourceRect[3] - pBackdrop_im_w , old_sourceRect[4]) im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) pMbr.texture(the_texture).image = im else -- nibble -- end bit im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) -- front bit nibble_len = new_sourceRect[3] - pBackdrop_im_w front_nibble_source = rect(0, new_sourceRect[2], nibble_len, new_sourceRect[4]) nibble_dest = rect(ptexture_dim - nibble_len,0, ptexture_dim, ptexture_dim) im.copyPixels(pBackdrop_im, nibble_dest, front_nibble_source) pMbr.texture(the_texture).image = im end if else if new_sourceRect[1] < 0 then -- test for nibble if new_sourceRect[3] <= 0 then -- no nibble. Just show the start -- wrap back and start from the end new_sourceRect = rect(pBackdrop_im_w + new_sourceRect[1], old_sourceRect[2], pBackdrop_im_w + new_sourceRect[3] , old_sourceRect[4]) im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) pMbr.texture(the_texture).image = im else -- nibble -- end bit im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) -- front bit nibble_len = -1*new_sourceRect[1] front_nibble_source = rect(pBackdrop_im_w - nibble_len, new_sourceRect[2], pBackdrop_im_w, new_sourceRect[4]) nibble_dest = rect(0,0, nibble_len, ptexture_dim) im.copyPixels(pBackdrop_im, nibble_dest, front_nibble_source) pMbr.texture(the_texture).image = im end if else -- no adjustment required im.copyPixels(pBackdrop_im, destRect_or_quad, new_sourceRect) pMbr.texture(the_texture).image = im end if end if -- update the stored rect data.the_rect = new_sourceRect end --- --/--------------------------------------------------------------------------- --| mFind_graphics --| Get a list of all 3D members in the "models" castlib --\--------------------------------------------------------------------------- on mFind_graphics me rtn_lst = [] ccnt = the number of castlibs repeat with c = 1 to ccnt cnt = the number of members of castLib(c) repeat with i = 1 to cnt mem = member(i, "models") if mem.type = #bitmap then rtn_lst.add(mem.name) end if end repeat end repeat return rtn_lst end --- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] tList = aScript.mFind_graphics(tList) tGPDList[#pPano_mem] = \ [#comment:"Which pano graphic?",\ #format: #graphic,\ #default: member "pano"] return(tGPDList) end if end getPropertyDescriptionList scrolling background0,>Fn>richard rossCASt m _ property pThe_last_channel property pStart_vol_spts property pEnd_vol_spts on new me pThe_last_channel = the lastChannel pStart_vol_spts = 1 pEnd_vol_spts = 1 return me end --- on mDestroy me end --- on mClean_list me, the_list if not listP(the_list) then exit -- this is used to clear out a list - it's a good thing to do to avoid memory leaks -- step through all the list entries and wipe out any lists within lists cnt = the_list.count repeat with n = 1 to cnt entry = the_list[n] if ilk(entry) = #list or ilk(entry) = #proplist then -- if it's a list, recursively clean it me.mClean_list(the_list[n]) else -- if it's an object, then destroy it if ilk(entry) = #object then the_list[n].mDestroy() end if end if the_list[n] = VOID end repeat the_list = VOID end --- on mGet_next_free_sprite me -- find the next unused sprite repeat with thisSprite = pStart_vol_spts to pThe_last_channel if not sprite(thisSprite).membernum then puppetSprite thisSprite, TRUE if thisSprite > pEnd_vol_spts then pEnd_vol_spts = thisSprite end if return thisSprite end if end repeat alert "out of sprites" end --- on mClear_sprites me -- run through all used sprites, destroy their behaviours then kill the sprite repeat with spt = pStart_vol_spts to pEnd_vol_spts me.mClear_spr(spt) end repeat pEnd_vol_spts = pStart_vol_spts end --- on mClear_spr_list me, spr_list -- run through all used sprites in a list, destroy their behaviours then kill the sprite sort spr_list cnt = spr_list.count if cnt then repeat with n = cnt down to 1 spt = spr_list[n] me.mClear_spr(spt) if spt >= pEnd_vol_spts then pEnd_vol_spts = spt - 1 end repeat end if end --- on mClear_spr me, spt -- return all the sprite propertis to the defaults sptObj = sprite(spt) if sptObj.membernum then sptObj.ink = 0 sptObj.locH = -10000 -- offstage sptObj.locZ = spt sptObj.blend = 100 sptObj.stretch = FALSE sptObj.forecolor = 255 sptObj.backcolor = 0 sptObj.member = 0 -- clear behavior list bLst = sptObj.scriptinstancelist bCnt = bLst.count repeat with i=1 to bCnt -- make sure any objects in the behaviours are wiped out bLst[i].mDestroy() bLst[i] = 0 end repeat sptObj.scriptinstancelist = [] puppetSprite(spt,FALSE) end if end --- on mGetEmptySlot me, the_castlib, nextpos -- return the next empty slot in a particular castlib if voidP(nextpos) then nextpos = 1 if voidP(the_castlib) then the_castlib = 1 repeat while true if the type of member nextpos of castlib the_castlib = #empty then return nextpos nextpos = nextpos + 1 end repeat end --- utils|0N,>Fn>richard rossCASt  $ screengrab=@>richard rossP%CASt             $(5--screen --grab --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr, glProps -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global goNetMgr property ancestor, spritenum property pSpr property pID property pIni_im on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #scrngrb -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) pSpr = sprite(me.spritenum) me.mRegister() (the actorlist).add(me) end --/--------------------------------------------------------------------------- --| stepframe --| initialisation is done on the first stepframe to allow all sprites to register --\--------------------------------------------------------------------------- on stepframe me pIni_im = duplicate(pSpr.member.image) prf_mn = get_prefs_nm("area") prev_area = goNetMgr.mGetPref(prf_mn) -- retrieve last 3D area sprite_rect = gUI_control_obj.mGet_sprite_rect (prev_area) im = image(sprite_rect[3] - sprite_rect[1], sprite_rect[4] - sprite_rect[2], 16) -- copypixels to the right size source_im = member("screengrab_ini").image im.copyPixels(source_im, im.rect, source_im.rect) pSpr.member.image = im -- now locate it at the position where the world will be set up cur_loc = pSpr.loc fin_loc = point( sprite_rect[1] + (sprite_rect[3] - sprite_rect[1])/2, sprite_rect[2] + (sprite_rect[4] - sprite_rect[2])/2 ) offset = fin_loc - cur_loc pSpr.member.regpoint = pSpr.member.regpoint - offset pos = (the actorlist).findpos(me) if pos then (the actorlist).deleteAt(pos) else alert "lost pos in screen grab control behaviour" end if end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if -- reset the members image to the starting image if pIni_im.ilk = #image then if pIni_im.width = 1 then pSpr.member.image = pIni_im else -- this should only happen in dev im = image(1, 1, 8) im.fill(0, 0, 1, 1, rgb(255,0,0)) pSpr.member.image = im end if pIni_im = VOID end if end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area --pSpr.locH = -99999 end --/--------------------------------------------------------------------------- --| mHide --| hides the static image --\--------------------------------------------------------------------------- on mHide me pSpr.locH = -99999 end --/--------------------------------------------------------------------------- --| mScreen_grab --| Screen grab the 3D world into the bitmap and place it in the same position that --| the 3D world occupied. --\--------------------------------------------------------------------------- on mScreen_grab me, the_rect, tDMem img = image(the_rect.width, the_rect.height, 16) -- limit to 16-bit for mem efficiency if (img.ilk = #image) then -- VOID indicates no mem avail for image creation img.fill(the_rect, rgb(0,0,0)) -- first fill with black (in case no bkgd img) img.copyPixels((the stage).image, the_rect, the_rect) end if pSpr.member.image = img pSpr.member.regpoint = point(0,0) pSpr.rect = the_rect pSpr.width = sprite (spritenum).member.width pSpr.height = sprite (spritenum).member.height end screen grab control behaviour0,>Fn>richard rossCASt key line=3>richard rossCASt  Yiiii}}}}}}--key --line --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- global gUI_control_obj global g3D_sprite_rect property ancestor, spritenum property pSpr property pID on beginSprite me --/--------------------------------------------------------------------------- --| register --\--------------------------------------------------------------------------- pID = #keyline -- ID tag for lookup reference by peer objects pSpr = sprite(me.spritenum) me.mRegister() -- move it into the initial position if not voidP(g3D_sprite_rect) then inflated_rect = inflate(g3D_sprite_rect, 1, 1) pSpr.rect = inflated_rect end if end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| mRelocate_UI --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area -- if threeD_sprite_rect = usable_area then -- -- -- no key line -- pSpr.locH = -99999 -- else inflated_rect = inflate(threeD_sprite_rect, 1, 1) pSpr.rect = inflated_rect -- end if endkeyline control| 0XOO,>Fn>richard rossCASt7 77%787878787L7L7L7L7L7L7`7`7`7`7`7`7d7h7u--add --image --/--------------------------------------------------------------------------- --| IMPORTANT --| DO NOT EDIT ANY OF THE SCRIPTS IN THIS CASTLIB --| Read the "read me" in cast 1 of castlib 1 --\--------------------------------------------------------------------------- --/--------------------------------------------------------------------------- --| This behaviour allows the user to add additional models to the world --| They can define the positon and scale of the model within the world --| They can also define some behaviour. --\--------------------------------------------------------------------------- global goWinMgr, goPoolMgr -- window and pool mgr classes (inited in preparemovie) global gUI_control_obj global gDBG property ancestor, spritenum property pSpr property pID property p3DMember property pServIntvl property pBumpChan property pInitial_im property pFinal_im property pImage_seq_list property pImage_seq_pos property pFinal_roll_im property pRoll_direction property pPlane_model property pFace_camera property pTxtr property pAnim_intlv property pNext_anim_time property pPosx property pPosy property pPosz property pRot_x property pRot_y property pRot_z property pScale property pNodeID property pTTTxt property pAutopilot_upto_dist on beginSprite me --/--------------------------------------------------------------------------- --| create base class and register with WinMgr --\--------------------------------------------------------------------------- pID = #addImage -- ID tag for lookup reference by peer objects ancestor = goPoolMgr.mNew(#cUIbeh) ancestor.mInit(me, pID) goWinMgr.mRegBeh(me, pID, me.spritenum, VOID) me.mRegister() me.mInit() end --/--------------------------------------------------------------------------- --| mInit --\--------------------------------------------------------------------------- on mInit me pCollision_snd = member "bump" -- user definable pSpr = sprite(me.spritenum) pServIntvl = 4 -- user definable p3DMember = pSpr.member pBumpChan = 1 pNext_anim_time = the milliseconds + pAnim_intlv if pFinal_im <> "no animation" then -- an animation has been specified if pFinal_roll_im <> "no animation" then alert "you can't specify a continuous animation and a rollover - check the parameters in the behavior on the 3D sprite" pImage_seq_list = [] tStart = member (pInitial_im).number tEnd = member (pFinal_im).number repeat with n = tStart to tEnd pImage_seq_list.add(n) end repeat pImage_seq_pos = 1 else -- a rollover has been specified pImage_seq_list = [] tStart = member (pInitial_im).number tEnd = member (pFinal_roll_im).number repeat with n = tStart to tEnd pImage_seq_list.add(n) end repeat pImage_seq_pos = 1 pRoll_direction = 0 end if -- check that the node ID is an integer if not (pNodeID.ilk = #integer) then alert "node ID "&pNodeID&"in additional model for "&pInitial_im"& is not an integer, please reenter it" end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| unregister from WinMgr, and free ancestor --\--------------------------------------------------------------------------- on endsprite me if objectP(goWinMgr) then goWinMgr.mUnRegBeh(me) end if if objectP(goPoolMgr) then goPoolMgr.mFree(ancestor) -- free ancestor end if -- tidy up the 3D stuff just to be tidy if not voidP(pTxtr) then txture_name = pTxtr.name p3DMember.deleteTexture(txture_name) pTxtr = VOID mdl_name = pPlane_model.name p3DMember.model(mdl_name).removeFromWorld() cnt = pImage_seq_list.count repeat with n = 1 to cnt pImage_seq_list[n] = VOID end repeat pImage_seq_list = VOID end if end --/--------------------------------------------------------------------------- --| mService --| from the main world controller --\--------------------------------------------------------------------------- on mService me -- start spinning the group as soo as it exists me.mAnimate() end --/--------------------------------------------------------------------------- --| mAnimate --| Do whatever type of animation is required --\--------------------------------------------------------------------------- on mAnimate me if pFace_camera then -- rotate the model so it always faces the camera keeping it's y component or rotation cam_pos = p3DMember.camera[1].getWorldTransform().position mdl_pos_y = pPlane_model.getWorldTransform().position.y position = cam_pos position.y = mdl_pos_y pPlane_model.pointAt(position) end if -- do we animate through a series of textures if pFinal_im <> "no animation" then if the milliseconds > pNext_anim_time then pImage_seq_pos = pImage_seq_pos + 1 if pImage_seq_pos > pImage_seq_list.count then pImage_seq_pos = 1 nxt = pImage_seq_list[pImage_seq_pos] if ilk(nxt) <> #image then im = member (nxt).image pImage_seq_list.setat(pImage_seq_pos, im) else im = nxt end if pTxtr.image = im pNext_anim_time = the milliseconds end if else -- are we doing a rollover? if pRoll_direction then if the milliseconds > pNext_anim_time then pImage_seq_pos = pImage_seq_pos + pRoll_direction if pImage_seq_pos > pImage_seq_list.count then pImage_seq_pos = pImage_seq_list.count + 1 pRoll_direction = 0 exit else if pImage_seq_pos < 1 then pRoll_direction = 0 exit end if end if nxt = pImage_seq_list[pImage_seq_pos] if ilk(nxt) <> #image then im = member (nxt).image pImage_seq_list.setat(pImage_seq_pos, im) else im = nxt end if pTxtr.image = im pNext_anim_time = the milliseconds end if end if end if end --/--------------------------------------------------------------------------- --| mAdd_image --| Create as many 256/256 planes as is required to show the selected image --| Create a new group of name "member name"&group. Add a string of the inst to make sure that --| it's a unique name. --\--------------------------------------------------------------------------- on mAdd_image me -- create the required number of planes pPlane_model = me.mCreate_Models() pos = vector(pPosx, pPosy, pPosz) s = float(pScale)/100 scl = vector(s, s, s) pPlane_model.transform.position = pos pPlane_model.transform.scale = scl -- now tell the cursor feedback object about it's node and tooltips gUI_control_obj.mSet_csr_fdbk(pPlane_model.name, me) end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseWithin me -- if there is a rollover animation sequence and we have not already started then start it if pRoll_direction = 0 then pRoll_direction = 1 end --/--------------------------------------------------------------------------- --| mMouseWithin --| From the cursor feedback object --\--------------------------------------------------------------------------- on mMouseLeave me if pRoll_direction = 0 then pRoll_direction = -1 end --/--------------------------------------------------------------------------- --| mCreate_Models --| Get the names of the nodes that are in fact models --\--------------------------------------------------------------------------- on mCreate_Models me -- first calculate how many planes are required -- then create the texture im = member (pInitial_im).image planeName = pInitial_im&&string(me) res = p3DMember.newmodelresource(planeName & "res", #plane) res.length = im.height res.width = im.width obj = p3DMember.newmodel(planeName, res) shd = p3DMember.newshader(planeName & "shd", #standard) the_texture = planeName&"_texture" pTxtr = p3DMember.newtexture(the_texture,#fromImageObject , im) -- if it is a 32 bit image set the renber format to support HQ alpha if im.depth = 32 then pTxtr.renderFormat = #rgba8888 end if shd.texture = pTxtr -- --- check we can take this texture size -- -- max_w = pMaxTexturesizes[1] -- -- if Shd.texture.width > max_w then -- Shd.texture.scaledown() -- end if -- -- max_h = pMaxTexturesizes[2] -- -- if Shd.texture.height > max_h then -- Shd.texture.scaledown() -- end if -- obj.shaderlist = shd --aList.add(p3DMember.model(planename)) return obj end --/--------------------------------------------------------------------------- --| mStart_fly_to --| Callback from camera control to say that the camera has just started zooming in --| it passes the fly to period so a model can make sure that it moves back to the correct orienation in time --\--------------------------------------------------------------------------- on mStart_fly_to me, fly_to_period pFly_to_flag = 1 pFly_to_period = fly_to_period pFly_to_end_time = the milliseconds + fly_to_period end --/--------------------------------------------------------------------------- --| mIs3D --| Check that we have dropped this behaviour on a 3D member --\--------------------------------------------------------------------------- on mIs3D(me, aMember) tIs3D = FALSE case aMember.type of #shockwave3d: tIs3D = TRUE #text: if aMember.displayMode = #mode3D then tIs3D = TRUE end if end case return(tIs3D) end mIs3D --- --/--------------------------------------------------------------------------- --| mFind_usable_member --| find members of this type in castlib 1 --\--------------------------------------------------------------------------- on mFind_usable_member me, this_mem, tType, rtn_lst cnt = the number of members of castLib(1) repeat with i = 1 to cnt mem = member(i, 1) if mem.type = tType then rtn_lst.add(mem.name) end if end repeat end ------- on getPropertyDescriptionList(aScript) if the currentSpriteNum > 0 then tGPDList = [:] this_mem = sprite(the currentSpriteNum).member if aScript.mIs3D(this_mem) then tList = [] tType = #bitmap aScript.mFind_usable_member(this_mem, tType, tList) tGPDList[#pInitial_im] = \ [#comment:"Which inital image?",\ #format: #string,\ #range: tList,\ #default: tList[1]] tList1 = duplicate(tList) tList1.add("no animation") tGPDList[#pFinal_im] = \ [#comment:"Which final image in animation (must be sequential)?",\ #format: #string,\ #range: tList1,\ #default: tList1[tList1.count]] tGPDList[#pFinal_roll_im] = \ [#comment:"Which final rollover image (must be sequential)? You can't have an anim and a rollover.",\ #format: #string,\ #range: tList1,\ #default: tList1[tList1.count]] tGPDList[#pAnim_intlv] = \ [#comment:"Anim interval (ms)",\ #format: #integer,\ #default: 100] tGPDList[#pFace_camera] = \ [#comment:"Always face camera?",\ #format: #boolean,\ #default: 1] tGPDList[#pPosX] = \ [#comment:"Postion x",\ #format: #integer,\ #default: 0] tGPDList[#pPosY] = \ [#comment:"Postion y",\ #format: #integer,\ #default: 0] tGPDList[#pPosZ] = \ [#comment:"Postion z",\ #format: #integer,\ #default: 0] tGPDList[#pRot_x] = \ [#comment:"Rotation X",\ #format: #integer,\ #default: 0] tGPDList[#pRot_y] = \ [#comment:"Rotation Y",\ #format: #integer,\ #default: 0] tGPDList[#pRot_z] = \ [#comment:"Rotation Z",\ #format: #integer,\ #default: 0] tGPDList[#pScale] = \ [#comment:"Scale x 100",\ #format: #integer,\ #range:[#min:0, #max:1000],\ #default: 100] tGPDList[#pTTTxt] = \ [#comment:"Tool tip text",\ #format: #string,\ #default: "a short descrition"] tGPDList[#pNodeID] = \ [#comment:"Node ID (0 means it's not a node)",\ #format: #integer,\ #default: 0] tGPDList[#pAutopilot_upto_dist] = \ [#comment:"If node, how close to autopilot to when clicked)",\ #format: #integer,\ #range:[#min:0, #max:500],\ #default: 50] end if return(tGPDList) end if end getPropertyDescriptionList add image as plane|0N h h,>Fn>richard rossCAStg  $(5 vendorlist>п mText;P>richard rosstext3TEXd2??NoTextureCASt bump=>richard rossCASt # sound off>Op>richard rossP!  CASt PZZZZnnnnnnon dummy -- this just creates an empty line in the behavors dropdown menu end ----- dev|0N,>Fn>richard rossCASt Phhhh||||||on dummy -- this just creates an empty line in the behavors dropdown menu end *** dev tools behaviors|0N,>Fn>richard rossCASt!.dev - show browser frame=~H>richard rossvCASt       !%2--key --line global gUI_control_obj property ancestor, spritenum property pSpr property pID on beginSprite me --/--------------------------------------------------------------------------- --| register --\--------------------------------------------------------------------------- pID = #shbr -- ID tag for lookup reference by peer objects pSpr = sprite(me.spritenum) me.mRegister() end --/--------------------------------------------------------------------------- --| mRegister_UI --| aList - the list to get back the data to be registered --\--------------------------------------------------------------------------- on mRegister_UI me, aList aList.addProp(pID, me) end --/--------------------------------------------------------------------------- --| mRegister --| type - the type of UI control - an unique identifier --| inst - the object ref. --\--------------------------------------------------------------------------- on mRegister me if objectP(gUI_control_obj) then gUI_control_obj.mRegister(pID, me) end if end --/--------------------------------------------------------------------------- --| place UI element at the right place relatuive to --| the current size of the world sprite and browser frame size --\--------------------------------------------------------------------------- on mRelocate_UI me, threeD_sprite_rect, usable_area, UI_rects_list, pBrowser_frame_rect pSpr.rect = pBrowser_frame_rect end --- dev - show br frame}1Ycscs,>Fn>richard rossCASts,,,,,04Aoutput>п mTextGrichard rosstextG3TEXd2??NoTextureCASt / ! h z z z z --Ultimo 00, Jakob Hede Madsen --Attach this behavior to a field or text to see fps --As it uses the actorList it will count both native updates, --and those caused by "updateStage". --Samples are included for a timespan determined by "pRange" in mS --The display will update each "pRefreshDur" mS property pTimeList property pSum property pRange property pSampleCnt property pNextTime property pRefreshDur property pMbr property pText property pLapseAverageTime property pLastTime property pSpr global gUI_control_obj on beginSprite me ---- pRange = 1000 pRefreshDur = 500 ---- call #mFpsMeterRemove, (the actorList).duplicate() (the actorList).add(me) pTimeList = [:] pSum = 0.0 pSampleCnt = 0 pNextTime = 0 pMbr = sprite(me.spriteNum).member pMbr.text = "--" pSpr = sprite (me.spritenum) --position the sprite along the bottom of the browser frame at the centre -- b_rect = gUI_control_obj.pBrowser_frame_rect -- -- l = b_rect[3] - pSpr.member.width -- -- t = b_rect[4] + pSpr.member.height*2 -- -- pSpr.loc = point(l,t) end on endSprite me me.mFpsMeterRemove() end on mResize_sprite me, hide_flag if hide_flag = 1 then pSpr.locH = -99999 else --pSpr.loc = point(g3D_sprite_rect[3], g3D_sprite_rect[4]) - point(70, -5) end if end on stepFrame me theTime = the milliSeconds if pLastTime.voidP then pLastTime = theTime return end if theLapsedTime = theTime - pLastTime pLastTime = theTime pSum = pSum + theLapsedTime pSampleCnt = pSampleCnt + 1 pTimeList.addProp(theTime, theLapsedTime) theIncludeTime = theTime - pRange repeat while pTimeList.getPropAt(1) < theIncludeTime pSum = pSum - pTimeList.getAt(1) pTimeList.deleteAt(1) pSampleCnt = pSampleCnt - 1 end repeat if pSampleCnt = 0 then return pLapseAverageTime = pSum / pSampleCnt if pLapseAverageTime = 0 then return theFps = 1000 / pLapseAverageTime if theTime < pNextTime then return pNextTime = theTime + pRefreshDur fp = the floatPrecision the floatPrecision = 1 --theNewText = theFps && "/" && the FrameTempo theNewText = string(theFps )&&"fps" the floatPrecision = fp if theNewText = pText then return pText = theNewText pMbr.text = pText end on mFpsMeterRemove me (the actorList).deleteOne(me) end -------- frame rate scriptP00,>Fn>richard rossCASt !%2node IDsM>N1?>richard rossCASt "sound on>Oq> $richard rossP!  Fmap<J*:JJArialCourier Courier New HelveticaVERS, f f BITD5#c`_c`_c`_|\W[twr]W[twr]W[twr]1"bmvpaquiWbmvo\nuiWbmvmRguiWwj WYsva,$@nvpcW WYsva-%;ivpcW WYsv`0(2]vpcW,\nuuO&.A+0^sumq\nuuN'.A+/Xsumq\nuuN(.A-+Lrumq JDnvp;(Akuh?&DquZDnvo<(Akuh@(@nuZDnvn<)Bluh@)9iuZFdqt8-[uwtwu\*PtYdpt9-[uwtwu\,LtYdmt:-\uwtwu\0CtY ;CjsQkwtS:[vwmbqBChsRkwtS:[vwmbqBCesRkwtS:[vwmapB 1Hjtuxg<%%'CkxupDHhtuxg<%%'CkxupDHdtuxg<%%'CkxupD%IivuU,%)%.VsrXIevuU,%)%.VsrXI^vuU,%)%.VsrX^nuL%()'%[uE^nuL%()'%[uE^nuL%()'%[uE2cs0')&XuD2cs0')&XuD2cs0')&XuDOjt5')*)*)'YvCOjt5')*)*)'YvCOjt5')*)*)'YvC jt6')((]rQjt6')((]rQjt6')((]rQ lr5')((^qNlr5')((^qNlr5')((^qNes5')()`kKes5')()`kKes5')()`kKns6')(*ekMns6')(*ekMns6')(*ekM`u8&)(*gd`u8&)(*gd`u8&)(*gdhs8&)(+jfhs8&)(+jfhs8&)(+jfTw4"%$(miTw4"%$(miTw4"%$(mi^zRFHGJtl^zRFHGJtl^zRFHGJtl`mS[\]\]]\\JS[\]\]]\\JS[\]\]]\\JajoSajoSajoS̾{nd[J?1%   '1>GT_hr|ɸ>dkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUdkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUdkqibp`eghpTTf>ePG^JjWDeYFgPCcV;c^Femddi\ipairhUq_ k+ dirutqjetvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_ dirutqidtvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_ dirutphctvtuwuvwutuouomqeqdU7 chsrpvuuwxwywvwxuwusvuuvso_0z gottnJ++PsswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusnJ;RquuqWKgottnK++PsswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusnI9PquuqWKgottnK+,QsswmJ;>BFHLORUVZ\^cdud5vs[XWUSRQOMKIGFCDbvusmI8MouuqWK xAGgsuoT1(1bstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtj?&5bsuuk_GgsuoU2)1bstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtj?'4_suuk_GgsuoT3)2bstx_1$&&%%$%&&'()+hatn-$&%$%(Epvtk?(3Zsuuk_hdEbvtj7)(1ftux\)&)('+m^tq4')**))(#:lxttL('CmuuskEbvtj8))1ftux\)&)('+m^tq4')**))(#:lxttL('BkuuskEbvtj8))2ftux\)&)('+m^tq4')**))(#:lxttM)(@iuuskWR(WlvqO,)(@otvsJ(()(/sWtr9&)&0[wutY1(+WrutgKWkvqO-)(@otvsJ(()(/sWtr9&)&0[wutZ1(+TrutgKWgvqO.))@ntvsJ(()(/sWtr9&)&0[wutZ1(,PqutgK"zCw Gguva1))3`ttug8%()'2tTwt@%)''GltulG,&6btwo[YGguva1))3_ttug8%()'2tTwt@%)''GltulG,'6`two[YGguva2))3_ttug8%()'2tTwt@%)''GltulG,(6[two[Y6[<Yrusi7))4susv`)')&:tCZvF$)*)(!CustwS)($MstxcYrusi7))5susv`)')&:tCZvF$)*)(!CustwT)(%JstxcYrusj7))6rusv`)')&:tCZvF$)*)(!CustwT))(Estxc<H(&Jputp?)(8mtsw`+')%@uE*uM$)&3justl6)),bttqDJputp?)(7ktsw`+')%@uE*uM$)&3justl6))-attqDJputq?))6gtsw`+')%@uE*uM$)&3justl6))/]ttqDF:+KrutsE)&:stsx\)')%FtItT%)'.fwssl8))0ittrdKrutsE)'8qtsx\)')%FtItT%)'.fwssk8))1ittrdKrutsF))6mtsx\)')%FtItT%)'.fwssl8))1gttrdN <_stK)%Bsx[)'('&!Lu$+qX!%%&&'())(()'+bxssr8)(3mttse_st K)&@qssx[)'('&!Lu$+qX!%%&&'())(()'+bxssr9))5lttse_st L)):nssx[)'('&!Lu$+qX!%%&&'())(()'+bxssr9))6jttseWH LsusuV/%EqssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ysC)(9pttrW LsusuV/&CqssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ysD)(:ottrW LsusuW0(?pssxY+)+,,-./134458:8[t6$giGDA>;8530-,+*((&)\ysD)):mttrWb ]Jutsui\\nsujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsst_:7@pttuVJutsui\\nsujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsst`:8@pttuVJutsui\\nsujfijlnnprrsuutvxvkM Zwwvuuttwspqljgb`\bvsst`99AnttuVixX(/@M[irm_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuV_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuV_tuutuwvsvxtvwutqosnhnn`ir_UnX8lYTbLalPfoapkmtqsutvvtwwtuuVȿm\G8*  '8Jf|_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX_ogmoekqbVo_GWmP0a]B[NQk:IkKSo^dqghqlX  IN5XfAJjA5IN5XfAJjA5IN5XfAJjA5"~~}~~#@egfG@egfG@egfGZ[gtsosuPgtsosuPgtsosuPrvPzR+/-[xcPzR+/-[xcPzR+/-[xc_yH$(%T}O_yH$(%T}O_yH$(%T}OquC%)%P{_quC%)%P{_quC%)%P{_bw>&)%Lxmdbw>&)%Lxmdbw>&)%Lxmd Olt8&)%GwnDOlt8&)%GwnDOlt8&)%GwnD,rr2')%Cvn(,rr2')%Cvn(,rr2')%Cvn(+M=so,()&=trY=so,()&=trY=so,()&=trYIyaui+()&8rwbaui+()&8rwbaui+()&8rwbbJyc)()'5p{RJyc)()'5p{RJyc)()'5p{RPz\(()'1nwaPz\(()'1nwaPz\(()'1nwaiyV&)(.kuofiyV&)(.kuofiyV&)(.kuof Z|Q%)(,gvo0Z|Q%)(,gvo0Z|Q%)(,gvo0!AfyL%)(*awq1AfyL%)(*awq1AfyL%)(*awq19apvG%)()^wrUapvG%)()^wrUapvG%)()^wrUQHsuA%)'YwskHsuA%)'YwskHsuA%)'Ywsk9j2qtvLUyo6_usvg_vs?1ptvLUyo9\usvg_vs?/otvLVyp1&XusvvsE)/otu_Vyp1'XusvvsF).ntu_Vyp2*VusvvsF).ntu_hvq/))YtstI)(7qsughvq/)*YtstJ)(7qsughvq/),XtstJ))6qsug `ntu=))(Qus uG)(-mtsv^ `ntu=)Pus uG)(.ktsv^ `ntu>))*Pus uG))/htsv^  .lutn5))(MtssuK))%atssuh3.lutn5))(MtssuK))&^tssuh3.lutn5)NtssuK))*Xtssuh3)Eqtsu`-))'PvvM))$Qusv^Eqtsua-))(OvvM))&Nusv^Eqtsua-)NvvM))(Iusv^WoussuW)(IJ))&?rsvn_WoussuX)(IJ))'>rsvn_WoussuY)JJ))(;rsvn_`ntssvD)&9rtsswbR`ntssvE)'6ptsswbR`ntssvE)3ktsswbRaots9)(+ktssvk<aots9)(,gtssvk<aots:),`tssvk<D+dststd,)$Yvssun=dststd,)&Tvssun=dststd-)Hvssun=fXgtssuT))%MqtstsSgtssuU))&HptstsSgtssuV)=ntstsS}y ivssvA$WAquttXAquttXAquttXTxEvwkEvwkEvwkbFXKFXKFXKThum7)VVVVVVVVVV+V+VVV++VVVV + VV+++VVV+V V V V  ++V+++XMEDFFFF000000060004000177AA00000000005D000000004000110000001-7FFD6FDF0480048-10100-10707010367FF00010800001000000310000000108840101010367038E0001041000020000000C000000008,The Moon0004000000090000000205A5000500000008000000020A00006000001420000000650C310FFFF0C00000 10 10B30FFFF0C00000 20 10B30EE000FFFF0C00000 30 10B30FF000FFFF0C00000 40 10D30FF000FFFF0E00000 101010D30FFFF0E00000 10 00070000002300000001020174518001800008000001690000000240,Geneva40,1040304E44000104004000801040,Arial40,10407D104E44000104004000801000090000001500000002010367010367000A0000001500000002010367010367000B00000005000000020000C00000013000000018782902B1000F0000002100000000400 10  00130000007E00000000DA91F8CE1C1D1E1F7F1B044,-..'"FFFF0FFFF001280000000A00000001A001290000000A00000001A0Thum57) XMED.FFFF000000060004000177AA00000000004D000000004000110000001-7FFD6FE00480048-10E0-10 E470107000010000003000000001078401010E47038E00011E36000020000000B000000007,7.5 fps00040000000900000002029200050000000900000002019000060000009D0000000320C310FFFF0C00000 10 10B30FFFF0C00000 20 10B30FF000FFFF0C00000 10 00070000004600000002010174518001801010174518001800008000001690000000240,Geneva40,1040304E44000104004000801040,Arial40,10407D104E440001040040008010000900000011000000020E470E47000A00000011000000020E470E47000B00000005000000020000C000000140000000170D16002F1000F0000002100000000400 10  00130000007E00000000DA91F8CE1C1D1E1F7F1B044,-..'"FFFF0FFFF001280000000A000000019001290000000A0000000190Thum7) BITDS 7?]ccfecc^]ccfecc^]ccfecc^?{Omefdefeddfmefdefeddfmefdefeddfcsmde]NF>6FFTefdmdelw}}}refdmdeW@3&33JefdKc UffN-*9ad]Uffxid]UffA ]d]7S fe[52[eğo[22DeeU fepײ۹eeU feT?KooooW?/eeUsffe>9e\_|ȍw99Tfcffeeh忢}fcffe!LY]y˿aFfc'GbfZAA yDZ|AAGeebfz yPfޕ|ڨeebfP!! yAV|!!-ee?_eeWII NKcIffee ]Z״effeeH** IF}c*ff?_ee[QQkMyXQffee}_iffeeL33fHtR3ff?_ee_XX H,5Xffee ]@ͣJffeeQ<cj+@FLv`ffee cW{CY^dffeeVFF_ Ce7\c$9?E_Fff?_eegh 7^;(7TL9ahffee RyVDSphU|ffeeZO /V3 0LE2YOff?_eekp @Z!!Ce,8Xpffee [u<<^GSsffee_X 9S<^$1QXff?_eenw 3{B#%*F|HjXwffee M]>@E`csffeeca ,t;$?uBcRaff?_eer sgW0'(X7ffee qJABrQffeehj l`P*!"R1jff?_eevS(*y;`ffeelACR`ffeelsM"$ss5`sff7Wffu Bv1~v`edff FIyedffn} Aq+xq}[}zed7^ei ~Ukv~ef^en m棎ef^eh yPfquefgmfe{Dniddmfe[oddmfezv?ihdd'Cbdf[<recbdfq<ցecbdfV<oec?S Uede|jfe]Uedeofe]Uedexife]+ϓ?UedemUedemUedemGwS#^eedefU^eedefU^eedefUThum/$$+++++VVVVV+V||V+V+ V|uuQuQuQuQ+VuQuQu|+#u+%+%+%%{+%+&u{V#VPP&P,O,J&J,JP|++||P,JPV+VPWPv|+#{vQPPQPQPP{{VPP,PQPQPP|+||vPuQQuPVWVVQVQ PuQv|v{v{vuQuQ{VWPuQuvuv+#+{vuuvuvuV|{Puvuvuv{vu{uuvuvPЂ{VPuuvuvuv+{QuQuQЦ{PQuuQuQu+#{QuuQuQu{PVPQuQuQuQuQ+{QoPQKtQQuJ{QQoPQnQQ+#V{PKQJuQJQJ{{PPVQJQnQQJu+#VQJPKPJQJJQ{KV{VPKPJPKV#VKJPJQJJPJJ{V{JPJPKJPPPJJ&PJ,JJP&VVJJPVV{P&JJ&JJ&J&JJ&JJ&J&J&PPV+++mmap/ [RIFXc4imap D mmapKp> KEY* free CASt]CAStCAStfree CAStB^free free CAStd#xCASt \CAStCAStACAStCAStfGCASt6ZCASt3Bfree CAStCAStCASt7!CAStCAStCAStCAStjCAStz4CAStCASt|CASt<BCASt%CAStd&PCASt(CAStIDdCAStWCAStZ@CAStR\CASt1p`$CASt mCAStCAStfree CAStCASt <CASt7bCAStgXCAStCASt&CASt>CAStdCASt"CAStsCASt /Pfree +free 7free 8free 9free :free ;free free ?free @free Afree Bfree Cfree Dfree Efree FCAStTCASt`CAStfree Gfree Kfree Lfree Mfree Nfree Ofree Pfree Qfree Rfree Sfree Tfree Ufree Vfree Wfree Xfree Yfree Zjunk9]junkSl^junk.v_junk`junkajunk,junkBcjunkhdjunk /0ejunksfjunkgjunkDhjunkijunkjjunk|kjunkljunkgtmjunk7~njunk Xojunkpjunkqjunk.rjunk msjunk1pk@tjunkRgujunke\vjunkbwjunkIOxjunk3yjunkd1lzjunk0{junk<"^|junk!}junk ~junkz Pjunk junk junk junk junk7!junkjunkjunkRjunk3Bjunk6e,junkfGjunkjunkAjunkjunk xjunkd.junk%junk%*junk]"junkB zCAS*Zjunk~junkTjunkThum?Thum59vThum0junk\junk,CASt6DRCFTxfree junkLctX4FmapjunkbCinf~VERS,Lnam!LscrLscrxLscrLscr4 Lscr\$LscrR&tLscr5Lscr^;rLscrSLscrcLscr\rfLscrLscr(LscrLscr LscrLscr >LscrLscrhLscr>LscrLscrIJLscrHLscrLscrNpLscrfree free STXTfree free free free free free free free free free BITDfree BITD3ThumRSTXTUfree free BITD3V0ThumelBITD-gVThumvSTXTYxrfree BITD xThumfree BITD ]PThum\BITD Thum|free BITDALFAhThumXMED3free free free XMEDPThumXMEDThumfree free free BITDThumfree Thumfree free XMED `Thum}Tfree free snd sndHdsndS" Nfree BITDvThumC BITDS@Thum/H8free free Thumd free XMED.:free free  STXT free