/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield * * This software is open source and may be redistributed and/or modified under * the terms of the GNU General Public License (GPL) version 2.0. * The full license is in LICENSE.txt file included with this distribution,. * * This software 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 * include LICENSE.txt for more details. */ #include #include using namespace osgPresentation; const osg::Object* osgPresentation::getUserObject(const osg::NodePath& nodepath, const std::string& name) { for(osg::NodePath::const_reverse_iterator itr = nodepath.rbegin(); itr != nodepath.rend(); ++itr) { const osg::UserDataContainer* udc = (*itr)->getUserDataContainer(); const osg::Object* object = udc ? udc->getUserObject(name) : 0; if (object) return object; } return 0; } bool osgPresentation::containsPropertyReference(const std::string& str) { return (str.find('$')!=std::string::npos); } void PropertyAnimation::reset() { _firstTime = DBL_MAX; _pauseTime = DBL_MAX; OSG_NOTICE<<"PropertyAnimation::reset()"<getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR && nv->getFrameStamp()) { double time = nv->getFrameStamp()->getSimulationTime(); _latestTime = time; if (!_pause) { // Only update _firstTime the first time, when its value is still DBL_MAX if (_firstTime==DBL_MAX) _firstTime = time; update(*node); } } traverse(node, nv); } class MySetValueVisitor : public osg::ValueObject::SetValueVisitor { public: MySetValueVisitor(double in_r1, double in_r2, osg::ValueObject* in_object2): _r1(in_r1), _r2(in_r2), _object2(in_object2) { } template void combineRealUserValue(T& value) const { typedef osg::TemplateValueObject UserValueObject; const UserValueObject* uvo = _object2 ? dynamic_cast(_object2) : 0; if (uvo) { value = value*_r1 + uvo->getValue()*_r2; } OSG_NOTICE<<"combineRealUserValue r1="<<_r1<<", r2="<<_r2<<", value="< void combineIntegerUserValue(T& value) const { typedef osg::TemplateValueObject UserValueObject; const UserValueObject* uvo = _object2 ? dynamic_cast(_object2) : 0; if (uvo) { value = static_cast(static_cast(value)*_r1 + static_cast(uvo->getValue())*_r2); } OSG_NOTICE<<"combineIntegerUserValue "< void combineDiscretUserValue(T& value) const { if (_r1<_r2) // choose value2 if possible { typedef osg::TemplateValueObject UserValueObject; const UserValueObject* uvo = _object2 ? dynamic_cast(_object2) : 0; if (uvo) { value = uvo->getValue(); } } OSG_NOTICE<<"combineDiscretUserValue "< void combineRotationUserValue(T& /*value*/) const { OSG_NOTICE<<"combineRotationUserValue TODO - do slerp"< void combinePlaneUserValue(T& /*value*/) const { OSG_NOTICE<<"combinePlaneUserValue TODO"< void combineMatrixUserValue(T& /*value*/) const { OSG_NOTICE<<"combineMatrixUserValue TODO - decomposs into translate, rotation and scale and then interpolate."<second.get()); } else if (itr!=_keyFrameMap.end()) { KeyFrameMap::const_iterator itr_1 = itr; --itr_1; KeyFrameMap::const_iterator itr_2 = itr; // delta_time = second.time - first.time double delta_time = itr_2->first - itr_1->first; double r1, r2; if (delta_time==0.0) { r1 = 0.5; r2 = 0.5; } else { r2 = (time - itr_1->first)/delta_time; r1 = 1.0-r2; } osg::UserDataContainer* p1 = itr_1->second.get(); osg::UserDataContainer* p2 = itr_2->second.get(); // clone all the properties from p1; osg::ref_ptr destination = node.getOrCreateUserDataContainer(); assign(destination.get(), p1); for(unsigned int i2=0; i2getNumUserObjects(); ++i2) { osg::Object* obj_2 = p2->getUserObject(i2); unsigned int i1 = p1->getUserObjectIndex(obj_2->getName()); if (i1getNumUserObjects()) { osg::Object* obj_1 = p1->getUserObject(i1); osg::ValueObject* valueobject_1 = dynamic_cast(obj_1); osg::ValueObject* valueobject_2 = dynamic_cast(obj_2); if (valueobject_1 && valueobject_2) { osg::ref_ptr vo = osg::clone(valueobject_1); MySetValueVisitor mySetValue(r1, r2, valueobject_2); vo->set(mySetValue); assign(destination.get(), vo.get()); } else if (obj_1) { assign(destination.get(), obj_1); } else if (obj_2) { assign(destination.get(), obj_2); } } else { // need to insert property; assign(destination.get(), obj_2); } } } else // (itr==_keyFrameMap.end()) { OSG_NOTICE<<"PropertyAnimation::update() : copy last UserDataContainer"<second.get()); } } void PropertyAnimation::assign(osg::UserDataContainer* destination, osg::UserDataContainer* source) { if (!destination) return; if (!source) return; for(unsigned int i=0; igetNumUserObjects(); ++i) { assign(destination, source->getUserObject(i)); } } void PropertyAnimation::assign(osg::UserDataContainer* udc, osg::Object* obj) { if (!obj) return; unsigned int index = udc->getUserObjectIndex(obj); if (index != udc->getNumUserObjects()) { OSG_NOTICE<<"Object already assigned to UserDataContainer"<getUserObjectIndex(obj->getName()); if (index != udc->getNumUserObjects()) { OSG_NOTICE<<"Replacing object in UserDataContainer"<setUserObject(index, obj); return; } OSG_NOTICE<<"Assigned object to UserDataContainer"<addUserObject(obj); } void ImageSequenceUpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) { float x; if (_propertyManager->getProperty(_propertyName,x)) { double xMin = -1.0; double xMax = 1.0; double position = ((double)x-xMin)/(xMax-xMin)*_imageSequence->getLength(); _imageSequence->seek(position); } else { OSG_INFO<<"ImageSequenceUpdateCallback::operator() Could not find property : "<<_propertyName<setProperty("mouse.x",ea.getX()); _propertyManager->setProperty("mouse.x_normalized",ea.getXnormalized()); _propertyManager->setProperty("mouse.y",ea.getX()); _propertyManager->setProperty("mouse.y_normalized",ea.getYnormalized()); } return false; }