/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct InstLoaderProj = [ LOADPROJ_iId : I, LOADPROJ_project : Project ]mkInstLoaderProj;; struct InstLoader = [ PLOAD_inst : PInstance, PLOAD_parent : SO3_OBJECT, PLOAD_node : SO3_OBJECT, PLOAD_bUseEnv : I, PLOAD_fMaxSize : F, PLOAD_iIndex : I, PLOAD_lProjects : [InstLoaderProj r1], PLOAD_httpReq : ObjCURL ]mkInstLoader;; var sTmpDownloadPath = "tmp/download/";; fun deleteOb(inst, loadstr)= if (loadstr.PLOAD_httpReq == nil) then nil else ( killHttpRequest loadstr.PLOAD_httpReq; set loadstr.PLOAD_httpReq = nil; ); let (V3DgetSessionView c3dXsession) -> viewstr in let if ((sizelist loadstr.PLOAD_lProjects) > 0) then 1 else 0 -> env in ( while (loadstr.PLOAD_lProjects != nil) do ( let hd loadstr.PLOAD_lProjects -> instprojstr in deleteProject instprojstr.LOADPROJ_project viewstr; ); if (!env) then nil else loadEnvironmentPlayer inst.INST_groupstr.GRP_project (V3DgetSessionView c3dXsession) inst.INST_groupstr.GRP_xmlMark; ); set loadstr.PLOAD_iIndex = 0; SO3ObjectDestroy loadstr.PLOAD_node; SO3GroupDelete (V3DgetSession c3dXsession) (getPluginInstanceName inst); 0;; fun unLoad(loadstr)= if (loadstr.PLOAD_httpReq == nil) then nil else ( killHttpRequest loadstr.PLOAD_httpReq; set loadstr.PLOAD_httpReq = nil; ); let (V3DgetSessionView c3dXsession) -> viewstr in let if ((sizelist loadstr.PLOAD_lProjects) > 0) then 1 else 0 -> env in ( while (loadstr.PLOAD_lProjects != nil) do ( let hd loadstr.PLOAD_lProjects -> instprojstr in deleteProject instprojstr.LOADPROJ_project viewstr; ); if (!env) then nil else loadEnvironmentPlayer loadstr.PLOAD_inst.INST_groupstr.GRP_project (V3DgetSessionView c3dXsession) loadstr.PLOAD_inst.INST_groupstr.GRP_xmlMark; ); set loadstr.PLOAD_iIndex = 0; SO3ObjectDestroy loadstr.PLOAD_node; SO3GroupDelete (V3DgetSession c3dXsession) (getPluginInstanceName loadstr.PLOAD_inst); SO3GroupCreate (V3DgetSession c3dXsession) (getPluginInstanceName loadstr.PLOAD_inst); let V3DaddShell c3dXsession (getPluginInstanceName loadstr.PLOAD_inst) "0" loadstr.PLOAD_parent [0.0 0.0 0.0] [0.0 0.0 0.0 1.0] -> node in set loadstr.PLOAD_node = node; 0;; fun applySceneFlags(l, sons)= if l == nil then nil else let hd l -> obj in ( if (!sons) then nil else applySceneFlags (SO3ObjectGetChildren obj) sons; SO3ObjectSetFlags obj iNodeFlagScene; applySceneFlags (tl l) sons; ); 0;; fun cbSceneLoaded(projstr, loadstr, instprojstr)= //applySceneFlags (SO3ObjectGetChildren loadstr.PLOAD_node) 1; if (loadstr.PLOAD_fMaxSize == 0.0) then nil else let SO3ObjectGetBoundingBoxInfo loadstr.PLOAD_node 1 -> [[sx sy sz] _ _] in let maxf maxf sx sy sz -> maxsize in if ((maxsize <=. loadstr.PLOAD_fMaxSize) || (maxsize == 0.0)) then nil else ( let loadstr.PLOAD_fMaxSize /. maxsize -> scale in SO3ObjectSetGlobalScale loadstr.PLOAD_node [scale scale scale]; ); SendPluginEvent loadstr.PLOAD_inst "Loaded" nil nil; 0;; fun cbSceneDestroyed(projstr, loadstr, instprojstr)= SendPluginEvent loadstr.PLOAD_inst "Unloaded" nil nil; set loadstr.PLOAD_lProjects = remove_from_list loadstr.PLOAD_lProjects instprojstr; 0;; fun loadOS3DScene(loadstr, path)= let (V3DgetSessionView c3dXsession) -> viewstr in let crProject path (strcatn (itoa loadstr.PLOAD_iIndex)::"."::(getPluginInstanceName loadstr.PLOAD_inst)::nil) 2 loadstr.PLOAD_inst.INST_sName -> projstr in let mkInstLoaderProj [loadstr.PLOAD_iIndex projstr] -> instprojstr in ( set loadstr.PLOAD_lProjects = instprojstr::loadstr.PLOAD_lProjects; set loadstr.PLOAD_iIndex = loadstr.PLOAD_iIndex + 1; setProjectCbSceneLoaded instprojstr.LOADPROJ_project mkfun2 mkfun3 @cbSceneLoaded instprojstr loadstr; setProjectCbSceneDestroyed instprojstr.LOADPROJ_project mkfun2 mkfun3 @cbSceneDestroyed instprojstr loadstr; loadProject instprojstr.LOADPROJ_project viewstr loadstr.PLOAD_node [0.0 0.0 0.0] [0.0 0.0 0.0 1.0] [1.0 1.0 1.0] loadstr.PLOAD_bUseEnv; ); 0;; fun cbStartLoading(trm, p)= _deltimer trm; let p -> [loadstr pfile] in let c3dXsession -> sessionstr in ( let getFileExt _GetFileNameFromP pfile -> ext in if (!strcmpi ext "XOS") then ( loadOS3DScene loadstr (_PtoScol pfile); ) else if (!strcmpi ext "PKOS") then ( //editor mode if (iPluginMode == 1) then nil else _cacheActivate; let mkUnpakOS3DProject pfile nil (iPluginMode == 1) -> nfile in if (nfile == nil) then ( SendPluginEvent loadstr.PLOAD_inst "Error" nil nil; 0; ) else ( loadOS3DScene loadstr nfile; 0; ); ) else if ((SO3SceneLoadFile sessionstr.V3D_session (getPluginInstanceName loadstr.PLOAD_inst) pfile loadstr.PLOAD_node SO3CONVERTER_SPLIT_LARGE_MESHES|SO3CONVERTER_GEN_SMOOTH_NORMALS|SO3CONVERTER_OPTIMIZE_SCENEGRAPH) != nil) then ( applySceneFlags (SO3ObjectGetChildren loadstr.PLOAD_node) 1; if (loadstr.PLOAD_fMaxSize == 0.0) then nil else let SO3ObjectGetBoundingBoxInfo loadstr.PLOAD_node 1 -> [[sx sy sz] _ _] in let maxf maxf sx sy sz -> maxsize in if ((maxsize <=. loadstr.PLOAD_fMaxSize) || (maxsize == 0.0)) then nil else ( let loadstr.PLOAD_fMaxSize /. maxsize -> scale in SO3ObjectSetScale loadstr.PLOAD_node [scale scale scale]; ); SendPluginEvent loadstr.PLOAD_inst "Loaded" nil nil; ) else SendPluginEvent loadstr.PLOAD_inst "Error" nil nil; ); 0;; fun cbDlgLoadFile(dlg, loadstr, pfile)= if pfile == nil then nil else ( SendPluginEvent loadstr.PLOAD_inst "Loading" nil nil; _rfltimer _starttimer _channel 200 @cbStartLoading [loadstr pfile]; ); 0;; fun cbDownloaded(file, wfile, loadstr)= let _WtoP wfile -> tmpfile in let _fileSize tmpfile -> size in if (size == 0) then ( SendPluginEvent loadstr.PLOAD_inst "Error" nil nil; 0; ) else ( cbDlgLoadFile nil loadstr tmpfile; 0; ); 0;; fun cbFileInfos(url, tag, length, loadstr)= if (loadstr.PLOAD_httpReq == nil) then nil else ( killHttpRequest loadstr.PLOAD_httpReq; set loadstr.PLOAD_httpReq = nil; ); //bad response if ((tag == nil) && (length == nil)) then ( SendPluginEvent loadstr.PLOAD_inst "Error" nil nil; 0; ) else ( let getPathFile url "" -> [dir file] in let strcat sTmpDownloadPath file -> tmpfile in let strcat tmpfile ".tag" -> tagfile in let strcatn tag::" "::(itoa length)::nil -> tagcont in if (((_checkpack tmpfile) != nil) && (!strcmp (_getpack _checkpack tagfile) tagcont)) then ( cbDlgLoadFile nil loadstr _checkpack tmpfile; 0; ) else ( _storepack tagcont tagfile; let _getmodifypack tmpfile -> wfile in let _createpack "" wfile -> _ in //force empty set loadstr.PLOAD_httpReq = downloadFileW url wfile mkfun3 @cbDownloaded loadstr; 0; ); ); 0;; fun cbOs3dFileInfos(url, data, loadstr)= if (data != nil) then ( let readCSVdata data "," -> lcont in let hd lcont -> [name [dlurl [size [md5 _]]]] in let strcat sTmpDownloadPath name -> tmpfile in if (((_checkpack tmpfile) != nil) && (!strcmp (_filemd5 _checkpack tmpfile) md5)) then ( cbDlgLoadFile nil loadstr _checkpack tmpfile; 0; ) else ( let _getmodifypack tmpfile -> wfile in let _createpack "" wfile -> _ in //force empty set loadstr.PLOAD_httpReq = downloadFileW dlurl wfile mkfun3 @cbDownloaded loadstr; 0; ); 0; ) else ( SendPluginEvent loadstr.PLOAD_inst "Error" nil nil; 0; ); 0;; fun downloadScene(loadstr, url)= //editor mode if (iPluginMode == 1) then nil else _cacheActivate; if (loadstr.PLOAD_httpReq == nil) then nil else ( killHttpRequest loadstr.PLOAD_httpReq; set loadstr.PLOAD_httpReq = nil; ); let if (strfind "os3dpak.php?dl=" url 0) != nil then 1 else 0 -> os3dpakUrl in if (os3dpakUrl) then ( let strfind "?dl=" url 0 -> fpos in let substr url 0 fpos -> burl in let substr url (fpos + 4) (strlen url) - (fpos + 4) -> fname in let strcatn burl::"?fileinfos="::fname::nil -> iurl in set loadstr.PLOAD_httpReq = getUrl iurl nil mkfun3 @cbOs3dFileInfos loadstr; ) else ( set loadstr.PLOAD_httpReq = getUrlContentInfos url mkfun4 @cbFileInfos loadstr; ); SendPluginEvent loadstr.PLOAD_inst "Downloading" nil nil; 0;; fun cbLoad(inst, from, action, param, reply, loadstr)= unLoad loadstr; if (strIsUrl param) then ( downloadScene loadstr param; ) else ( let _checkpack param -> pfile in if (pfile != nil) then ( SendPluginEvent loadstr.PLOAD_inst "Loading" nil nil; _rfltimer _starttimer _channel 200 @cbStartLoading [loadstr pfile]; 0; ) else ( _DLGrflopen _DLGOpenFile _channel DMSwin "/" "" "3D formats\0*.3ds;*.dae;*.blend;*.obj;*.fbx;*.stl;*.dxf;*.ifc;*.xos;*.pkos;\0'3D Studio'\0*.3ds\0Collada\0*.dae\0Blender\0*.blend\0Obj\0*.obj\0IFC\0*.ifc\0OpenSpace3D\0*.xos;*.pkos;\0All\0*.*\0\0" @cbDlgLoadFile loadstr; 0; ); ); 0;; fun cbUnload(inst, from, action, param, reply, loadstr)= unLoad loadstr; 0;; fun loadFiles(inst, lp, loadstr)= if lp == nil then nil else ( cbDlgLoadFile nil loadstr hd lp; loadFiles inst tl lp loadstr; ); 0;; fun dropFiles(inst, viewstr, x, y, lp, loadstr)= if (lp == nil) then nil else ( unLoad loadstr; loadFiles inst lp loadstr; ); 0;; fun newOb(inst)= SO3GroupCreate (V3DgetSession c3dXsession) (getPluginInstanceName inst); let (getPluginInstanceParam inst "object") -> objname in let atof (getPluginInstanceParam inst "maxsize") -> msize in let if msize == nil then 0.0 else msize -> msize in let atoi (getPluginInstanceParam inst "env") -> env in let if env == nil then 1 else env -> env in let atoi (getPluginInstanceParam inst "dragndrop") -> dragndrop in let if dragndrop == nil then 0 else dragndrop -> dragndrop in let V3DgetObjectByName c3dXsession objname -> parent in let mkInstLoader [inst parent nil env msize 0 nil nil] -> loadstr in ( PluginRegisterAction inst "Load" mkfun6 @cbLoad loadstr; PluginRegisterAction inst "Unload" mkfun6 @cbUnload loadstr; if (!dragndrop) then nil else setPluginInstanceCbDropFile inst mkfun6 @dropFiles loadstr; setPluginInstanceCbDel inst mkfun2 @deleteOb loadstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;