| 1245 | | std::string foundFile = findFileAndRecordPath(filename); |
| 1246 | | if (foundFile.empty()) return; |
| 1247 | | |
| 1248 | | subgraph = osgDB::readNodeFile(foundFile); |
| 1249 | | } |
| 1250 | | |
| 1251 | | if (!subgraph) return; |
| 1252 | | |
| 1253 | | addModel(subgraph, positionData, modelData); |
| | 1252 | subgraph = osgDB::readNodeFile(filename, _options.get()); |
| | 1253 | if (subgraph) recordOptionsFilePath(_options.get()); |
| | 1254 | } |
| | 1255 | |
| | 1256 | if (subgraph) |
| | 1257 | { |
| | 1258 | addModel(subgraph, positionData, modelData); |
| | 1259 | } |
| | 1260 | |
| | 1261 | osg::notify(osg::INFO)<<"end of SlideShowConstructor::addModel("<<filename<<")"<<std::endl<<std::endl; |
| | 1262 | |
| 1619 | | osg::AnimationPath* SlideShowConstructor::readPivotPath(const std::string& filename) const |
| 1620 | | { |
| 1621 | | std::ifstream in(filename.c_str()); |
| 1622 | | if (!in.eof()) |
| 1623 | | { |
| 1624 | | osg::AnimationPath* animation = new osg::AnimationPath; |
| 1625 | | |
| 1626 | | while (!in.eof()) |
| 1627 | | { |
| 1628 | | double time; |
| 1629 | | osg::Vec3 pivot; |
| 1630 | | osg::Vec3 position; |
| 1631 | | float scale; |
| 1632 | | osg::Quat rotation; |
| 1633 | | in >> time >> pivot.x() >> pivot.y() >> pivot.z() >> position.x() >> position.y() >> position.z() >> rotation.x() >> rotation.y() >> rotation.z() >> rotation.w() >> scale; |
| 1634 | | if(!in.eof()) |
| | 1639 | osg::AnimationPathCallback* SlideShowConstructor::getAnimationPathCallback(const PositionData& positionData) |
| | 1640 | { |
| | 1641 | if (!positionData.path.empty()) |
| | 1642 | { |
| | 1643 | osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(positionData.path, _options.get()); |
| | 1644 | osg::AnimationPath* animation = dynamic_cast<osg::AnimationPath*>(object.get()); |
| | 1645 | if (animation) |
| | 1646 | { |
| | 1647 | if (positionData.frame==SlideShowConstructor::SLIDE) |
| 1636 | | osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)* |
| 1637 | | osg::Matrixf::rotate(rotation); |
| 1638 | | |
| 1639 | | osg::Matrix invSR; |
| 1640 | | invSR.invert(SR); |
| 1641 | | |
| 1642 | | position += (invSR*pivot)*SR; |
| 1643 | | |
| 1644 | | animation->insert(time,osg::AnimationPath::ControlPoint(position,rotation,osg::Vec3(scale,scale,scale))); |
| 1645 | | } |
| 1646 | | } |
| 1647 | | |
| 1648 | | return animation; |
| 1649 | | } |
| 1650 | | return 0; |
| 1651 | | } |
| 1652 | | |
| 1653 | | struct RotationPathData |
| 1654 | | { |
| 1655 | | RotationPathData(): |
| 1656 | | time(0.0), |
| 1657 | | scale(1.0f), |
| 1658 | | azim(0.0f), |
| 1659 | | elevation(0.0f) {} |
| 1660 | | |
| 1661 | | double time; |
| 1662 | | osg::Vec3 pivot; |
| 1663 | | osg::Vec3 position; |
| 1664 | | float scale; |
| 1665 | | float azim; |
| 1666 | | float elevation; |
| 1667 | | |
| 1668 | | void addToPath(osg::AnimationPath* animation) const |
| 1669 | | { |
| 1670 | | osg::Quat Rx, Rz, rotation; |
| 1671 | | |
| 1672 | | Rx.makeRotate(osg::DegreesToRadians(elevation),1.0f,0.0f,0.0f); |
| 1673 | | Rz.makeRotate(osg::DegreesToRadians(azim),0.0f,0.0f,1.0f); |
| 1674 | | rotation = Rz * Rx; // note, I believe this is the wrong way round, but I had to put it in this order to fix the Quat properly. |
| 1675 | | |
| 1676 | | osg::Matrix SR = osg::Matrix::scale(scale,scale,scale)* |
| 1677 | | osg::Matrixf::rotate(rotation); |
| 1678 | | |
| 1679 | | osg::Matrix invSR; |
| 1680 | | invSR.invert(SR); |
| 1681 | | |
| 1682 | | osg::Vec3 local_position = position + (invSR*pivot)*SR; |
| 1683 | | |
| 1684 | | animation->insert(time,osg::AnimationPath::ControlPoint(local_position,rotation,osg::Vec3(scale,scale,scale))); |
| 1685 | | } |
| 1686 | | |
| 1687 | | }; |
| 1688 | | osg::AnimationPath* SlideShowConstructor::readRotationPath(const std::string& filename) const |
| 1689 | | { |
| 1690 | | std::ifstream in(filename.c_str()); |
| 1691 | | if (!in.eof()) |
| 1692 | | { |
| 1693 | | osg::AnimationPath* animation = new osg::AnimationPath; |
| 1694 | | |
| 1695 | | RotationPathData prevValue; |
| 1696 | | bool first = true; |
| 1697 | | while (!in.eof()) |
| 1698 | | { |
| 1699 | | RotationPathData currValue; |
| 1700 | | in >> currValue.time >> currValue.pivot.x() >> currValue.pivot.y() >> currValue.pivot.z() >> currValue.position.x() >> currValue.position.y() >> currValue.position.z() >> currValue.azim >> currValue.elevation >> currValue.scale; |
| 1701 | | if(!in.eof()) |
| 1702 | | { |
| 1703 | | |
| 1704 | | if (!first) |
| | 1649 | osg::AnimationPath::TimeControlPointMap& controlPoints = animation->getTimeControlPointMap(); |
| | 1650 | for(osg::AnimationPath::TimeControlPointMap::iterator itr=controlPoints.begin(); |
| | 1651 | itr!=controlPoints.end(); |
| | 1652 | ++itr) |
| 1706 | | |
| 1707 | | unsigned int num = 20; |
| 1708 | | float dr = 1.0f/(float)num; |
| 1709 | | float r=dr; |
| 1710 | | for(unsigned int i=0; |
| 1711 | | i<num; |
| 1712 | | ++i, r+=dr) |
| 1713 | | { |
| 1714 | | RotationPathData localValue; |
| 1715 | | localValue.time = currValue.time *r + prevValue.time * (1.0f-r); |
| 1716 | | localValue.pivot = currValue.pivot *r + prevValue.pivot * (1.0f-r); |
| 1717 | | localValue.position = currValue.position *r + prevValue.position * (1.0f-r); |
| 1718 | | localValue.scale = currValue.scale *r + prevValue.scale * (1.0f-r); |
| 1719 | | localValue.azim = currValue.azim *r + prevValue.azim * (1.0f-r); |
| 1720 | | localValue.elevation = currValue.elevation *r + prevValue.elevation * (1.0f-r); |
| 1721 | | |
| 1722 | | localValue.addToPath(animation); |
| 1723 | | } |
| 1724 | | } |
| 1725 | | else |
| 1726 | | { |
| 1727 | | currValue.addToPath(animation); |
| 1728 | | } |
| 1729 | | prevValue = currValue; |
| 1730 | | first = false; |
| 1731 | | } |
| 1732 | | |
| 1733 | | } |
| 1734 | | |
| 1735 | | return animation; |
| 1736 | | } |
| 1737 | | return 0; |
| 1738 | | } |
| 1739 | | |
| 1740 | | osg::AnimationPathCallback* SlideShowConstructor::getAnimationPathCallback(const PositionData& positionData) |
| 1741 | | { |
| 1742 | | if (!positionData.path.empty()) |
| 1743 | | { |
| 1744 | | std::string absolute_animation_file_path = osgDB::findDataFile(positionData.path); |
| 1745 | | if (!absolute_animation_file_path.empty()) |
| 1746 | | { |
| 1747 | | |
| 1748 | | osg::AnimationPath* animation = 0; |
| 1749 | | |
| 1750 | | std::string extension = osgDB::getLowerCaseFileExtension(absolute_animation_file_path); |
| 1751 | | if (osgDB::equalCaseInsensitive(extension,"pivot_path")) |
| 1752 | | { |
| 1753 | | animation = readPivotPath(absolute_animation_file_path); |
| 1754 | | } |
| 1755 | | else if (osgDB::equalCaseInsensitive(extension,"rotation_path")) |
| 1756 | | { |
| 1757 | | animation = readRotationPath(absolute_animation_file_path); |
| 1758 | | } |
| 1759 | | else if (osgDB::equalCaseInsensitive(extension,"path")) |
| 1760 | | { |
| 1761 | | std::ifstream animation_filestream(absolute_animation_file_path.c_str()); |
| 1762 | | if (!animation_filestream.eof()) |
| 1763 | | { |
| 1764 | | animation = new osg::AnimationPath; |
| 1765 | | animation->read(animation_filestream); |
| | 1654 | osg::AnimationPath::ControlPoint& cp = itr->second; |
| | 1655 | cp.setPosition(convertSlideToModel(cp.getPosition()+positionData.position)); |
| 1768 | | else |
| 1769 | | { |
| 1770 | | std::ifstream animation_filestream(absolute_animation_file_path.c_str()); |
| 1771 | | |
| 1772 | | osgDB::Input fr; |
| 1773 | | fr.attach(&animation_filestream); |
| 1774 | | |
| 1775 | | static osg::ref_ptr<osg::AnimationPath> s_path = new osg::AnimationPath; |
| 1776 | | osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(absolute_animation_file_path); // fr.readObjectOfType(*s_path); |
| 1777 | | object = fr.readObject(); // fr.readObjectOfType(*s_path); |
| 1778 | | if (object.valid()) |
| 1779 | | { |
| 1780 | | animation = dynamic_cast<osg::AnimationPath*>(object.get()); |
| 1781 | | } |
| 1782 | | } |
| 1783 | | |
| 1784 | | if (animation) |
| 1785 | | { |
| 1786 | | if (positionData.frame==SlideShowConstructor::SLIDE) |
| 1787 | | { |
| 1788 | | osg::AnimationPath::TimeControlPointMap& controlPoints = animation->getTimeControlPointMap(); |
| 1789 | | for(osg::AnimationPath::TimeControlPointMap::iterator itr=controlPoints.begin(); |
| 1790 | | itr!=controlPoints.end(); |
| 1791 | | ++itr) |
| 1792 | | { |
| 1793 | | osg::AnimationPath::ControlPoint& cp = itr->second; |
| 1794 | | cp.setPosition(convertSlideToModel(cp.getPosition()+positionData.position)); |
| 1795 | | } |
| 1796 | | } |
| 1797 | | |
| 1798 | | animation->setLoopMode(positionData.path_loop_mode); |
| 1799 | | |
| 1800 | | osg::AnimationPathCallback* apc = new osg::AnimationPathCallback(animation); |
| 1801 | | apc->setTimeOffset(positionData.path_time_offset); |
| 1802 | | apc->setTimeMultiplier(positionData.path_time_multiplier); |
| 1803 | | apc->setUseInverseMatrix(positionData.inverse_path); |
| 1804 | | |
| 1805 | | osg::notify(osg::INFO)<<"UseInverseMatrix "<<positionData.inverse_path<<std::endl; |
| 1806 | | |
| 1807 | | return apc; |
| 1808 | | |
| 1809 | | } |
| 1810 | | } |
| | 1658 | |
| | 1659 | animation->setLoopMode(positionData.path_loop_mode); |
| | 1660 | |
| | 1661 | osg::AnimationPathCallback* apc = new osg::AnimationPathCallback(animation); |
| | 1662 | apc->setTimeOffset(positionData.path_time_offset); |
| | 1663 | apc->setTimeMultiplier(positionData.path_time_multiplier); |
| | 1664 | apc->setUseInverseMatrix(positionData.inverse_path); |
| | 1665 | |
| | 1666 | osg::notify(osg::INFO)<<"UseInverseMatrix "<<positionData.inverse_path<<std::endl; |
| | 1667 | |
| | 1668 | return apc; |
| | 1669 | |
| | 1670 | } |
| | 1671 | |
| | 1713 | |
| | 1714 | void SlideShowConstructor::recordOptionsFilePath(const osgDB::Options* options) |
| | 1715 | { |
| | 1716 | if (options) |
| | 1717 | { |
| | 1718 | std::string filename_used = _options->getPluginStringData("filename"); |
| | 1719 | std::string path = osgDB::getFilePath(filename_used); |
| | 1720 | if (!path.empty() && _filePathData.valid()) |
| | 1721 | { |
| | 1722 | osgDB::FilePathList::iterator itr = std::find(_filePathData->filePathList.begin(),_filePathData->filePathList.end(),path); |
| | 1723 | if (itr==_filePathData->filePathList.end()) |
| | 1724 | { |
| | 1725 | osg::notify(osg::INFO)<<"SlideShowConstructor::recordOptionsFilePath(..) - new path to record path="<<path<<" filename_used="<<filename_used<<std::endl; |
| | 1726 | _filePathData->filePathList.push_front(path); |
| | 1727 | } |
| | 1728 | } |
| | 1729 | } |
| | 1730 | } |
| | 1731 | |