void U2MaxCameraExport::ExtractFromViewport(Interface* pIf) { ViewExp* viewport = pIf->GetActiveViewport(); if(viewport) { Matrix3 modelView, invModelView; viewport->GetAffineTM(modelView); invModelView = Inverse(modelView); Point3 up = invModelView.GetRow(0); // up Point3 right = invModelView.GetRow(1); // right Point3 look = invModelView.GetRow(2); Point3 eye = invModelView.GetRow(3); float fFov = viewport->GetFOV(); BOOL bIsPerp = viewport->IsPerspView(); pIf->ReleaseViewport(viewport); if(bIsPerp) { ; } else { ; } } }
/** * This method will be called from the max system when the user * has choosen to export to the OpenSceneGraph format. * This method is the entry point to the exporter plugin. */ int OSGExp::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD MAXOptions){ // Only support "one at the time" exporting. if(isExporting){ return FALSE; } isExporting = TRUE; // Grab the interface pointer and save it for later use. _ip = i; // Set export path in options class TCHAR p[300]; TCHAR f[100]; TCHAR e[10]; BMMSplitFilename(name, p, f, e); _options->setExportPath(p); _options->setExportFilename(f); _options->setExportExtension(e); // Get filename to config file. TSTR cfgfilename = _ip->GetDir(APP_PLUGCFG_DIR);; cfgfilename += _T("\\OSGEXP.CFG"); // Load options from config file _options->load(cfgfilename); // Should we only export selected nodes? _onlyExportSelected = (MAXOptions & SCENE_EXPORT_SELECTED) ? TRUE : FALSE; // Show option dialog to user and retrive any possible plugin choices. if(!suppressPrompts) if(!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EXPORTBOX), GetActiveWindow(), OptionsDlgProc, (LPARAM)_options)){ // If user closed or canceled export box then shutdown plugin. isExporting = FALSE; return TRUE; } // Write options to config file. _options->write(cfgfilename); // Create OSG root transform to hold the scene. { osg::ref_ptr<osg::MatrixTransform> rootTransform = new osg::MatrixTransform(); //osg::MatrixTransform* rootTransform = new osg::MatrixTransform(); rootTransform->setName(std::string(_ip->GetRootNode()->GetName())); // Set static datavariance for better performance rootTransform->setDataVariance(osg::Object::STATIC); // Set NodeMask if(_options->getUseDefaultNodeMaskValue()) rootTransform->setNodeMask(_options->getDefaultNodeMaskValue()); osg::Matrix rootMat = getNodeTransform(_ip->GetRootNode(), _ip->GetTime()); rootTransform->setMatrix(rootMat); // Create root stateset for the lights. osg::ref_ptr<osg::StateSet> rootStateSet = new osg::StateSet(); // Turn of lighting if set by the user. if(_options->getTurnOffLighting()) rootStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF); else rootStateSet->setMode(GL_LIGHTING,osg::StateAttribute::ON); //osg::StateSet* rootStateSet = new osg::StateSet(); rootTransform->setStateSet(rootStateSet.get()); // We will make two progress bars. The first one will show // the exporting of materials, wheras the second one will show // the exporting of nodes. To get the total number of nodes in the // scene graph we will accumulate the total node count while // preprocessing the scenegraph for materials. _nTotalNodeCount = 0; _nCurNode = 0; _nTotalMtlCount = _ip->GetSceneMtls()->Count(); _nCurMtl = 0; // Starting up the material exporting progress bar. _ip->ProgressStart(_T("Exporting materials..."), TRUE, fn, NULL); // Export materials by preprocessing the scenegraph. if(!preProcess(_ip->GetRootNode(), _ip->GetTime())){ // If user cancels we stop progress bar and return. _ip->ProgressEnd(); isExporting = FALSE; return TRUE; } // We're done exporting materials. Finish the progress bar. _ip->ProgressEnd(); // Starting up the node exporting progress bar. _ip->ProgressStart(_T("Exporting scene..."), TRUE, fn, NULL); // Get number of children for the root node in the interface. int numChildren = _ip->GetRootNode()->NumberOfChildren(); // Call our node enumerator. // The nodeEnum function will recurse into itself and // export each object found in the scene. for (int idx=0; idx<numChildren; idx++) { if (_ip->GetCancel() || !nodeEnum(rootTransform.get(), _ip->GetRootNode()->GetChildNode(idx), rootTransform.get())){ // If user cancels we stop progress bar and return _ip->ProgressEnd(); isExporting = FALSE; return TRUE; } } // Finish exporting progress bar _ip->ProgressEnd(); // If optimize scene graph unsigned int optimizeMask = 0; if(_options->getTriStripGeometry()) optimizeMask |= osgUtil::Optimizer::TRISTRIP_GEOMETRY; if(_options->getMergeGeometry()) optimizeMask |= osgUtil::Optimizer::MERGE_GEOMETRY; if(_options->getFlattenStaticTransform()) optimizeMask |= osgUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS; if(_options->getShareDuplicateStates()) optimizeMask |= osgUtil::Optimizer::SHARE_DUPLICATE_STATE; if(_options->getSpatializeGroups()) optimizeMask |= osgUtil::Optimizer::SPATIALIZE_GROUPS; if(optimizeMask){ _ip->ProgressStart(_T("Optimizing scenegraph..."), FALSE, fn, NULL); _ip->ProgressUpdate(0.5f); osgUtil::Optimizer optimizer; optimizer.optimize(rootTransform.get(), optimizeMask); _ip->ProgressEnd(); } // Save file to disk. if(_options->getSaveFile()){ _ip->ProgressStart(_T("Writing file..."), FALSE, fn, NULL); _ip->ProgressUpdate(0.5f); if(_options->getExportExtension().compare(".osg")==0 || _options->getExportExtension().compare(".OSG")==0 || _options->getExportExtension().compare(".ive")==0 || _options->getExportExtension().compare(".IVE")==0 ){ std::string filename(name); // Exclude image data from ive file if this options has been choosen if(!_options->getIncludeImageDataInIveFile()){ osgDB::ReaderWriter::Options* opt = new osgDB::ReaderWriter::Options("noTexturesInIVEFile"); osgDB::Registry::instance()->setOptions(opt); } #if defined(OPENSCENEGRAPH_MAJOR_VERSION) && OPENSCENEGRAPH_MAJOR_VERSION >= 2 && defined(OPENSCENEGRAPH_MINOR_VERSION) && OPENSCENEGRAPH_MINOR_VERSION >= 4 osgDB::ReaderWriter::WriteResult res = osgDB::Registry::instance()->writeNode(*rootTransform, filename, NULL); #else osgDB::ReaderWriter::WriteResult res = osgDB::Registry::instance()->writeNode(*rootTransform, filename); #endif if(res.error() && _options->getShowErrMsg()){ static TCHAR szBuffer[256]; wsprintf(szBuffer,TEXT("Error writing file %s:\n%s"), TEXT(filename.c_str()),res.message()); MessageBox (GetActiveWindow(), szBuffer, TEXT("Warning"), MB_OK | MB_ICONWARNING) ; } if(!_options->getIncludeImageDataInIveFile()){ // Turn readerwriter options off again. osgDB::ReaderWriter::Options* opt = new osgDB::ReaderWriter::Options(); osgDB::Registry::instance()->setOptions(opt); } } else{ if(_options->getShowErrMsg()){ std::string error("Can not find plugin to save file: "); error.append(name); MessageBox (GetActiveWindow(), error.c_str() , TEXT("Warning"), MB_OK | MB_ICONWARNING) ; } } _ip->ProgressEnd(); } // Show quick preview if(_options->getQuickView()){ float fNear = 1.0f; float fFar = 1000.0f; // Get the active viewport and the win32 window within it. // The position and size will be retreive from this. ViewExp* viewExp = _ip->GetActiveViewport(); float fov = viewExp->GetFOV(); HWND hWnd = viewExp->getGW()->getHWnd(); RECT sRect; BOOL ok = GetWindowRect(hWnd, &sRect); int width = 100; int height = 100; int x =100; int y =100; if(ok){ x = sRect.left; y = sRect.top; width = sRect.right - sRect.left; height = sRect.bottom - sRect.top; } // Create previewer window and set size. Previewer previewer; previewer.setWindowSize(x, y, width, height); // The affine TM transforms from world coords to view coords // so we need the inverse of this matrix Matrix3 aTM, camTM, coordSysTM; Point3 viewDir, viewPos, lookAtPos, upVector; INode* camera; float dist = 100; Point3 upperLeft = viewExp->MapScreenToView(IPoint2(0, 0), fFar); Point3 lowerRight = viewExp->MapScreenToView(IPoint2(width, height), fFar); viewExp->GetAffineTM(aTM); coordSysTM = Inverse(aTM); viewDir = coordSysTM.VectorTransform(Point3(0.0f, 0.0f, -1.0f)); viewPos = coordSysTM.GetRow(3); lookAtPos = viewPos + viewDir; upVector.Set(0.0f, 0.0f, 1.0f); switch(viewExp->GetViewType()){ case VIEW_ISO_USER: case VIEW_PERSP_USER: previewer.setProjectionMatrixAsFrustum(lowerRight.x, upperLeft.x, upperLeft.y, lowerRight.y, fFar, -fFar); break; case VIEW_CAMERA: previewer.setProjectionMatrixAsFrustum(upperLeft.x, lowerRight.x, lowerRight.y, upperLeft.y, fFar, -fFar); camera = viewExp->GetViewCamera(); camTM = camera->GetObjTMBeforeWSM(_ip->GetTime()); viewDir = camTM.VectorTransform(Point3(0.0f, 0.0f, -1.0f)); viewPos = camTM.GetRow(3); lookAtPos = viewPos + viewDir; break; case VIEW_LEFT: case VIEW_RIGHT: case VIEW_TOP: case VIEW_BOTTOM: case VIEW_FRONT: case VIEW_BACK: previewer.setProjectionMatrixAsOrtho(upperLeft.x, lowerRight.x, lowerRight.y, upperLeft.y, -fFar, fFar); //cam->setOrtho(upperLeft.x, lowerRight.x, lowerRight.y, upperLeft.y, -fFar, fFar); // Go far away from the viewing point in the negative viewing direction. viewPos = coordSysTM.PointTransform(Point3(0.0f, 0.0f, fFar)); lookAtPos = viewPos + viewDir; // In top view the up vector on the camera is the positive y-axis. if(viewExp->GetViewType() == VIEW_TOP) upVector.Set(0.0f, 1.0f, 0.0f); // In bottom view the up vector on the camera is the negative y-axis. if(viewExp->GetViewType() == VIEW_BOTTOM) upVector.Set(0.0f, -1.0f, 0.0f); break; } // When we are done with the viewport we should release it. _ip->ReleaseViewport(viewExp); // Set scene data. previewer.setSceneData(rootTransform.get()); // set the view - OpenGL look at previewer.setViewMatrixAsLookAt(osg::Vec3( viewPos.x, viewPos.y, viewPos.z), osg::Vec3(lookAtPos.x, lookAtPos.y, lookAtPos.z), osg::Vec3(upVector.x, upVector.y, upVector.z) ); previewer.run(); isExporting = FALSE; return TRUE; } } isExporting = FALSE; return TRUE; }